; "Acquisition de température via RS232" ; Utilisation de l'USART du 16F628A avec interruption ; 9600 bauds/s 8 bits de données Pas de bit de parité ; 1 bit de STOP Pas de contrôle de flux ; Quand le PIC reçoit la caractère 't' (code ASCII 0x74), ; le PIC lit les sorties de l'ADC et renvoie la température vers le PC ; sous la forme 19,6 (4 caractères ASCII) ; Plage de température : 00,0 à 51,0 °C par pas de 0,2 °C ; (C) Fabrice Sincère, mars 2007 ; IUT Nancy-Brabois ; version 1.03 ; microcontrôleur PIC 16F628A ; développé avec Microchip MPLAB IDE List p=16F628A ; processeur utilisé #include __config _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _DATA_CP_OFF & _BOREN_OFF & _MCLRE_ON ;bits de configuration : ;code protect OFF ;watchdog timer OFF ;power up timer ON ;oscillateur HS (quartz 4 MHz) ;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 0x070 ; début de la zone des registres d'usage général du 16F628A ; (banque quelconque : 0,1,2 ou 3) STATUS_TEMP : 1 ; sauvegarde du registre STATUS (routine d'interruption) W_TEMP : 1 ; sauvegarde du registre W (routine d'interruption) donnee_r : 1 ; 8 bits de données en réception donnee_t : 1 ; 8 bits de données en émission donnee_t_lsb : 1 ; 3 bits de poids faibles donnee_t_msb : 1 ; 5 bits de poids forts flag_t : 1 ; bit 0 mis à 1 quand réception du code ASCII 't' bcd0 : 1 ; octet de poids faible (code ASCII) bcd1 : 1 ; bcd2 : 1 ; octet de poids fort ; (bcd2 bcd1 bcd0) = (0x31 0x39 0x36) <=> 19,6 °C compteur : 1 ; compteur des caractères transmis (4) flag_e : 1 ; bit 0 mis à 1 quand l'émission des 4 caractères débute ENDC ;xxxxxxxxxxxxxxxxxxxx ; démarrage sur reset ;xxxxxxxxxxxxxxxxxxxx org 0x0000 goto initialisation ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ; Routine d'interruption ; 2 sources d'interruption : réception (USART) ; émission (USART) ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx org 0x0004 ; vecteur d'interruption movwf W_TEMP swapf STATUS,W movwf STATUS_TEMP ; sauvegarde du registre W puis du registre STATUS bank1 btfss PIE1, RCIE goto int1 bank0 btfsc PIR1, RCIF goto reception int1 bank1 btfss PIE1, TXIE goto int2 bank0 btfsc PIR1, TXIF goto emission int2 goto restauration ; traitement de l'interruption de réception de l'USART reception bank0 movf RCREG , W ; le flag RCIF est remis à 0 par une lecture du registre RCREG movwf donnee_r ; les 8 bits de données sont transféres dans (donnee_r) ; on teste si le code ASCII est 0x74 (caractère 't') movlw 0x74 subwf donnee_r , W btfsc STATUS , Z bsf flag_t , 0 ; drapeau mis à 1 ; test d'une erreur d'overrun bank0 btfss RCSTA , OERR goto int1 ; traitement de l'erreur d'overrun bcf RCSTA , CREN ; on efface le bit OERR bsf RCSTA , CREN ; on relance la réception goto int1 ; traitement de l'interruption d'émission de l'USART emission btfsc flag_e , 0 goto transmission btfss flag_t , 0 goto int2 bcf flag_t , 0 ; drapeau mis à 0 ; on arrive ici si l'on a reçu un caractère 't' movf PORTA , W ; lecture du port A movwf donnee_t_lsb movf PORTB , W ; lecture du port B movwf donnee_t_msb movlw B'00000111' ; masque andwf donnee_t_lsb , f movlw B'11111000' andwf donnee_t_msb , f movf donnee_t_lsb , W iorwf donnee_t_msb , W movwf donnee_t ; 8 bits de l'ADC ; xxxxx conversion binaire 8 bits -> BCD -> ASCII ; (donnee_t) = 00000000 <=> 00,0 °C ; (donnee_t) = 00000001 <=> 00,2 °C ; (donnee_t) = 11111111 <=> 51,0 °C ; (bcd2 bcd1 bcd0) = (0x31 0x39 0x36) <=> 19,6 °C clrf bcd2 clrf bcd1 clrf bcd0 ; (donnee_t) est utilisé comme compteur incf donnee_t , f conv0 decfsz donnee_t , f goto conv1 ; conversion bcd -> ASCII movlw 0x30 iorwf bcd0 , f iorwf bcd1 , f iorwf bcd2 , f movlw D'5' movwf compteur bsf flag_e , 0 ; drapeau mis à 1 goto transmission conv1 incf bcd0 , f incf bcd0 , f movlw D'10' subwf bcd0 , W btfss STATUS , Z goto conv0 clrf bcd0 incf bcd1 , f movlw D'10' subwf bcd1 , W btfss STATUS , Z goto conv0 clrf bcd1 incf bcd2 , f goto conv0 ; xxxxxxxxxxxxxxxxxxxxxxxx transmission bank0 decfsz compteur , f goto test4 bcf flag_e , 0 ; drapeau mis à 0 goto int2 test4 movlw D'4' subwf compteur , W btfss STATUS , Z goto test3 movf bcd2 , W ; transmission du 1er caractère ASCII goto transm test3 movlw D'3' subwf compteur , W btfss STATUS , Z goto test2 movf bcd1 , W ; transmission du 2eme caractère ASCII goto transm test2 movlw D'2' subwf compteur , W btfss STATUS , Z goto test1 movlw 0x2C ; transmission du 3eme caractère ASCII 0x2C (,) goto transm test1 ; compteur = 1 movf bcd0 , W ; transmission du 4eme caractère ASCII goto transm transm movwf TXREG ; transmission ; le flag TXIF est remis à 0 par une écriture dans le registre TXREG goto int2 restauration swapf STATUS_TEMP,W ; restauration des registres STATUS puis W movwf STATUS swapf W_TEMP,f swapf W_TEMP,W retfie ;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'11111111' movwf TRISA ; bit 0 du port A (RA0) = 1 : configuration en entrée (bit D0 LSB de l'ADC) ; bit 1 du port A (RA1) = 1 : configuration en entrée (bit D1 de l'ADC) ; bit 2 du port A (RA2) = 1 : configuration en entrée (bit D2 de l'ADC) ; bits 3 à 7 du port A (RA3 à RA7) = 1 : configuration en entrée, par exemple movlw B'11111111' movwf TRISB ; bit 0 du port B (RB0) = 1 : configuration en entrée, par exemple ; bit 1 du port B (RB0) = 1 : configuration en entrée (RX : USART) ; bit 2 du port B (RB0) = 1 : configuration en entrée (TX : USART) ; bit 3 du port B (RB3) = 1 : configuration en entrée (bit D3 de l'ADC) ; bit 4 du port B (RB4) = 1 : configuration en entrée (bit D4 de l'ADC) ; bit 5 du port B (RB5) = 1 : configuration en entrée (bit D5 de l'ADC) ; bit 6 du port B (RB6) = 1 : configuration en entrée (bit D6 de l'ADC) ; bit 7 du port B (RB7) = 1 : configuration en entrée (bit D7 MSB de l'ADC) movlw D'25' movwf SPBRG ; (SPBRG) = D'25' movlw B'00100100' movwf TXSTA ; bit 7 (CSRC) = 0 (non utilisé : 0 par exemple) ; bit 6 (TX9) = 0 : 8 bits de transmission ; bit 5 (TXEN) = 1 : autorise la réception ; bit 4 (SYNC) = 0 : mode asynchrone ; bit 3 = 0 (non implémenté) ; bit 2 (BRGH) = 1 : mode asynchrone haute vitesse ; bit 1 (TRMT) = 0 (en lecture seule) ; bit 0 (TX9D) = 0 (non utilisé : 0 par exemple) bank0 movlw B'10010000' movwf RCSTA ; bit 7 (SPEN) = 1 : utilisation du port série ; bit 6 (RX9) = 0 : 8 bits de réception ; bit 5 (SREN) = 0 (non utilisé : 0 par exemple) ; bit 4 (CREN) = 1 : autorise la réception ; bit 3 (ADEN) = 0 (non utilisé : 0 par exemple) ; bit 2 (FERR) = 0 (en lecture seule) ; bit 1 (OERR) = 0 (en lecture seule) ; bit 0 (RX9D) = 0 (non utilisé : 0 par exemple) clrf donnee_r clrf donnee_t clrf flag_t clrf flag_e bank1 bsf INTCON, GIE ; autorisation globale des interruptions bsf INTCON , PEIE ; autorisation des interruptions des périphériques bsf PIE1 , RCIE ; autorisation de l'interruption de réception de l'USART bsf PIE1 , TXIE ; autorisation de l'interruption d'émission de l'USART bank0 goto debut_programme ;xxxxxxxxxxxxxxxxxxxxx ; programme principal ;xxxxxxxxxxxxxxxxxxxxx debut_programme goto debut_programme ; on attend une interruption (USART) END