; "Diapason La3 440 hertz" ; Fabrice Sincère (C) décembre 2006 ; IUT Nancy-Brabois ; version 1.03 ; microcontrôleur PIC 16F84A ; développé avec Microchip MPLAB IDE List p=16F84A ; processeur utilisé #include __config _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ;bits de configuration : ;code protect OFF ;watchdog timer OFF ;power up timer ON ;oscillateur HS (quartz à grande fréquence : 20 MHz) ;xxxxxx ; macro ;xxxxxx bank1 macro ; passage en banque 1 bsf STATUS,RP0 endm bank0 macro ; passage en banque 0 bcf STATUS,RP0 endm ;xxxxxxxxxxxxxxxxxxxxxxxxx ; déclaration de variables ;xxxxxxxxxxxxxxxxxxxxxxxxx CBLOCK H'00C' ; début de la zone des registres d'usage général du 16F84A compteur1 : 1 ; variable de la boucle de temporisation STATUS_TEMP : 1 ; sauvegarde du registre STATUS (routine d'interruption) W_TEMP : 1 ; sauvegarde du registre W (routine d'interruption) ENDC ;xxxxxxxxxxxxxxxxxxxx ; démarrage sur reset ;xxxxxxxxxxxxxxxxxxxx org H'0000' goto initialisation ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ; Routine d'interruption timer0 (en mode timer) ; 5682 cycles pour une demi période (pour un quartz de 20 MHz) ; 23*256 -206 ; 439,986 Hz nominale ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx org H'0004' ; vecteur d'interruption movwf W_TEMP swapf STATUS,W movwf STATUS_TEMP ; sauvegarde du registre W puis du registre STATUS incf compteur1,f ; on incrémente (compteur1) movf compteur1, W sublw D'22' ; on compare (compteur1) et D'22' btfss STATUS,Z goto suite1 ; (compteur1) différent de D'22' ; compteur1 égal à D'22': movlw D'209' addwf TMR0,f ; on incrémente le timer0 de 206+1+2 = 209 goto suite ; +1 car l'instruction addwf TMR0,f dure 1 cycle ; +2 car une instruction d'écriture (addwf) sur TMR0 ; inhibe TMR0 pendant deux cycles suite1 movf compteur1, W sublw D'23' ; on compare (compteur1) et D'23' btfss STATUS,Z goto suite ; (compteur1) différent de D'23' (et de D'22') ; (compteur1) égal à D'23': clrf compteur1 movlw B'00000001' xorwf PORTA,f ; on inverse l'état de la sortie RA0 (sortie 440 Hz La3) btfsc PORTA,0 goto suite movlw B'00000010' ; on inverse l'état de la sortie RA1 (sortie 220 Hz La2) xorwf PORTA,f ; sur le front descendant de RA0 btfsc PORTA,1 goto suite movlw B'00000100' ; on inverse l'état de la sortie RA2 (sortie 110 Hz La1) xorwf PORTA,f ; sur le front descendant de RA1 suite bcf INTCON,T0IF ; on efface le flag 'TMR0 Overflow Interrupt' swapf STATUS_TEMP,W ; restauration des registres STATUS puis W movwf STATUS swapf W_TEMP,f swapf W_TEMP,W retfie ; retour d'interruption ;xxxxxxxxxxxxxxx ; initialisation ;xxxxxxxxxxxxxxx initialisation bank0 clrf PORTA ; mise à 0 des sorties du port A clrf PORTB ; mise à 0 des sorties du port B bank1 movlw B'00001000' movwf OPTION_REG ; bit 5 (T0CS) = 0 : Timer0 Clock Source Select = CLKOUT ; bit 3 (PSA) = 1 : Prescaler attribué au Watchdog ; bit 2 (PS2)= 0 ; bit 1 (PS1) = 0 ; bit 0 (PS0) = 0 : Facteur de division du prescaler = 1:1 ; bits 4, 6 ,7 : ici, options non utilisées (on les met à 0, par exemple) movlw B'00011000' movwf TRISA ; bit 0 du port A (RA0) = 0 : configuration en sortie (440 Hz La3) ; bit 1 du port A (RA1) = 0 : configuration en sortie (220 Hz La2) ; bit 2 du port A (RA2) = 0 : configuration en sortie (110 Hz La1) ; bits 3 et 4 du port A (RA3 et RA4) = 1 : non utilisés (configuration en entrée, par exemple) movlw B'11111111' movwf TRISB ; bits 0 à 7 du port B (RB0 à RB7) = 1 : non utilisés (configuration en entrée, par exemple) bank0 movlw B'10100000' movwf INTCON ; bit 7 (GIE) = 1 : autorisation globale des interruptions ; bit 5 (T0IE)= 1 : autorisation de l'interruption de débordement du Timer0 ; bit 2 (T0IF) = 0 : on efface le flag 'TMR0 Overflow Interrupt' ; les autres bits sont inutilisés (valeur par défaut = 0) clrf PORTA ; sortie RA0, RA1 et RA2 au niveau bas clrf compteur1 ; mise à zero du compteur1 clrf TMR0 ; mise à zero du timer0 goto debut_programme ;xxxxxxxxxxxxxxxxxxxxx ; programme principal ;xxxxxxxxxxxxxxxxxxxxx debut_programme goto debut_programme ; on attend le débordement de TMR0 (H'FF' -> H'00') ; ce qui génére une interruption END