; "Dé électronique (6 faces)" ; (C) Fabrice Sincère, décembre 2006 ; IUT Nancy-Brabois ; version 1.02 ; microcontrôleur PIC 16F628A ; développé avec Microchip MPLAB IDE List p=16F628A ; processeur utilisé #include __config _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC_CLKOUT & _LVP_OFF & _DATA_CP_OFF & _BOREN_OFF & _MCLRE_ON ;bits de configuration : ;code protect OFF ;watchdog timer OFF ;power up timer ON ;oscillateur RC_CLKOUT : ;f#1/(RC) R=10k C=10nF fOSC#10kHz fOSC interne = fOSC/4 # 2,5 kHz ;low voltage program OFF ;data EE read protect OFF ;brown out detect OFF ;master clear enable ON ;xxxxxx ; macro ;xxxxxx bank1 macro ; passage en banque 1 bsf STATUS,RP0 bcf STATUS,RP1 endm bank0 macro ; passage en banque 0 bcf STATUS,RP0 bcf STATUS,RP1 endm ;xxxxxxxxxxxxxxxxxxxxxxxxx ; déclaration de variables ;xxxxxxxxxxxxxxxxxxxxxxxxx CBLOCK H'020' ; début de la zone des registres d'usage général du 16F628A STATUS_TEMP : 1 ; sauvegarde du registre STATUS (routine d'interruption) W_TEMP : 1 ; sauvegarde du registre W (routine d'interruption) valeur_de : 1 ; 1 à 6 ENDC ;xxxxxxxxxxxxxxxxxxxx ; démarrage sur reset ;xxxxxxxxxxxxxxxxxxxx org H'0000' goto initialisation ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ; Routine d'interruption ; 1 source d'interruption : ; RB0/INT sur front descendant ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx org H'0004' ; vecteur d'interruption movwf W_TEMP swapf STATUS,W movwf STATUS_TEMP ; sauvegarde du registre W puis du registre STATUS btfsc INTCON,INTF goto inter1 ; on teste qu'il s'agit bien d'une interruption RB0/INT goto restauration ; xxxxxxxxxxxxxxxxxxxxxxxxxxxx ; gestion interruption RB0/INT ; xxxxxxxxxxxxxxxxxxxxxxxxxxxx inter1 ; temporisation movlw B'11111101' movwf PORTB ; RB1 au niveau bas (le segment g est allumé) clrf TMR0 bcf INTCON,T0IF ; on efface le flag 'TMR0 Overflow Interrupt' tempo btfsc INTCON,T0IF ; on utise le registre TMR0 pour effectuer une temporisation goto fintempo ; d'environ 1,6 seconde : 256 cycles * 16 (prescaler) goto tempo fintempo movlw D'1' subwf valeur_de,W ; dé = 1 ? btfsc STATUS,Z goto de1 ; oui movlw D'2' ; non ; dé = 2 ? subwf valeur_de,W btfsc STATUS,Z goto de2 ; oui movlw D'3' ; non ; dé = 3 ? subwf valeur_de,W btfsc STATUS,Z goto de3 ; oui movlw D'4' ; non ; dé = 4 ? subwf valeur_de,W btfsc STATUS,Z goto de4 ; oui movlw D'5' ; non ; dé = 5 ? subwf valeur_de,W btfsc STATUS,Z goto de5 ; oui movlw D'6' ; non ; dé = 6 ? subwf valeur_de,W btfsc STATUS,Z goto de6 de1 movlw B'10011111' ; on affiche '1' movwf PORTB ; afficheur 7 segments (abcdefg) = (1001111) goto fininter1 de2 movlw B'00100101' ; on affiche '2' movwf PORTB ; afficheur 7 segments (abcdefg) = (0010010) goto fininter1 de3 movlw B'00001101' ; on affiche '3' movwf PORTB ; afficheur 7 segments (abcdefg) = (0000110) goto fininter1 de4 movlw B'10011001' ; on affiche '4' movwf PORTB ; afficheur 7 segments (abcdefg) = (1001100) goto fininter1 de5 movlw B'01001001' ; on affiche '5' movwf PORTB ; afficheur 7 segments (abcdefg) = (0100100) goto fininter1 de6 movlw B'11000001' ; on affiche '6' movwf PORTB ; afficheur 7 segments (abcdefg) = (1100000) goto fininter1 fininter1 bcf INTCON,T0IF ; on efface le flag 'TMR0 Overflow Interrupt' bcf INTCON,INTF ; on efface le flag 'RB0/INT' goto restauration restauration 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 movlw B'00000111' movwf CMCON ; inactivation des comparateurs analogiques bank1 movlw B'00000011' movwf OPTION_REG ; bit 7 (/RBPU) = 0 : activation des résistances de pull-up du port B ; (ce qui permet de faire l'économie d'une résistance externe sur RB0) ; bit 6 (INTEDG)= 0 : Interrupt on falling edge of RB0/INT pin ; bit 5 (T0CS) = 0 : Timer0 Clock Source Select = CLKOUT ; bit 3 (PSA) = 0 : Prescaler attribué au TMR0 ; bit 2 (PS2)= 0 ; bit 1 (PS1) = 1 ; bit 0 (PS0) = 1 : Facteur de division du prescaler = 1:16 ; bit 4 : ici, option non utilisée (= 0, par exemple) movlw B'00011111' movwf TRISA ; bits 0 à 4 du port A (RA0 à RA4) = 1 : non utilisés (configuration en entrée, par exemple) movlw B'00000001' movwf TRISB ; bit 0 du port B (RB0) = 1 : configuration en entrée (bouton poussoir) ; bit 1 du port B (RB1) = 0 : configuration en sortie (LED segment g de l'afficheur) ; bit 2 du port B (RB2) = 0 : configuration en sortie (LED segment f) ; bit 3 du port B (RB3) = 0 : configuration en sortie (LED segment e) ; bit 4 du port B (RB4) = 0 : configuration en sortie (LED segment d) ; bit 5 du port B (RB5) = 0 : configuration en sortie (LED segment c) ; bit 6 du port B (RB6) = 0 : configuration en sortie (LED segment b) ; bit 7 du port B (RB7) = 0 : configuration en sortie (LED segment a) bank0 movlw B'10010000' movwf INTCON ; bit 7 (GIE) = 1 : autorisation globale des interruptions ; bit 5 (T0IE)= 0 : inhibition de l'interruption de débordement du Timer0 ; bit 4 (INTE) = 1 : Enables the RB0/INT external interrupt ; bit 2 (T0IF) = 0 : on efface le flag 'TMR0 Overflow Interrupt' ; bit 1 (INTF)= 0 : on efface le flag 'RB0/INT External Interrupt' ; les autres bits sont inutilisés (valeur par défaut = 0) movlw B'11111101' movwf PORTB ; RB1 au niveau bas (le segment g est allumé) movlw D'1' movwf valeur_de ; initialisation de la valeur du dé à 1 goto debut_programme ;xxxxxxxxxxxxxxxxxxxxx ; programme principal ;xxxxxxxxxxxxxxxxxxxxx ; On attend un appui sur le bouton poussoir (RB0/INT), ce qui génére une interruption. ; A chaque boucle, on incrémente la valeur faciale du dé ; 1->2->3->4->5->6->1->2 ... ce qui tient lieu de générateur de nombre aléatoire. debut_programme movlw D'6' subwf valeur_de,W ; on compare (6) et (valeur_de) btfsc STATUS,Z goto de_6 ; (valeur_de)=6 nop ; 2 cycles (nop) indispensables : nop ; (valeur_de) change tous les 9 cycles incf valeur_de,f ; on incrémente (valeur_de) goto debut_programme de_6 movlw D'1' movwf valeur_de goto debut_programme END