;***************************************************************************** ; Ce fichier est la base de départ pour une programmation avec * ; le PIC 16F876A. Il contient les informations de base pour * ; démarrer. * ; * ;***************************************************************************** ; * ; NOM: * ; Date: * ; Version: * ; Circuit: * ; Auteur: * ; * ;***************************************************************************** ; * ; Fichier requis: P16F876A.inc * ; * ; * ; * ;***************************************************************************** ; * ; Notes: * ; * ; * ; * ; * ;***************************************************************************** ERRORLEVEL -302 ; suppression du message bank select LIST p=16F876a ; Définition de processeur #include ; fichier include __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC ; '__CONFIG' précise les paramètres encodés dans le processeur au moment de ; la programmation du processeur. Les définitions sont dans le fichier include. ; Choisir une valeur par groupe. ; Voici les valeurs et leurs définitions : ; Protection du programme en lecture ; ----------------------- ;_CP_ALL protection totale ;_CP_OFF Pas de protection ; Debuggage ; --------- ;_DEBUG_ON RB6 et RB7 utilisées pour debugger ;_DEBUG_OFF RB6 et RB7 en utilisation normale ; Accès à la flash programme ; -------------------------- ;_WRT_OFF Le programme peut écrire dans la flash ;_WRT_256 Le programme ne peut pas écrire dans la flash dans les 256 premier octets ;_WRT_1FOURTH Le programme ne peut pas écrire dans la flash dans le premier quart ;_WRT_HALF Le programme ne peut pas écrire dans la flash dans la premiere moitiée ; Protection de la EEprom ; ----------------------- ;_CPD_ON Mémoire EEprom protégée ;_CPD_OFF Mémoire EEprom déprotégée ; Programmation sur circuit ; ------------------------- ;_LVP_ON RB3 permet la programmation série de la PIC ;_LVP_OFF RB3 en utilisation normale ; Reset de la PIC si tension <4V ; ------------------------------ ; _BODEN_ON Reset tension en service ; Valide PWRTE_ON automatiquement ; _BODEN_OFF Reset tension hors service ; Retard à la mise sous tension ; ----------------------------- ;_PWRTE_OFF Démarrage rapide ;_PWRTE_ON Démarrage temporisé ; Watchdog ; -------- ;_WDT_ON Watchdog en service ;_WDT_OFF Watchdog hors service ; Oscillateur ; ----------- ;_LP_OSC Oscillateur basse vitesse (322K) ENDC ;***************************************************************************** ; VARIABLES BANQUE 0 * ;***************************************************************************** ; Zone de 80 bytes ; ---------------- CBLOCK 0x20 ; Début de la zone (0x20 à 0x6F) ;Exemples ;-------- ; test :1 ; Zone de 1 byte ; table : 10 ; zone de 10 bytes ENDC ; Fin de la zone ;Exemples ;-------- ;var1 EQU H'006E' ; adresse imposée ;***************************************************************************** ; VARIABLES BANQUE 1 * ;***************************************************************************** ; Zone de 80 bytes ; ---------------- CBLOCK 0xA0 ; Début de la zone (0xA0 à 0xEF) ENDC ; Fin de la zone ;***************************************************************************** ; VARIABLES BANQUE 2 * ;***************************************************************************** ; Zone de 96 bytes ; ---------------- CBLOCK 0x110 ; Début de la zone (0x110 à 0x16F) ENDC ; Fin de la zone ;***************************************************************************** ; VARIABLES BANQUE 3 * ;***************************************************************************** ; Zone de 96 bytes ; ---------------- CBLOCK 0x190 ; Début de la zone (0x190 à 0x1EF) ENDC ; Fin de la zone ;***************************************************************************** ; DEMARRAGE SUR RESET * ;***************************************************************************** org 0x000 ; Adresse de départ après reset clrf PCLATH ; Effacer sélecteur de pages goto init ; Initialiser ; //////////////////////////////////////////////////////////////////////////// ; I N T E R R U P T I O N S ; //////////////////////////////////////////////////////////////////////////// ;***************************************************************************** ; ROUTINE INTERRUPTION * ;***************************************************************************** ;----------------------------------------------------------------------------- ; Si on n'utilise pas l'adressage indirect dans les interrupts, on se passera ; de sauvegarder FSR ; Si le programme ne fait pas plus de 2K, on se passera de la gestion de ; PCLATH ;----------------------------------------------------------------------------- ;sauvegarder registres ;--------------------- org 0x004 ; adresse d'interruption movwf w_temp ; sauver registre W swapf STATUS,w ; swap status avec résultat dans w movwf status_temp ; sauver status swappé movf FSR , w ; charger FSR movwf FSR_temp ; sauvegarder FSR movf PCLATH , w ; charger PCLATH movwf PCLATH_temp ; le sauver clrf PCLATH ; on est en page 0 BANK0 ; passer en banque0 ; switch vers différentes interrupts ; inverser ordre pour modifier priorités ; mais attention alors au test PEIE ; effacer les inutiles ;---------------------------------------- ; Interruption TMR0 ; ----------------- btfsc INTCON,T0IE ; tester si interrupt timer autorisée btfss INTCON,T0IF ; oui, tester si interrupt timer en cours goto intsw1 ; non test suivant call inttmr0 ; oui, traiter interrupt tmr0 bcf INTCON,T0IF ; effacer flag interrupt tmr0 goto restorereg ; et fin d'interruption ; SUPPRIMER CETTE LIGNE POUR ; TRAITER PLUSIEURS INTERRUPT ; EN 1 SEULE FOIS ; Interruption RB0/INT ; -------------------- intsw1 btfsc INTCON,INTE ; tester si interrupt RB0 autorisée btfss INTCON,INTF ; oui, tester si interrupt RB0 en cours goto intsw2 ; non sauter au test suivant call intrb0 ; oui, traiter interrupt RB0 bcf INTCON,INTF ; effacer flag interupt RB0 goto restorereg ; et fin d'interruption ; SUPPRIMER CETTE LIGNE POUR ; TRAITER PLUSIEURS INTERRUPT ; EN 1 SEULE FOIS ; interruption RB4/RB7 ; -------------------- intsw2 btfsc INTCON,RBIE ; tester si interrupt RB4/7 autorisée btfss INTCON,RBIF ; oui, tester si interrupt RB4/7 en cours goto intsw3 ; non sauter call intrb4 ; oui, traiter interrupt RB4/7 bcf INTCON,RBIF ; effacer flag interupt RB4/7 goto restorereg ; et fin d'interrupt ; détection interruptions périphériques ; le test peut être supprimé si une seule ; interrupt est traitée à la fois ; -------------------------------------- intsw3 btfss INTCON,PEIE ; tester interruption périphérique autorisée goto restorereg ; non, fin d'interruption ; Interruption convertisseur A/D ; ------------------------------ bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,ADIE ; tester si interrupt autorisée goto intsw4 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,ADIF ; tester si interrupt en cours goto intsw4 ; non sauter call intad ; oui, traiter interrupt bcf PIR1,ADIF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; Interruption réception USART ; ---------------------------- intsw4 bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,RCIE ; tester si interrupt autorisée goto intsw5 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,RCIF ; oui, tester si interrupt en cours goto intsw5 ; non sauter call intrc ; oui, traiter interrupt ; LE FLAG NE DOIT PAS ETRE REMIS A 0 ; C'EST LA LECTURE DE RCREG QUI LE PROVOQUE goto restorereg ; et fin d'interrupt ; Interruption transmission USART ; ------------------------------- intsw5 bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,TXIE ; tester si interrupt autorisée goto intsw6 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,TXIF ; oui, tester si interrupt en cours goto intsw6 ; non sauter call inttx ; oui, traiter interrupt ; LE FLAG NE DOIT PAS ETRE REMIS A 0 ; C'EST L'ECRITURE DE TXREG QUI LE PROVOQUE goto restorereg ; et fin d'interrupt ; Interruption SSP ; ---------------- intsw6 bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,SSPIE ; tester si interrupt autorisée goto intsw7 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,SSPIF ; oui, tester si interrupt en cours goto intsw7 ; non sauter call intssp ; oui, traiter interrupt bcf PIR1,SSPIF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; Interruption CCP1 ; ----------------- intsw7 bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,CCP1IE ; tester si interrupt autorisée goto intsw8 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,CCP1IF ; oui, tester si interrupt en cours goto intsw8 ; non sauter call intccp1 ; oui, traiter interrupt bcf PIR1,CCP1IF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; Interruption TMR2 ; ----------------- intsw8 bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,TMR2IE ; tester si interrupt autorisée goto intsw9 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,TMR2IF ; oui, tester si interrupt en cours goto intsw9 ; non sauter call inttmr2 ; oui, traiter interrupt bcf PIR1,TMR2IF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; Interruption TMR1 ; ----------------- intsw9 bsf STATUS,RP0 ; sélectionner banque1 btfss PIE1,TMR1IE ; tester si interrupt autorisée goto intsw10 ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR1,TMR1IF ; oui, tester si interrupt en cours goto intsw10 ; non sauter call inttmr1 ; oui, traiter interrupt bcf PIR1,TMR1IF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; Interruption comparateurs ; ------------------------- intsw10 BANK1 ; sélectionner banque1 btfss PIE1,CMIE ; tester si interrupt autorisée goto intswA ; non sauter BANK0 ; oui, sélectionner banque0 btfss PIR1,CMIF ; oui, tester si interrupt en cours goto intswA ; non sauter call intcmp ; oui, traiter interrupt goto restorereg ; et fin d'interrupt ; Interruption EEPROM ; ------------------- intswA bsf STATUS,RP0 ; sélectionner banque1 btfss PIE2,EEIE ; tester si interrupt autorisée goto intswB ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR2,EEIF ; oui, tester si interrupt en cours goto intswB ; non sauter call inteprom ; oui, traiter interrupt bcf PIR2,EEIF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; Interruption COLLISION ; ---------------------- intswB bsf STATUS,RP0 ; sélectionner banque1 btfss PIE2,BCLIE ; tester si interrupt autorisée goto intswC ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR2,BCLIF ; oui, tester si interrupt en cours goto intswC ; non sauter call intbc ; oui, traiter interrupt bcf PIR2,BCLIF ; effacer flag interupt goto restorereg ; et fin d'interrupt ; interruption CCP2 ; ----------------- intswC bsf STATUS,RP0 ; sélectionner banque1 btfss PIE2,CCP2IE ; tester si interrupt autorisée goto restorereg ; non sauter bcf STATUS,RP0 ; oui, sélectionner banque0 btfss PIR2,CCP2IF ; oui, tester si interrupt en cours goto restorereg ; non sauter call intccp2 ; oui, traiter interrupt bcf PIR2,CCP2IF ; effacer flag interupt goto restorereg ; et fin d'interrupt ;restaurer registres ;------------------- restorereg movf PCLATH_temp , w ; recharger ancien PCLATH movwf PCLATH ; le restaurer movf FSR_temp , w ; charger FSR sauvé movwf FSR ; restaurer FSR swapf status_temp,w ; swap ancien status, résultat dans w movwf STATUS ; restaurer status swapf w_temp,f ; Inversion L et H de l'ancien W ; sans modifier Z swapf w_temp,w ; Réinversion de L et H dans W ; W restauré sans modifier status retfie ; return from interrupt ;***************************************************************************** ; INTERRUPTION TIMER 0 * ;***************************************************************************** inttmr0 return ; fin d'interruption timer ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION RB0/INT * ;***************************************************************************** intrb0 return ; fin d'interruption RB0/INT ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION RB0/RB4 * ;***************************************************************************** intrb4 return ; fin d'interruption RB0/RB4 ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION CONVERTISSEUR A/D * ;***************************************************************************** intad return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION RECEPTION USART * ;***************************************************************************** intrc return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION TRANSMISSION USART * ;***************************************************************************** inttx return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION SSP * ;***************************************************************************** intssp return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION CCP1 * ;***************************************************************************** intccp1 return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION TIMER 2 * ;***************************************************************************** inttmr2 return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION TIMER 1 * ;***************************************************************************** inttmr1 return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;**************************************************************************** ; INTERUPTION COMPARATEUR * ;**************************************************************************** intcmp return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION EEPROM * ;***************************************************************************** inteprom return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION COLLISION * ;***************************************************************************** intbc return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ;***************************************************************************** ; INTERRUPTION CCP2 * ;***************************************************************************** intccp2 return ; fin d'interruption ; peut être remplacé par ; retlw pour retour code d'erreur ; //////////////////////////////////////////////////////////////////////////// ; P R O G R A M M E ; //////////////////////////////////////////////////////////////////////////// ;***************************************************************************** ; INITIALISATIONS * ;***************************************************************************** init ; initialisation PORTS (banque 0 et 1) ; ------------------------------------ BANK0 ; sélectionner banque0 clrf PORTA ; Sorties PORTA à 0 clrf PORTB ; sorties PORTB à 0 clrf PORTC ; sorties PORTC à 0 bsf STATUS,RP0 ; passer en banque1 movlw ADCON1VAL ; PORTA en mode digital/analogique movwf ADCON1 ; écriture dans contrôle A/D movlw DIRPORTA ; Direction PORTA movwf TRISA ; écriture dans registre direction movlw DIRPORTB ; Direction PORTB movwf TRISB ; écriture dans registre direction movlw DIRPORTC ; Direction PORTC movwf TRISC ; écriture dans registre direction ; Registre d'options (banque 1) ; ----------------------------- movlw OPTIONVAL ; charger masque movwf OPTION_REG ; initialiser registre option ; registres interruptions (banque 1) ; ---------------------------------- movlw INTCONVAL ; charger valeur registre interruption movwf INTCON ; initialiser interruptions movlw PIE1VAL ; Initialiser registre movwf PIE1 ; interruptions périphériques 1 movlw PIE2VAL ; initialiser registre movwf PIE2 ; interruptions périphériques 2 movlw CVRCONVAL ; charger la valeur du registre pour VREF movwf CVRCON ; initialiser le registre movlw CMCONVAL ; charger la valeur du registre des comparateurs movwf CMCON ; initialiser le registre ; Effacer RAM banque 0 ; --------------------- bcf STATUS,RP0 ; sélectionner banque 0 movlw 0x20 ; initialisation pointeur movwf FSR ; d'adressage indirect init1 clrf INDF ; effacer ram incf FSR,f ; pointer sur suivant btfss FSR,7 ; tester si fin zone atteinte (>7F) goto init1 ; non, boucler ; autoriser interruptions (banque 0) ; ---------------------------------- clrf PIR1 ; effacer flags 1 clrf PIR2 ; effacer flags 2 bsf INTCON,GIE ; valider interruptions goto start ; programme principal ;***************************************************************************** ; PROGRAMME PRINCIPAL * ;***************************************************************************** start clrwdt ; effacer watch dog goto start ; boucler END ; directive fin de programme