;---------------------------------------------------------------------- ;Release build of project `C:\Mplab8\_Mesprojets\_16F876\16F876_RS.mcp' started. ;Sun Oct 18 18:31:44 2009 ;---------------------------------------------------------------------- ;Clean: Deleting intermediary and output files. ;Clean: Deleted file "C:\Mplab8\_Mesprojets\_16F876\16F876A_rs232.err". ;Clean: Deleted file "C:\Mplab8\_Mesprojets\_16F876\16F876A_rs232.cod". ;Clean: Deleted file "C:\Mplab8\_Mesprojets\_16F876\16F876A_rs232.hex". ;Clean: Deleted file "C:\Mplab8\_Mesprojets\_16F876\16F876A_rs232.lst". ;Clean: Deleted file "C:\Mplab8\_Mesprojets\_16F876\16F876_RS.mcs". ;Clean: Done. ;Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F876 ; "16F876A_rs232.asm" ;/l"16F876A_rs232.lst" /e"16F876A_rs232.err" ;Loaded C:\Mplab8\_Mesprojets\_16F876\16F876A_rs232.cod. ;---------------------------------------------------------------------- ;Release build of project `C:\Mplab8\_Mesprojets\_16F876\16F876_RS.mcp' succeeded. ;Sun Oct 18 18:32:02 2009 ;---------------------------------------------------------------------- ;BUILD SUCCEEDED ; programme de test ; fonction UART … 19200bds 8bits datas ; PIC16F876A en DIP28 narrow ; pin 21 RB0 -- led blanche - R 390 -- +5V ; pin17 RC6 Tx ----vert ---- 3 de DS275 5 -- RS232 --> Ecran ; pin18 RC7 Rx --- blc/vert--- 1 de DS275 7 -- RS232 <-- Clavier ; pin 9 et 10 Quartz Q=20MHz ; pin 8 VSS ;acquisition de 3 mesures ANA ; PORTA,5 (pin 7) <----------- Entree ANALOGIQUE 4 ; PORTA,4 (pin 6) libre I/O ; PORTA,3 (pin 5) ---------> +REF 5.00V => 1023 ; PORTA,2 (pin 4) <--------- -REF 0.00V => 0000 ; PORTA,1 (pin 3) <----------- Entree ANALOGIQUE 1 ; PORTA,0 (pin 2) <----------- Entree ANALOGIQUE 0 ;************************************************* #include list p=PIC16F876A,c=132,n=60,st=ON,mm=ON,t=ON,x=ON,r=hex __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC __IDLOCS H'2100' ; version du bootloader ERRORLEVEL -302 ;=========== declarations de variables ========= cblock 0x20 ; en bank0 buff Buffer_Texte :.32 ptr1 : 1 ; pointeur temporaire 1 ptr2 : 1 ; pointeur temporaire 2 octemp : 1 ; sauvegarde temporaire SEC MIN HEURE JourSem Jour Mois Annee CtrlReg Conf ADDR DEV_DS1307 ; adresse DS1307 RTC DEV_1624 ; Adresse DS1624 mesure Tø DEV_PCF8574 ; O_BYTE I_BYTE _N _N0 _N1 _Cpt1 _Cpt2 _RsByte _Temp1 _Temp2 _10it addwrite Voie IntervalSec Drapeaux ; Drapeaux de 8 bits … usage multiple ;7 signe 1=negatif ;6 elligible =1 ;5 si=1 => affichage 00000 … 999999 sinon si =0 affichage XXX.XX ;4 ;3 ;2 ;1 ;0 endc LastBank0 EQU Drapeaux IF ( LastBank0 >= 0x70 ) ERROR "Attention debordement zone RAM bank0" ENDIF ;---------------------------- cblock 0xA0 ; en bank1 Cpt10 ; Bcd Mcount btmp btmp1 dixmil mille cent dix un ; variables 16 bits SommeTamb :1 MesAn0 :2 MesAn1 :2 MesAn4 :2 valx :2 val1 :2 val2 :2 val3 :2 reste :2 result :2 count1 ;delay routines count2 ;delay routines count3 ;delay routines Nb_1 ; compteur bit pour Max186 endc ;------------------------- ; COMMON DATA AREA ;------------------------- CBLOCK 0x71 ;Attention 0x70 ... used by bootloader w_temp : 1 ; Sauvegarde registre W status_temp : 1 ; sauvegarde registre STATUS FSR_temp : 1 ; sauvegarde FSR (si indirect en interrupt) PCLATH_temp : 1 time:1 bufinptr : 1 ; pointeur sur caractere courant buffer entr‚e bufoutptr : 1 ; pointeur sur caractere courant buffer sortie flags : 1 ; 8 flags divers ; b0 : parit‚ calcul‚e ; b1 : erreur de parit‚ ; b2 : erreur de frame ; b3 : erreur overflow local1 : 1 ; variable locale pour interruptions ENDC LastCDA equ PCLATH_temp IF ( LastCDA > 0x7F ) ERROR "Attention debordement zone RAM Bootloader en bank0" ENDIF #DEFINE PARITE flags,0 ; parit‚ calcul‚e #DEFINE ER_PAR flags,1 ; erreur de parit‚ #DEFINE ER_FR flags,2 ; erreur de frame #DEFINE ER_OV flags,3 ; erreur d'overflow #define FOSC D'20000000' #define TIMEOUT D'10' ; <<< uniquement pour TIME - temps = [0.1s] ; variables gestion PWM IF FOSC > D'10240000' #define T1PS 8 #define T1SU 0x31 ELSE IF FOSC > D'5120000' #define T1PS 4 #define T1SU 0x21 ELSE IF FOSC > D'2560000' #define T1PS 2 #define T1SU 0x11 ELSE #define T1PS 1 #define T1SU 0x01 ENDIF ENDIF ENDIF TIMER EQU (D'65538'-(FOSC/(D'10'*4*T1PS))) ;*********************** ; VARIABLES BANQUE 2 * ;*********************** ; Zone de 96 bytes CBLOCK 0x110 ; Debut de la zone (0x110 … 0x16F) bufin : D'96' ; zone de stockage des donnees entrees ENDC ; Fin de la zone ;*********************** ; VARIABLES BANQUE 3 * ;*********************** ; Zone de 96 bytes ; ---------------- CBLOCK 0x190 ; Debut de la zone (0x190 … 0x1EF) bufout : D'96' ; message … envoyer ENDC ;=========== fin declaration de variables =========== #define BAUD D'19200' ; <<< vitesse du port serie [bit/sec] #define BAUD_ERROR D'4'; <<< erreur de vitesse [%] #define ProgHI 0x1FFF #define LoaderTop ProgHI-(ICD_DEBUG*0x100) ; adresse haute du bootloader #define DIVIDER (FOSC/(D'16' * BAUD))-1 #define Analog0 PORTA,0 ;pin2 #define RETENUE Drapeaux,7 #define ELLIGIBLE Drapeaux,6 #define I2C_SDA PORTB,7 ;RB7 (pin 28) ---> output-->SDA #define I2C_SCL PORTB,6 ;RB6 (pin 27) <--in/out---> SCL CONSTANT TABUL =.9 ; caractere ascii tabulation Buffer_MAJ EQU SEC BRGVAL EQU D'12' ; pour un debit de 38400 bauds en mode high-speed ;************************************************ ORG 0x0000 nop ; pour ICSP nop ; pour ICSP nop ; pour ICSP goto init ;---------------------------- ;interruption ;---------------------------- org 0x04 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 ; est-ce une interrupt sur RB0 ; btfsc INTCON,INTE ; tester si interrupt Rb0 autorisee ; btfss INTCON,INTF ; oui, tester si Flag Rb0 arme ; goto Timer1_int ; NON ;Rb0_int ; bcf INTCON,INTE ; raz autorise int RB0 ; bcf INTCON,INTF ; en sortie de traitement interrupt Rb0 devalid‚e! ; todo ; goto restorereg ;-------------------------------- ; Interruption transmission USART ; ------------------------------- Uart_Tx_Int bank1 btfss PIE1,TXIE ; tester si interrupt autoris‚e goto Uart_Rx_Int ; non sauter bank0 btfss PIR1,TXIF ; oui, tester si interrupt en cours goto Uart_Rx_Int ; non sauter call inttx ; oui, traiter interrupt ;-------------------------------- ; Interruption reception USART ;------------------------------- Uart_Rx_Int bank1 btfss PIE1,RCIE ; tester si interrupt autoris‚e goto Timer1_int ; non sauter bank0 btfss PIR1,RCIF ; oui, tester si interrupt en cours goto Timer1_int ; non sauter call intrc ; oui, traiter interrupt ;-------------------------------- ; Interruption TIMER1 ;------------------------------- Timer1_int btfss PIR1,TMR1IF ; oui, tester si Flag interrupt arme goto restorereg ; non test suivant decf _10it,f btfss STATUS,Z goto Tim11 bsf ELLIGIBLE ; arme drapeau,6 => ok pour mesure movlw .10 movwf _10it ; 10 x10000æS =1sec movlw .32 ; led change XORWF PORTA,f Tim11 movlw LOW (.65536-.15535) movwf TMR1L movlw HIGH (.65536-.15535) movwf TMR1H bcf PIR1,TMR1IF ; RAZ flag interrupt goto restorereg 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 movwf STATUS ; restaurer status swapf w_temp , f ; Inversion L et H de l'ancien ; sans modifier Z swapf w_temp , w ; R‚inversion de L et H dans ; W restaur‚ sans modifier retfie ; return from interrupt ;***************************************************************************** ; INTERRUPTION RECEPTION USART * ;***************************************************************************** ; Re‡oit le caractere de l'USART et le place dans le buffer d'entr‚e. ; Si la longueur atteint D'96', on n'encode plus, et on place 0x0D en avant- ; derniere position et 0x0A en derniere position ; Si la reception est terminee (longueur atteinte ou 0x0A recu), on stoppe les ; interruptions de reception et on repositionne le pointeur au d‚but du buffer ; Les erreurs sont detectees et signalees intrc ; tester si erreur de frame btfsc RCSTA,FERR ; tester si erreur de frame bsf ER_FR ; oui, signaler erreur de frame ; lire la parite bcf PARITE ; par defaut, parite = 0 btfsc RCSTA,RX9D ; parite lue = 1? bsf PARITE ; oui, le signaler ; lire octet recu bsf STATUS,IRP ; pointer banques 2 et 3 en indirect movf bufinptr,w ; charger pointeur destination movwf FSR ; dans pointeur d'adresse movf RCREG,w ; charger octet re‡u movwf INDF ; sauver dans buffer ; verifier la parite intrc1 movf INDF,w ; charger caractere recu xorlw 0x0A ; comparer avec line-feed btfsc STATUS,Z ; identique? goto intrcend ; oui, fin de message ; verifier si buffer plein incf bufinptr,f ; incr‚menter pointeur de caracteres movf FSR,w ; charger pointeur xorlw 0x6D ; comparer avec dernier emplacement possible btfss STATUS,Z ; identique? return ; non, fin de reception incf FSR,f ; pointeur sur emplacement suivant movlw 0x0D ; mettre carriage-return movwf INDF ; en avant-derniere position incf FSR,f ; pointer sur derniere position movlw 0x0A ; charger line-feed movwf INDF ; en derniere position intrcend ; fin de message movlw LOW bufin ; oui, adresse de depart du buffer d'entree movwf bufinptr ; prochain caractere sera le premier bank1 bcf PIE1,RCIE ; fin des interruptions de reception bank0 return ;***************************************************************************** ; INTERRUPTION EMISSION USART * ;***************************************************************************** ; envoie le caractere point‚ par bufoutptr, puis incremente le pointeur ; Si ce caractere est le "line-feed", alors on arrete l'emission et on pointe de ; nouveau au debut du buffer ;----------------------------------------------------------------------------- inttx ; Charger octet … envoyer bsf STATUS,IRP ; pointer banques 3 et 4 movf bufoutptr,w ; charger pointeur d'octets movwf FSR ; dans pointeur movf INDF,w ; charger octet … envoyer bank0 movwf TXREG ; envoyer octet incf bufoutptr,f ; pointer sur octet suivant ; tester si fin de message xorlw 0x0A ; comparer octet envoy‚ avec Line-feed btfss STATUS,Z ; egalite return ; non, retour d'interruption ; traiter fin d'‚mission bsf STATUS,RP0 ; passer en banque 1 bcf PIE1,TXIE ; fin des interruptions ‚mission USART bank0 movlw LOW bufout ; adresse du buffer de sortie movwf bufoutptr ; prochain caractere = premier return ; fin d'interruption ;****************************************************************** init ;------------------------------------------ ; Configuration Voie ANALOGIQUE et logiques ;right justified, max.ref = sur RA3 pin4 et min.ref= sur RA2 pin 3 ; voie analogique AN0 pin RA0 sur Pin 2 ; voie analogique AN1 pin RA1 sur Pin 3 ; voie analogique AN4 pin RA5 sur pin 7 ; RA4=Digital sur Pin 6 ;------------------------------------------- bank1 movlw b'10001011' ; RA0,RA1,RA2,RA5= ANA, RA3=+Vref, RE0..RE2=digital ,cadre a droite movwf ADCON1 ; 1100 D D D A VREF+ VREF- A A movlw b'00111111' ; RA0 .... RA5 en entrees car ANA en Entrees movwf TRISA movlw b'11001000' ; RB0,RB1,RB2 en sorties ,RB3 en entree ,RB4,RB5 en sortie Rb6,RB7 en entrees movwf TRISB movlw b'11011000' ; SCL, SDA et Rx Uart en entrees movwf TRISC clrf OPTION_REG bsf OPTION_REG,7 ;=1 disable pull_up bcf OPTION_REG,6 ;INTEDG =0 int sur front descendant RB0 bank0 clrf Voie ;------------------------------------------ ;bit 7-6: ADCS1:ADCS0: A/D Conversion Clock Select bits 10 = FOSC/32 ;bit 5-3: CHS2:CHS0: Analog Channel Select bits 000 = channel 0, (RA2/AN2) RA0,1,2,3,5 ;bit 2: GO/DONE: A/D Conversion Status bit,If ADON = 1 1=in progress 0=Done ;bit 1: Unimplemented: Read as '0' ;bit 0: ADON: A/D On bit 1 = A/D converter module is operating movlw b'10000001' ;clock/32 Channel=0 ADON=1 movwf ADCON0 clrf INTCON ;--------------------------------------------------------------------- ;config UART asynchrone ; pin17=RC6=Tx ------vert ---------- 3 de DS275 --- RS232 --> Ecran ; pin18=RC7=Rx ------blznc/vert ---- 1 de DS275 --- RS232 <-- Clavier ;---------------------------------------------------------------------- bank1 ; b7=0 ; b6=0=TX9 8 bits datas ; b5=1=TXEN Transmit ENable ; b4=0 SYNC=0 Asynchrone ; b3=0 ; b2=1 BRGH=1 high speed ; b1=x TRMT Status registre TRANSMISIION 1=vide ; b0=0 TX9D 9em bit data movlw 0x24 ;BRGH=1 TXEN=1 movwf TXSTA ;Si BRGH = 1 ;Debit = Fosc / (16 * (SPBRG + 1))soit SPBRG = (Fosc / (D‚bit * 16)) - 1 movlw DIVIDER ; generateur de baud rate 38400bauds soit 12 movwf SPBRG bank0 ; b7=1 SPEN serial port ENAble ; b6=0 RX9 8 bits datas ; b5=0 ; b4=1 CREN Continuous enable bit ; b3=0 ADDEN Adress Detect Enable Bit ; b2=0 FERR Frame Error ; b1=0 OERR Over Flow Error ; b0=0 RX9D Receive 9em bit data movlw 0x90 ; SPEN = 1, CREN = 1 movwf RCSTA ; initialiser variables ; --------------------- clrf flags ; effacer flags movlw LOW bufin ; adresse du buffer de r‚ception movwf bufinptr ; dans pointeur movlw LOW bufout ; adresse basse du buffer d'‚mission movwf bufoutptr ; dans pointeur ;-------------------------------------------- ;config TIMER1 ;-------------------------------------------- movlw b'00110000' ; prescaler=8 Internal clock=Fosc/4 movwf T1CON movlw LOW (.65536-.15535) movwf TMR1L movlw HIGH (.65536-.15535) movwf TMR1H movlw .10 movwf _10it bank1 bsf PIE1,TMR1IE ; autoriser interruptions timer 1 bank0 bsf INTCON,PEIE ; interruptions peripheriques en service bsf T1CON,TMR1ON ; mettre timer 1 en service ;=============== MAIN ===================== movlw B'01001000' ; A0=0 A1=0 A2=1 MOVWF DEV_PCF8574 ; Presentation bcf PORTB,0 call delay_1S CALL Rs_CrLf clrf _Cpt1 movlw 0 call Msg_Eeprom call delay_1S bsf PORTB,0 call delay_1S movlw EE1-EE0 call Msg_Eeprom CALL Rs_CrLf movlw TIMEOUT+1 movwf time boucle bcf PORTB,0 call delay_1S bsf PORTB,0 call delay_1S movlw EE2-EE0 call Msg_Eeprom clrf _Cpt2 movlw TABUL call Rs_Putchar movlw 0x81 ;ana0 movwf Voie call Acquis_Ana call delay_100mS movlw 0x89 ; ana1 movwf Voie call Acquis_Ana call delay_100mS movlw 0xA1 ; ana4 movwf Voie call Acquis_Ana CALL Rs_CrLf goto boucle ;********** Subroutines **************** Acquis_Ana ;armemement acquisition Analogique bank0 movf Voie,w movwf ADCON0 bsf ADCON0,ADON ; set Analog Converter ON (ADCON0,0=1) call delay_25uS bsf ADCON0,GO_DONE ; set GO on start conversion (ADCON0,2=1) call delay_25uS call delay_25uS bcf RETENUE ; Positif not_yet btfsc ADCON0,NOT_DONE ; conversion AD ok ?(ADCON0,2=0 ???) goto not_yet bank0 movf ADRESH,w bank1 movwf val1 movwf val3 movf ADRESL,w movwf val1+1 movwf val3+1 Posit1 bank0 bcf Drapeaux,5 ; mode XXXXX bcf RETENUE call bcd_temp ; remplit le buffer d'affichage ASCII movlw TABUL call Rs_Putchar return ;---------------- sub16 bank1 movf val2+1,W ; source subwf val1+1,F ; dest movf val2,W btfss STATUS,C incfsz val2,W subwf val1,F ;dest = dest - source, WITH VALID CARRY return ;--------------------- delay_25uS bank1 movlw 0x01 movwf count1 movlw 0x01 movwf count2 movlw .10 movwf count3 goto delay1 delay_100uS bank1 movlw 0x01 movwf count1 movlw 0x01 movwf count2 movlw .40 movwf count3 goto delay1 delay_200uS bank1 movlw 0x01 movwf count1 movlw 0x01 movwf count2 movlw .80 movwf count3 goto delay1 delay_300uS bank1 movlw 0x01 movwf count1 movlw 0x01 movwf count2 movlw .120 movwf count3 goto delay1 delay_500uS bank1 movlw 0x01 movwf count1 movlw .1 movwf count2 movlw .200 movwf count3 goto delay1 delay_1mS bank1 movlw 0x01 movwf count1 movlw .2 movwf count2 movlw .144 movwf count3 goto delay1 delay_5mS bank1 movlw 0x01 movwf count1 movlw .8 movwf count2 movlw .205 movwf count3 goto delay1 delay_10mS bank1 movlw 0x01 movwf count1 movlw .16 movwf count2 movlw .154 movwf count3 goto delay1 delay_25mS bank1 movlw 0x01 ;24,36mS /4Mhz movwf count1 ;25,4mS /32Mhz movlw .40 movwf count2 movlw .1 movwf count3 goto delay1 delay_100mS bank1 movlw 1 movwf count1 movlw .157 movwf count2 movlw .2 movwf count3 goto delay1 delay_250mS bank1 movlw 1 movwf count1 movlw .196 movwf count2 movlw .2 movwf count3 goto delay1 delay_500mS bank1 movlw .4 movwf count1 movlw .14 movwf count2 movlw .55 movwf count3 goto delay1 delay_1S bank1 movlw .7 movwf count1 movlw .27 movwf count2 movlw .112 movwf count3 goto delay1 delay1 decfsz count3,f goto $-1 decfsz count2,f goto $-3 decfsz count1,f goto $-5 bank0 return ;--------------- Rs_CrLf bank0 movlw .13 call Rs_Putchar movlw .10 call Rs_Putchar return ;--------------- Rs_Putchar bank0 clrwdt Rs_P1 btfss PIR1,TXIF ; while(!TXIF) goto Rs_P1 movwf TXREG ; TXREG = octet return ;************ getbyte subroutine ************ getbyte ; clrwdt btfsc ELLIGIBLE goto fin_getbyte gb1 btfss PIR1,RCIF ; while(!RCIF) goto gb1 movf RCREG,w ; RCREG return fin_getbyte bcf ELLIGIBLE movlw '*' return ;----------------- Rs_Getchar bank0 clrwdt Rs_G1 btfss PIR1,RCIF ; while(!RCIF) goto Rs_G1 movf RCREG,w ; RCREG return ;--------------- Msg_Eeprom bank0 movwf _Cpt1 Msg_eep1 movf _Cpt1,w call Read_EE incf _Cpt1,f ANDLW 0x0FF BTFSC STATUS, Z Return call Rs_Putchar goto Msg_eep1 return ;------- ; subroutine to read EEPROM memory ;(adresse & r‚sultat en w) Read_EE ; 16F876 bank2 MOVWF EEADR ;Data Memory Address to read bank3 BCF EECON1, EEPGD ;Point to DATA memory BSF EECON1, RD ;EEPROM Read bank2 MOVF EEDATA, W ;W = EEDATA bank0 return ;--------------------------- Write_EE ; la donne‚e se trouve dans W bank2 movwf EEDATA ; placer data dans registre bank0 movlw addwrite ; charger adresse d'ecriture bank2 movwf EEADR ; placer dans registre bank3 bcf EECON1 , EEPGD ; pointer sur memoire data bsf EECON1 , WREN ; autoriser acces ecriture bcf INTCON , GIE ; interdire interruptions movlw 0x55 ; charger 0x55 movwf EECON2 ; envoyer commande movlw 0xAA ; charger 0xAA movwf EECON2 ; envoyer commande bsf EECON1 , WR ; lancer cycle d'‚criture bsf INTCON , GIE ; r‚autoriser interruptions loop clrwdt ; effacer watchdog btfsc EECON1 , WR ; tester si ‚criture termin‚e goto loop ; non, attendre bcf EECON1 , WREN ; verrouiller prochaine ‚criture bank0 return ;--------------- ; conv mot 16bits --> en XX.XXøC 25.42øC bcd_temp bank1 movf val1,W movwf valx movf val1+1,W movwf valx+1 swapf valx,W iorlw 0xf0 movwf mille addwf mille,F addlw 0xE2 ; 226 movwf cent addlw 0x32 ;50 movwf un movf valx,W andlw 0x0F addwf cent,F addwf cent,F addwf un,F addlw 0xE9 ;233 movwf dix addwf dix,F addwf dix,F swapf valx+1,W ;<- modif 20mars03 was val1 andlw 0x0F addwf dix,F addwf un,F rlf dix,F rlf un,F comf un,F rlf un,F movf valx+1,W andlw 0x0F addwf un,F rlf mille,F movlw 0x07 movwf dixmil movlw 0x0A Lb1: addwf un,F decf dix,F btfss STATUS,C goto Lb1 Lb2: addwf dix,F decf cent,F btfss STATUS,C goto Lb2 Lb3: addwf cent,F decf mille,F btfss STATUS,C goto Lb3 Lb4: addwf mille,F decf dixmil,F btfss STATUS,C goto Lb4 bank0 btfss Drapeaux,5 ; 1 => affichage 00000 … 999999 goto Bcd_5digits ; 0 => affichage + ou - XXX.XX movlw ' ' btfsc RETENUE movlw '-' call Rs_Putchar bank1 movf mille,w btfss STATUS,Z ; si digit=0 remplace par Blanc goto Lb5 bank0 movlw ' ' call Rs_Putchar bsf Drapeaux,1 goto Lb6 Lb5 bank0 addlw '0' call Rs_Putchar Lb6 bank1 movf cent,w addlw '0' call Rs_Putchar movlw '.' call Rs_Putchar bank1 movf dix,w addlw '0' call Rs_Putchar bank1 movf un,w addlw '0' call Rs_Putchar return ;--------------- Bcd_5digits bank1 ; movf dixmil,w ; addlw '0' ; call Rs_Putchar ; bank1 movf mille,w addlw '0' call Rs_Putchar bank1 movf cent,w addlw '0' call Rs_Putchar bank1 movf dix,w addlw '0' call Rs_Putchar bank1 movf un,w addlw '0' call Rs_Putchar movlw ' ' call Rs_Putchar return ;================================================================ ;Saisie_Caracteres: ; 2 caracteres par octet => BCD format 00 a 99 ; preciser la longueur du buffer a remplir dans W <= N-1 caracteres ; Buffer_MAJ = buffer de stockage en page 0 movwf _N1 ; Index de rangement 2 car -> 1 emplacement bcf INTCON,T0IE ; interdit interrupt timer0 Actualise bsf INTCON,GIE clrf _RsByte bsf INTCON,INTE ;Autorise interrupt RB0 ;attente saisi caractere au clavier Actu3 btfss ELLIGIBLE goto Actu3 bcf ELLIGIBLE bcf INTCON,GIE bcf INTCON,INTE ;interdit interrupt RB0 movf _RsByte,W ;echo call Rs_Putchar movlw .27 ;esc (abandon) xorwf _RsByte,w btfss STATUS,Z goto Test_Back return Test_Back movlw .8 ;back space (<- correction) xorwf _RsByte,w btfss STATUS,Z goto Test_Tab movlw Buffer_MAJ subwf _N1,w btfsc STATUS,C ; negatif ? goto Actualise incf _N1,f ;incremente indice goto Actualise Test_Tab movlw .9 ;tabulation (-> correction) xorwf _RsByte,w btfss STATUS,Z goto Test_Num decf _N1,w btfsc STATUS,C ; negatif ? goto Test_Num decf _N1,f ;decremente indice goto Actualise Test_Num movlw '0' subwf _RsByte,w btfsc STATUS,C goto SUP_0 goto Actualise SUP_0 movlw '9' subwf _RsByte,w btfsS STATUS,C goto LESS_EQ_9 ; less <9 btfsC STATUS,Z goto LESS_EQ_9 ;or egal =9 goto Actualise LESS_EQ_9 btfsc _N1,0 ;test bit 0 du compteur goto HB goto LB HB MOVLW .48 subWF _RsByte,w movwf _Temp2 ;=x1 bcf STATUS,C rlf _Temp2,f ;x2 rlf _Temp2,f ;x4 btfsc Drapeaux,5 ; si drapeau:5=1 *10 , sinon *16 goto HB1 bcf STATUS,C ; <- rajout 31/01/07 rlf _Temp2,f ;x2 rlf _Temp2,f ;x4 goto HB2 HB1 addwf _Temp2,w ;x5 movwf _Temp2 rlf _Temp2,f ;x10 HB2 decf _N1,f goto Actualise LB MOVLW .48 subWF _RsByte,w AndLW 0x0F ; MSB + LSB addwf _Temp2,W movwf _RsByte Rangement ; dans buffer specifique Horodatage bcf STATUS,C rrf _N1,W ; Index/2= deplacement en octet ADDLW Buffer_MAJ ; offset table movwf FSR movf _RsByte,w movwf INDF ; sauvegarde W -> @FSR() movf _N1,w btfsc STATUS,Z goto OK_Saisie decf _N1,f btfss STATUS,Z goto Actualise OK_Saisie bcf INTCON,GIE movf _RsByte,w return ;-------------------------------------- ; The following routines are low level I2C routines applicable to most ; interfaces with I2C devices. ;------------------------------------------------------ I2C_DELAY goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 return ;--------------- START: bsf STATUS,RP0 bcf I2C_SDA bcf STATUS,RP0 bsf I2C_SDA bsf I2C_SCL ;I2C start: change of SDA call I2C_DELAY ;from 1 to 0 while SCL = 1 bcf I2C_SDA call I2C_DELAY bcf I2C_SCL return ;--------------------- STOP: bsf STATUS,RP0 bcf I2C_SDA bcf STATUS,RP0 bcf I2C_SDA bsf I2C_SCL ;I2C stop: change of SDA call I2C_DELAY ;from 0 to 1 while SCL = 1 bsf I2C_SDA return ;--------------------- M_ACK: bsf STATUS,RP0 bcf I2C_SDA bcf STATUS,RP0 bcf I2C_SDA ;I2C master acknowledge: call I2C_DELAY ;SDA = 0 bsf I2C_SCL call I2C_DELAY bcf I2C_SCL return ;---------- NACK: bsf STATUS,RP0 bcf I2C_SDA bcf STATUS,RP0 bsf I2C_SDA ;I2C master non-acknowledge: call I2C_DELAY ;SDA = 1 bsf I2C_SCL call I2C_DELAY bcf I2C_SCL return ;----------- ACK: bsf STATUS,RP0 bsf I2C_SDA bcf STATUS,RP0 call I2C_DELAY ;I2C device acknowledge: bsf I2C_SCL ;SDA set 1 by master call I2C_DELAY ;SDA = 1 if device doesn't ACK bsf STATUS,Z ;SDA = 0 if devcie acknowledges btfsc I2C_SDA bcf STATUS,Z ;STATUS,Z=1 if device acknowledges bcf I2C_SCL ;STATUS,Z=0 if device doesn't ACK return ;------------ CLOCK_PULSE: ; SCL momentarily to logic one CALL HIGH_SCL call I2C_DELAY CALL LOW_SCL call I2C_DELAY RETURN ;------------ HIGH_SDA: ; high impedance by making SDA an input BSF I2C_SDA bank1 nop BSF I2C_SDA ; make SDA pin an input bank0 call I2C_DELAY RETURN ;------------ LOW_SDA: bank1 BCF I2C_SDA ; make SDA pin an output bank0 nop BCF I2C_SDA call I2C_DELAY RETURN ;------------ HIGH_SCL: BSF I2C_SCL bank1 nop BSF I2C_SCL ; make SCL pin an input bank0 call I2C_DELAY RETURN ;------------ LOW_SCL: bank1 BCF I2C_SCL ; make SCL pin an output bank0 BCF I2C_SCL call I2C_DELAY RETURN ;--------------------- ; The following routines are low level I2C routines applicable to most ; interfaces with I2C devices. IN_BYTE ; read byte on i2c bus CLRF I_BYTE MOVLW .8 MOVWF _N0 ; set index to 8 CALL HIGH_SDA ; be sure SDA is configured as input IN_BIT CALL HIGH_SCL ; clock high BTFSS I2C_SDA ; test SDA bit GOTO IN_ZERO GOTO IN_ONE IN_ZERO BCF STATUS, C ; clear any carry RLF I_BYTE, F ; i_byte = i_byte << 1 | 0 GOTO CONT_IN IN_ONE BCF STATUS, C ; clear any carry RLF I_BYTE, F INCF I_BYTE, F ; i_byte = (i_byte << 1) | 1 GOTO CONT_IN CONT_IN CALL LOW_SCL ; bring clock low DECFSZ _N0, F ; decrement index GOTO IN_BIT RETURN ;------------- OUT_BYTE: ; send o_byte on I2C bus MOVWF O_BYTE MOVLW .8 MOVWF _N0 OUT_BIT: BCF STATUS,C ; clear carry RLF O_BYTE, F ; left shift, most sig bit is now in carry BTFSS STATUS, C ; if one, send a one GOTO OUT_ZERO GOTO OUT_ONE OUT_ZERO: CALL LOW_SDA ; SDA at zero CALL CLOCK_PULSE CALL HIGH_SDA GOTO OUT_CONT OUT_ONE: CALL HIGH_SDA ; SDA at logic one CALL CLOCK_PULSE GOTO OUT_CONT OUT_CONT: DECFSZ _N0, F ; decrement index GOTO OUT_BIT RETURN ;--------------- Init_RTC CALL STOP call delay_25mS CALL START MOVLW 0xD0 ; B'11010000'=0xD0 = adresse device CALL OUT_BYTE CALL ACK clrf ADDR MOVF ADDR, W ; addresse registre CALL OUT_BYTE CALL ACK MOVF SEC,W CALL OUT_BYTE CALL ACK ; a ce momment la led connectee sur pin7 doit osciller a 1HZ ! MOVf MIN,W CALL OUT_BYTE CALL ACK Movf HEURE,w CALL OUT_BYTE CALL ACK Movf JourSem,w ;Jour de la semaine=07 CALL OUT_BYTE CALL ACK Movf Jour,w ;Jour du mois=02 CALL OUT_BYTE CALL ACK MOVF Mois,W ;Mois= 12 CALL OUT_BYTE CALL ACK MOVF Annee,W ;ANNEE=07 CALL OUT_BYTE CALL ACK MOVLW B'10010000' ;Registre de controle SQWE=1 RS0=RS1=0 sortie 1Hz CALL OUT_BYTE CALL NACK call STOP call delay_10mS return ;----------------------------- Lecture_DS1307 Call STOP call delay_25uS CALL START MOVLW 0xD0 ; B'11010000' MOVWF DEV_DS1307 ; @D0H adresse device CALL OUT_BYTE CALL ACK clrf ADDR ; adresse 0 MOVF ADDR, W ; send high byte of address CALL OUT_BYTE CALL ACK MOVLW 0xD1 ; B'11010001' MOVWF DEV_DS1307 ;Mode Lecture CALL START ;genere un start bit MOVF DEV_DS1307,W CALL OUT_BYTE CALL NACK ;-------- CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF SEC CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF MIN CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF HEURE CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF JourSem CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF Jour CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF Mois CALL IN_BYTE Call M_ACK MOVF I_BYTE,W MOVWF Annee ; CALL IN_BYTE ; Call M_ACK ; MOVF I_BYTE,W ; MOVWF CtrlReg ; call M_ACK CALL STOP return ORG 0x2100 ; 256 bytes of eeprom EEPROM EQU $ EE0 DT "16F876A_RS232.ASM 16 oct 09",'\f','\r' DT "PIC16F876 sans bootloader ",'\f','\r' DT "test fonction UART 19200bds",'\f','\r',0 EE1 DT "3 Mesures Ana. ",'\f','\r' DT "avec +REF=5.00=Vdd et -REF=0V=Vss",'\f','\r',0 EE2 DT "Lectures ADCs ",0 END *********************************** Resultat sur ecran terminal *********************************** 16F876A_RS232.ASM 16 oct 09 PIC16F876 sans bootloader test fonction UART 19200bds Mesure avec voie Ana 0 avec +REF=5.00=Vdd et -REF=0V=Vss Lecture ADC 10.21 1021 Lecture ADC 10.21 1021 Lecture ADC 10.21 1021 Lecture ADC 10.21 1021 Lecture ADC 9.35 0935 Lecture ADC 7.46 0746 Lecture ADC 7.08 0708 Lecture ADC 5.15 0515 Lecture ADC 4.20 0420 Lecture ADC 3.26 0326 Lecture ADC 1.28 0128 Lecture ADC 0.10 0010 Lecture ADC 0.11 0011 Lecture ADC 1.39 0139 Lecture ADC 4.58 0458 Lecture ADC 6.74 0674 Lecture ADC 9.15 0915