;********************************************************************** LIST p=16F84a ; Définition de processeur #include ; Définitions des constantes __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_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. ; Voici les valeurs et leurs définitions : ; _CP_ON Code protection ON : impossible de relire ; _CP_OFF Code protection OFF ; _PWRTE_ON Timer reset sur power on en service ; _PWRTE_OFF Timer reset hors-service ; _WDT_ON Watch-dog en service ; _WDT_OFF Watch-dog hors service ; _LP_OSC Oscillateur quartz basse vitesse ; _XT_OSC Oscillateur quartz moyenne vitesse ; _HS_OSC Oscillateur quartz grande vitesse ; _RC_OSC Oscillateur à réseau RC ;********************************************************************* ; DEFINE * ;********************************************************************* ; entrees / sorties #DEFINE SCL PORTA,0 ; SCL i2c sur RA0 #DEFINE SDA PORTA,1 ; SDA i2c sur RA1 #DEFINE LedR PORTA,4 ; Led sur RB4 N equ 0C ; i2c OCTET equ 0D ; i2c count1 equ 0E ; 1er compteur count2 equ 0F ; 2e compteur pour la tempo heures equ 10 ; heures lues dans RTC minutes equ 11 ; minutes lues dans RTC ;********************************************************************** ; DEMARRAGE SUR RESET * ;********************************************************************** org 0x000 ; Adresse de départ après reset call init ; Adresse 0: initialiser goto start ; Debut du prog principal ;********************************************************************* ; INITIALISATIONS * ;********************************************************************* init bsf STATUS,RP0 ; aller en bank1 movlw b'0000000' ; movwf TRISB ; port B en sortie movlw b'00000000' movwf TRISA ; port A en sortie bcf STATUS,RP0 ; aller en bank0 clrf PORTA clrf PORTB ; ttes les sorties a 0 init_i2c bsf SDA ; SDA a 1 bsf SCL ; SCL a 1 return ;********************************************************************* ; PROGRAMME PRINCIPAL * ;********************************************************************* start call tempo500ms call LIRE_RTC ; lit hrs et min dans la rtc movlw minutes movwf PORTB ; met les minutes sur le portB sleep ;************ SOUS PROGRAMMES I2C ***************************** LIRE_RTC ; ici c'est le prog qui lit ( heure et minutes ) la clock RTC call I2C_START ; bit de start de I2C movlw B'11010000' ; adresse RTC est 1101000 en mode ecriture call I2C_EMISSION call I2C_SLAVE_ACK ; attend ack du esclave RTC movlw B'00000001' ; on va a l'adresse ram 1 du RTC call I2C_EMISSION ; c'est l'adresse des minutes A LIRE call I2C_SLAVE_ACK ; attend ack du esclave RTC call I2C_RESTART ; bit de restart de I2C movlw B'11010001' ; adresse RTC est 1101000 en mode lecture call I2C_EMISSION call I2C_SLAVE_ACK ; attend ack du esclave RTC call I2C_RECEPTION ; on recoit les donnees call I2C_PIC_ACK ; Ack du pic movwf minutes ; on met w dans minutes call I2C_RECEPTION ; on recoit les donnees call I2C_PIC_NACK ; Nack du pic movwf heures ; on met w dans heures call I2C_STOP ; bit de stop de I2C return ; on a lu la clock rtc et mis les valeurs ; heures et minutes a jour I2C_START bsf SCL bsf SDA ; au repos SDA et SCL a 1 call tempo_5us bcf SDA ; SDA passe a 0 call tempo_5us bcf SCL ; SCL passe a 0 call tempo_5us ; >> bus I2C occupé return I2C_STOP ; ss prog bit de fin bcf SCL bcf SDA call tempo_5us bsf SCL ; SCL passe a 1 call tempo_5us bsf SDA ; SDA passe a 1 >> bus I2C au repos call tempo_5us return I2C_RESTART ; ss prog condition de restart bsf SDA ; au repos SDA et SCL a 1 call tempo_5us bsf SCL ; SDA passe a 0 call tempo_5us call tempo_5us bcf SDA ; SCL passe a 0 call tempo_5us bcf SCL ; SCL passe a 0 call tempo_5us ; >> bus I2C occupé return I2C_SLAVE_ACK ; attend acknowledge de l'esclave bcf SCL ; SCL a 0 call SDA_IN ; SDA en entree call tempo_5us ; tempo de 11 us bsf SCL ; SCL a1 call tempo_5us ; tempo de 11 us btfsc SDA call NO_ACK bcf SCL ; SCL a 0 call tempo_5us ; tempo de 11 us call SDA_OUT ; SDA en sortie return I2C_PIC_ACK ; envoye l'acknowledge du pic vers esclave bcf SCL ; SCL a 0 call SDA_OUT ; SDA en sortie bcf SDA ; SDA a 0 bsf SCL ; SCL a 1 call tempo_5us ; tempo de 11 us bcf SCL ; SCL a 0 call tempo_5us ; tempo de 11 us bsf SDA return I2C_PIC_NACK bcf SCL ; SCL a 0 call SDA_OUT ; SDA en sortie bsf SDA ; SDA a 0 bsf SCL ; SCL a 1 call tempo_5us ; tempo de 11 us bcf SCL ; SCL a 0 call tempo_5us ; tempo de 11 us bcf SDA return I2C_EMISSION ; envoye donnee du pic vers esclave movwf OCTET ; w >> OCTET movlw .8 movwf N ; 8 >> N call SDA_OUT ; mette SDA en sortie OUT_BIT rlf OCTET, F ; decalage a gauche dans carry btfsc STATUS, C ; goto OUT_ONE OUT_ZERO bcf SDA ; SDA a 0 goto OUT_CONT OUT_ONE bsf SDA ; SDA a 1 OUT_CONT call tempo_5us bsf SCL ; SCL a 1 call tempo_5us ; tempo de 5 us bcf SCL call tempo_5us decfsz N, F ; decrementer N goto OUT_BIT return I2C_RECEPTION ; recois donnees de l esclave vers le pic clrf OCTET ; efface octet movlw d'8' movwf N ; la donnees sur 8 bits call SDA_IN ; SDA en entree call tempo_5us ; tempo de 5 us IN_BYTE btfsc SDA ; test de SDA goto IN_ONE ; IN_ZERO bcf STATUS,C ; SDA a 0 met la carry a 1 ou a 0 goto IN_CONT ; suivant etat de SDA IN_ONE bsf STATUS,C ; SDA a 1 goto IN_CONT IN_CONT call tempo_5us bsf SCL ; impultion syr call tempo_5us ; SCL bcf SCL call tempo_5us rlf OCTET,1 ; decallage a gauche C >> OCTET call tempo_5us decfsz N,f ; si N = 0 goto IN_BYTE call tempo_5us ; tempo de 5 us movf OCTET,0 ; met octet recu dans w return NO_ACK ; si Nack de rtc alors stop i2c call tempo_5us bcf LedR ; Led rouge allumée call tempo500ms call tempo500ms ; attente 1 sec bsf LedR ; Led rouge eteinte goto start ; si erreur bus I2C alors goto start SDA_IN ; mettre SDA ( RA1 ) en entree bsf STATUS,RP0 ; aller en bank1 movlw b'00000010' movwf TRISA ; port A en sortie bcf STATUS,RP0 ; aller en bank0 return SDA_OUT ; mettre SDA ( RA1 ) en sortie bsf STATUS,RP0 ; aller en bank1 movlw b'00000000' movwf TRISA ; port A en sortie bcf STATUS,RP0 ; aller en bank0 return tempo_5us ; tempo de 5 us pour l' i2c nop nop return tempo500ms ; temporisation de 500 ms call wait0 call wait0 call wait0 call wait0 return wait0 ; Boucles réalisant une tempo élémentaire movlw .200 ; Charge count1 avec valeur décimale 200 movwf count1 d1 movlw .200 ; Charge count2 avec valeur décimale 200 movwf count2 d2 decfsz count2,1 ; décremente et saute ligne suiv. si zero goto d2 ; si différent de zero decfsz count1,1 ; décremente count1 si count2 == zero goto d1 ; boucle interne si count2 <> zero return END ; fin de programme