l'exemple avec le 16f887
-----
l'exemple avec le 16f887
Le programme est pour un PIC16F887 il est normal d'avoir une multitude d'erreurs par rapport à un PIC16F877A.
En reprenant un à un les messages vous devriez vous en sortir en adaptant/renommant les registres.
Un autre lien qui peut vous être utile avec votre µC:
http://dspace.rri.res.in/bitstream/2..._2006_LAMP.pdf
Vous êtes vraiment tous sympa de venir à mon secours!
Merci pour le pdf je vais le lire aussi.
Oui j'étais pas surpris que ça ne fonctionne pas même que j'avais quand même regonfigurer les adresses port pour que le programme soit compatible avec le mien.
J'ai fait la modif avec un BC557 et j'ai vérifié que le contraste fonctionne.
Bjr Antek,
Oui je connais le cours Bigonof à l'époque je l'avait tout télécharger il est intéressant mais très long à lire.
En fait je lis généralement ce que j'ai besoin et je cherche pas trop à vouloir tout apprendre d'un coup.
Si j'ai pas un projet qui m'oblige à passer par l'étape de la programmation, je n'irai pas me nourrir du cours; il me faudra une motivation en plus je suis tout seul dans mon coin.
Les cours Bigonof, j'en ai surtout eu besoin pour créer des interruptions et comprendre certains trucs.
Je suis souvent parti d’exemple pour élaborer mes programmes et comme ils se ressemble généralement tous, c'est juste des adresses ports qui change et des tempos. Partant de ce constat, j'ai vite compris l'intérêt de se créer des bibliothèques de routines.
Là j'attaque un gros morceaux et je n'ai pas fini de vous embêter.
Fin de mois, vous serez plus tranquille, je rentre en hospitalisation mais j'espère bien reprendre l'affaire vers le 15/12.
A+
A mon avis il est indispensable d'acquérir un minimum de notions, que le premier cours de Bigonoff dispense de manière facile à appréhender pour un débutant.
Ensuite on peut s'en sortir aisemment avec les autres µC et leurs modules "ésotériques".
C'est pas cher payer pour savoir réaliser un programme qui tient la route.
Je suis à reconstruire le programme de Jon Wilder avec le PIC 16f887 pour l'adapter à mon application.
Dans son programme intitulé "Initialization Routine" il y a 3 lignes nommées "banksel" est-ce le registre d'état que l'on nomme habituellement "STATUS" pour accéder aux pages mémoires TRIS?
Par contre, je n'ai rien compris à ce module qui s'affiche en erreur avec MPLABCode:START clrf PORTA ;init ports clrf PORTB clrf PORTC clrf PORTD clrf PORTE banksel ANSEL ;bank 3 clrf ANSEL ;all ports digital I/O clrf ANSELH banksel TRISA ;bank 1 clrf TRISA ;PORTA, PORTB, PORTC, and PORTE outputs clrf TRISB ;PORTD defaults to input clrf TRISC clrf TRISE banksel 0 ;bank 0
Code:;************************************************************************************************* ;** ** ;** RAM Location Constants ** ;** ** ;************************************************************************************************* cblock 0x20 TEMP ;temp buffer DATAL ;instruction data low byte DATAH ;instruction data high byte COMMAND ;instruction TABLECOUNT ;table counter endc cblock 0x70 W_TEMP ;interrupt context save for W STATUS_TEMP ;interrupt context save for STATUS PCLATH_TEMP ;interrupt context save for PCLATH COUNT1 ;delay counter 1 COUNT2 ;delay counter 2 COUNT3 ;delay counter 3 DATA_EE_ADDR ;data EEPROM address buffer DATA_EE_DATA ;data EEPROM data buffer endc
La recopie dans le message est un peu désordonné, l'idéal est de lancer le lien et de lire le prg dans le fichier.
https://www.electro-tech-online.com/...ontroller.482/
Dernière modification par Antoane ; 18/11/2018 à 19h13. Motif: Remplacement des balises QUOTE par CODE
Merci! c'est bcp plus facile à lire, je n'avais pas fait la subtilité entre quote et code!
Je ne suis pas un habitué des forums, j'ai encore à apprendre là aussi...
banksel est une instruction de sélection de bank
Existe-t-il une EEPROM dans le 877 ?
Quelles erreurs ?
Oui il existe une EEprom
Au résultat du Make project il m'indique ceci:
Erreur (113) Symbol not previously defined (Ansel)
A quoi correspond banksel dans le mapping de la mémoire?
Dans les 4 pages mémoire, je n'ai pas trouvé ANSEL
http://daniel.menesplier.free.fr/Doc/PIC%2016F877.pdf
ANSEL est un registre permettant de choisir l'I/O en entrée analogique ou en I/O numérique.
Le PIC16F877 n'a pas de registre ANSEL.
Bonjour à tous,
Donc inutile que je m'acharne à vouloir l'adapter à mon prg.
Il faut que je trouve une solution pour cette boucle.
Quelqu'un a une idée?
J'ai pensé déclarer le portD en entrée dans une première étiquette et le déclarer en sortie dans une seconde. Le seul soucis est de savoir comment il ira chercher la bonne étiquette.
A vous relire..Code:Port en sortie BSF STATUS,5 MOVLW B'00000000' MOVWF TRISD BCF STATUS,5 Port en entré BSF STATUS,5 MOVLW B'11111111' MOVWF TRISD BCF STATUS,5
Bonjour tout le monde,
J'ai donc repris la maquette de Jon Wilder pour l'adapter à mon application avec le 16f877.
Si le 887 dispose de fonctionnalité que le 877 n'a pas, je suis quand même arrivé à les adapter en utilisant les cdes propres au 877.
J'ai compris certaines fonctionnalité du programme mais pour d'autres non.
D'autre part j'ai l'impression que le programme est incomplet, il manque des routines que MPLAB a mis en erreur.
Il s'agit de la cde
CALL DAWset et CALL DAWRESET qui ne trouvent pas leurs étiquettes pour se raccorder (ligne 340 et 350 du prg)
Malgré cela en les isolant par un ";" j'ai quand même chargé le programme et je me retrouve avec une ligne horizontale qui traverse l'écran et qui ne se place pas forcement au même endroit
Si qq'un à envie d'y jeter un œil
Voici le programme:
Code:;---------------------------------------------------------GESTION AFFICHEUR----------------------------------------------------------------- ; TITRE: Gestion d'un afficheur LCD graphique ; DATE: 10/11/2018 ; AUTEUR: nondediode ; PIC UTILISE: PIC16F877 ; Gestion PP845 version 2019 ; le quartz est de 4MHz ;----------------------------------------------------Brochage du PIC sur la carte--------------------------------------------------------- ; ; Port | Broche | E/S | Description ; RA0 | 02 | S | Relais "MUTE" ; RA1 | 03 | S | Relais "PHASE" ; RA2 | 04 | S | LED droite ; RA3 | 05 | S | LED gauche ; RA4 | 06 | S | Relais de cde HT gauche et droit ; RA5 | 07 | S | Relais statique gauche et droit ; RB0 | 33 | E | Inter "on / off" ; RB1 | 34 | E | Bouton poussoir "OK" ; RB2 | 35 | S | Data Write afficheur ; RB3 | 36 | S | Data Read afficheur ; RB4 | 37 | S | Chip Enable ; RB5 | 38 | S | C/D ; RB6 | 39 | S | Font Size Select ; RB7 | 40 | S | Reset ; RC0 | 15 | S | Adressage entrée audio bit A ; RC1 | 16 | S | Adressage entrée audio bit B ; RC2 | 17 | S | Adressage entrée audio bit C ; RC3 | 18 | S | Adressage entrée audio bit D ; RC4 | 23 | S | LEDs Rouge droit et gauche ; RC5 | 24 | E | Bouton poussoir "INPUT" ; RC6 | 25 | E | Bouton poussoir "PHASE" ; RC7 | 26 | E | Bouton poussoir "MUTE" ; RD0 | 19 | S | Sortie bit D7 du LCD ; RD1 | 20 | S | Sortie bit D6 du LCD ; RD2 | 21 | S | Sortie bit D5 du LCD ; RD3 | 22 | S | Sortie bit D4 du LCD ; RD4 | 27 | S | Sortie bit D3 du LCD ; RD5 | 28 | S | Sortie bit D2 du LCD ; RD6 | 29 | S | Sortie bit D1 du LCD ; RD7 | 30 | S | Sortie bit D0 du LCD ;--------------------------------------------------DIRECTIVE D'ASSEMBLAGE POUR MPLAB------------------------------------------------------- list p=16f877 #include <p16f877.inc> __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC ;-------------------------------------------------Definition de la RAM------------------------------------------------------ cblock 0x20 TEMP ;temp buffer DATAL ;instruction donnée =0 DATAH ;instruction donnée =1 COMMAND ;instruction TABLECOUNT ;tablecounter endc cblock 0x70 W_TEMP ;interruptcontextsave for W STATUS_TEMP ;interruptcontextsave for STATUS PCLATH_TEMP ;interruptcontextsave for PCLATH COUNT1 ;delaycounter 1 COUNT2 ;delaycounter 2 COUNT3 ;delaycounter 3 DATA_EE_ADDR ;data EEPROM address buffer DATA_EE_DATA ;data EEPROM data buffer endc ;-------------------------------------------------Definition des constantes------------------------------------------------------ #define WRITE PORTB,2 ; GLCD writeenable/disable (active low) #define READ PORTB,3 ; GLCD readenable/disable (active low) #define CE PORTB,4 ; GLCD chip enable/disable (active low) #define CD PORTB,5 ; GLCD command/data #define FONT PORTB,6 ; GLCD font select (6x8 or 8x8) #define RST PORTB,7 ; GLCD reset #define D0 PORTD,RD0 ; GLCD data port bit 0 #define D1 PORTD,RD1 ; GLCD data port bit 1 #define D2 PORTD,RD2 ; GLCD data port bit 2 #define D3 PORTD,RD3 ; GLCD data port bit 3 #define D4 PORTD,RD4 ; GLCD data port bit 4 #define D5 PORTD,RD5 ; GLCD data port bit 5 #define D6 PORTD,RD6 ; GLCD data port bit 6 #define D7 PORTD,RD7 ; GLCD data port bit 7 ;--------------------------------------------Definition des registres temporaires------------------------------------------------------ WR_EN EQU 2 WR_DIS EQU 7 RD_EN EQU 1 RD_DIS EQU 7 ;--------------------------------------------Directives des programmes------------------------------------------------------ org 0x000 ; Debut du programme principale goto START ; Saut à START org 0x004 ; Debut du programme d'interruption goto ISR ; Sautà ISR ;-------------------------------------------------INITIALISATION------------------------------------------------------ START CLRF PORTA ; Remise à 0 du port A CLRF PORTB ; Remise à 0 du port B CLRF PORTC ; Remise à 0 du port C CLRF PORTD ; Remise à 0 du port D CLRF PORTE ; Remise à 0 du port E ;;;;;;;;;; banksel ANSEL ; bank 3 ;;;;;;;;;; CLRF ANSEL ; all ports digital I/O ;;;;;;;;;; CLRF ANSELH ; ;;;;;;;;;; banksel TRISA ; bank 1 CLRF TRISA ; PORTA, PORTB, PORTC, and PORTE outputs CLRF TRISB ; PORTD defaults to input CLRF TRISC ; CLRF TRISE ; ;;;;;;;;;; banksel 0 ; bank 0 GLCD_INIT BCF RST ; reset du GLCD MOVLW B'01111100' ; On charge la valeur dans le registre W MOVWF PORTB ; Command mode and 6x8 font, disableread, write, and chip enable call Delay50mS ; Appel de la tempo de 50ms BSF RST ; disable reset ;-------------------------------------------------INITIALISATION afficheur------------------------------------------------------ ModeSet MOVLW 0x84 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL NoData ; Appel de l'étiquette NoData GraphicsHome MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH MOVLW 0x42 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData GraphicsArea MOVLW 0x28 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x0 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH MOVLW 0x43 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData TextHome MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x17 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH MOVLW 0x40 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData TextArea MOVLW 0x28 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH MOVLW 0x41 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData CGROMSet MOVLW 0x03 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x0 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH MOVLW 0x22 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData ;cleargraphics RAM MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAL ; Setaddress pointer to 0x0000 MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH CALL ADDR_PTR ; Appel de l'étiquette ADDR_PTR MOVLW 0x20 ; Charge la valeur dans W MOVWF COUNT2 ; Transfert de W sur COUNT2 CALL DisplayClear ; Appel de l'étiquette DisplayClear ;cleartext RAM MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAL ; Setaddress pointer to 0x0000 MOVLW 0x17 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH CALL ADDR_PTR ; Appel de l'étiquette ADDR_PTR MOVLW 0x08 ; Charge la valeur dans W MOVWF COUNT2 ; Transfert de W sur COUNT2 CALL DisplayClear ; Appel de l'étiquette DisplayClear CSRPattern MOVLW 0xA0 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL NoData ; Appel de l'étiquette NoData CSRPointer MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH CALL CSR_PTR ; Appel de l'étiquette CSR_PTR ADDRPointer MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAL ; Transfert de W sur DATAL MOVLW 0x00 ; Charge la valeur dans W MOVWF DATAH ; Transfert de W sur DATAH CALL ADDR_PTR ; Appel de l'étiquette ADDR_PTR DisplayOn MOVLW 0x9F ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL NoData ; Appel de l'étiquette NoData GOTO $ ; Comptage de boucle ;-------------------------------------------------Programme tempo------------------------------------------------------ Delay50mS MOVLW 0x40 ; Charge la valeur dans W MOVWF COUNT1 ; Transfert de W sur COUNT1 MOVWF COUNT2 ; Transfert de W sur COUNT2 DECFSZ COUNT1,F ; On décrémente COUNT1,F GOTO $-1 ; Comptage de boucle DECFSZ COUNT2,F ; On décrémente COUNT2,F GOTO $-3 ; Comptage de boucle RETURN Delay MOVWF COUNT3 ; Transfert de W sur COUNT3 CALL Delay50mS ; Appel de l'étiquette Delay50mS DECFSZ COUNT3,F ; On décrémente COUNT3,F GOTO $-2 ; Comptage de boucle RETURN ;-------------------------------------------------Position Address Pointer ------------------------------------------------------ ADDR_PTR MOVLW 0x24 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData RETURN ;-------------------------------------------------Position Cursor Pointer ------------------------------------------------------ CSR_PTR MOVLW 0x21 ; Charge la valeur dans W MOVWF COMMAND ; Transfert de W sur COMMAND CALL TwoData ; Appel de l'étiquette TwoData RETURN ;-------------------------------------------------Command Send Routines ------------------------------------------------------ TwoData CALL LCDStat ; Appel de l'étiquette LCDStat MOVWF DATAL ; Transfert de W sur DATAL CALL DWrite ; Appel de l'étiquette DWrite OneData CALL LCDStat ; Appel de l'étiquette LCDStat MOVWF DATAH ; Transfert de W sur DATAH CALL DWrite ; Appel de l'étiquette DWrite NoData CALL LCDStat ; Appel de l'étiquette LCDStat MOVWF COMMAND ; Transfert de W sur COMMAND CALL Command ; Appel de l'étiquette Command RETURN ;------------------------------------------------GLCD Read/Write/Status Check------------------------------------------------------ Command BSF CD ; CD=1 GOTO $+2 ; Permet de sauter 2 lignes de code DWrite BCF CD ; CD=0 MOVWF PORTD ; Transfert de W sur port D MOVLW WR_EN ; Charge WR_EN dans W MOVWF PORTB ; Transfert de W sur port B BSF STATUS,5 ; Accès à la 2ème page mémoire TRISD MOVLW B'00000000' ; Charge la valeur dans W MOVWF TRISD ; Le port D est en sortie MOVLW WR_DIS ; Charge WR_DIS dans W MOVWF PORTB ; Transfert de W sur port B BCF STATUS,5 ; Accès à la 1ère page mémoire TRISD call Delay50mS ; Appel de la tempo de 50ms BSF STATUS,5 ; Accès à la 2ème page mémoire TRISD MOVLW B'11111111' ; Charge la valeur dans W MOVWF TRISD ; Le port D est en entrée BCF STATUS,5 ; Accès à la 1ère page mémoire TRISD RETURN LCDStat CALL StatReadEn ; Appel de l'étiquette StatReadEn BTFSC PORTD,0 ; D0 = 0? BTFSS PORTD,1 ; D1 = 1? GOTO $-2 ; Comptage de boucle CALL StatReadDis ; Appel de l'étiquette StatReadDis RETURN DAWStat CALL StatReadEn ; Appel de l'étiquette StatReadEn BTFSS PORTD,3 ; D3 = 1? GOTO $-1 ; Comptage de boucle CALL StatReadDis ; disablestatusread RETURN StatReadEn BSF CD ; CD=1 MOVLW RD_EN ; Charge RD_EN dans W MOVWF PORTB ; Transfert de W sur port B RETURN StatReadDis MOVLW RD_DIS ; Charge RD_DIS dans W MOVWF PORTB ; Transfert de W sur port B RETURN ;------------------------------------------------Clear Display------------------------------------------------------ DisplayClear MOVLW 160 ; Charge la valeur dans W MOVWF COUNT1 ; Transfert de W sur COUNT1 ;;;;;;;;;; CALL DAWSet ; Appel de l'étiquette DAWSet CALL DAWStat ; Appel de l'étiquette DAWStat MOVLW 0 ; Charge la valeur dans W CALL DWrite ; Appel de l'étiquette DWrite DECFSZ COUNT1,F ; On décrémente COUNT1,F GOTO $-4 ; Comptage de boucle MOVLW 160 ; Charge la valeur dans W MOVWF COUNT1 ; Transfert de W sur COUNT1 DECFSZ COUNT2,F ; On décrémente COUNT2,F GOTO $-8 ; Comptage de boucle ;;;;;;;;;; CALL DAWReset ; Appel de l'étiquette DAWReset RETURN ;------------------------------------------------Interrupt Handler------------------------------------------------------ ISR MOVWF W_TEMP ; Transfert de W sur W_TEMP SWAPF STATUS,W ; Echange de quartet entre status et W ;;;;;;;;;; BANKSEL 0 ; bank 0 MOVWF STATUS_TEMP ; Transfert de W sur STATUS_TEMP MOVFW PCLATH ; Transfert de PCLATH sur W MOVWF PCLATH_TEMP ; Transfert de W sur PCLATH_TEMP ISRExit MOVFW PCLATH_TEMP ; Transfert de PCLATH_TEMP sur W MOVWF PCLATH ; Transfert de W sur PCLATH SWAPF STATUS_TEMP,W ; Echange de quartet entre STATUS_TEMP et W MOVWF STATUS ; SWAPF W_TEMP,F ; Echange de quartet entre W_TEMP et F SWAPF W_TEMP,W ; Echange de quartet entre W_TEMP et F RETFIE END
Bonsoir,
les fonctions DAWset et DAWreset sont celles-ci:
Code:;************************************************************************************************* ;** ** ;** Data Auto Read/Write Routines ** ;** ** ;************************************************************************************************* DAWSet movlw 0xB0 movwf COMMAND call NoData call LCDStat call DAWStat return ;************************************************************************************************* DAWReset call DAWStat movlw 0xB2 movwf COMMAND call NoData return ;*************************************************************************************************
Bonjour et merci,
Je vais tester
Sinon, vous avez jeter un œil sur mon programme?
Amicalement,
Non pas encore, je le ferai dès que j'ai un peu plus de temps.
J'ai testé avec les 2 routines et c'est pareil; un trait horizontale traverse l'écran.
Il doit y avoir des erreurs que je ne maîtrise pas
Bonjour tout le monde,
Dans le programme de Jon Wilder il est régulièrement utilisé la commande:
GOTO $-2
ou
Goto $+2
J'ai compris que cette commande est un saut inconditionnel mais par quoi pourrais-je la remplacer pour que MPLAB l'interprète plus efficacement?
En vous remerciant
Il ne doit pas y avoir de problème, c'est une instruction valide.
Mais l'enchaînement doit être entièrement revu lors d'une réécriture.
On peut aussi la remplacer par une adresse de branchement sous forme d'étiquette.
Je pense que le cours Bigonoff te ferais du bien . . .
Dernière modification par antek ; 23/11/2018 à 10h35.
OK merci!
Donc si je comprends bien cette action
GOTO $+3
Serait égale à dire
sauter les 3 instructions prochaines?
Et lorsque je lis
GOTO $-3
Cela veut dire quoi?
J'espère ne pas trop vous embêter avec mes questions ridicules.
Mais j'essaie de comprendre et je n'arrive pas à trouver une explication claire à ce sujet.
c'est moi
Branchement à la 3e instruction suivant le goto
Branchement à la 3e instruction précédent le goto
Sauf erreur . . . , je n'utilise jamais ces trucs, mais des étiquettes.
C'est plus lisible pour moi.
Dernière modification par antek ; 23/11/2018 à 11h13.
L'avantage de cette cde c'est qu'on est pas obligé de créer une étiquette spécifique.
Je ne connaissait pas cette cde mais c'est vrai que je n'ai pas un grand niveau en assembleur
Merci de m'avoir renseigner