INIT_MSSP
bank1
bsf TRISC,3 ; SCL en entrée (mis par défaut sur un reset)
bsf TRISC,4 ; SDA en entrée (idem)
movlw B'00000000' ; slew rate control en service, mode I²C
movwf SSPSTAT ; dans SSPSTAT
movlw 0x02 ; valeur de recharge du BRG ( Fréquence interne = 4MHz, SSPADD = FOSC/(FSCL*4)-1 )
movwf SSPADD ; dans registre de recharge
bank0 ; passer banque 0
movlw B'00101000' ; module MSSP en service en mode I²C master
movwf SSPCON ; dans registre de contrôle
return
I2C_start
bank1 ; passer en banque 1
bsf SSPCON2,SEN ; lancer le start-condition
I2C_start2
btfsc SSPCON2,SEN ; start-condition terminé ?
goto I2C_start2 ; non, attendre
bank0 ; oui, repasser en banque 0
return
I2C_adress_write
movlw SLAVE*2 ; charger adresse esclave (b7 à b1) avec b0 = 0
movwf SSPBUF ; lancer l’émission de l’adresse en mode écriture
bank1 ; passer en banque 1
I2C_adress_write2
btfsc SSPSTAT,R_W ; tester si émission terminée
goto I2C_adress_write2 ; non, attendre
bank0 ; oui, repasser banque 0
return
I2C_adress_read
movlw SLAVE*2+1 ; charger adresse esclave (b7 à b1) avec b0 = 1
movwf SSPBUF ; lancer l’émission de l’adresse en mode lecture
bank1 ; passer en banque 1
I2C_adress_read2
btfsc SSPSTAT,R_W ; tester si émission terminée
goto I2C_adress_read2 ; non, attendre
bank0 ; oui, repasser banque 0
return
I2C_check
bank1 ; passer en banque 1
I2C_check2
btfsc SSPCON2,ACKSTAT ; tester ACK reçu
goto I2C_check2 ; pas reçu, traiter erreur
bank0 ; repasser en banque 0
return
I2C_send
movlw OCTET ; charger octet à envoyer
movwf SSPBUF ; lancer l’écriture
bank1 ; passer en banque 1
I2C_send2
btfsc SSPSTAT,R_W ; tester si émission terminée
goto I2C_send2 ; non, attendre
bank0 ; oui, repasser banque 0
return
I2C_read
bank1 ; passer banque 1
bsf SSPCON2,RCEN ; lancer la réception
I2C_read2
btfsc SSPCON2,RCEN ; réception terminée ?
goto I2C_read2 ; non, attendre
bank0 ; repasser banque 0
return
I2C_noack
bank1 ; passer banque 1
bsf SSPCON2,ACKDT ; le bit qui sera envoyé vaudra « 1 »
bsf SSPCON2,ACKEN ; lancer l’acknowledge (= ACKDT = 1 = NOACK)
I2C_noack2
btfsc SSPCON2,ACKEN ; tester si NOACK terminé
goto I2C_noack2 ; non, attendre
bank0 ; repasser banque 0
return
I2C_ack
bank1 ; passer banque 1
bcf SSPCON2,ACKDT ; le bit qui sera envoyé vaudra « 0 »
bsf SSPCON2,ACKEN ; lancer l’acknowledge (= ACKDT = 0 = ACK)
I2C_ack2
btfsc SSPCON2,ACKEN ; tester si ACK terminé
goto I2C_ack2 ; non, attendre
bank0 ; repasser banque 0
return
I2C_stop
bank1 ; passer en banque 1
bsf SSPCON2,PEN ; lancer le stop-condition
I2C_stop2
btfsc SSPCON2,PEN ; stop-condition terminé ?
goto I2C_stop2 ; non, attendre
bank0 ; oui, repasser en banque 0
return
[...]
H_MINU_READ
movlw H_ADDR
movwf SLAVE
movlw H_MINU_REGISTER
movwf OCTET
call I2C_start
call I2C_adress_write
call I2C_check
call I2C_send ; on envoie l'adresse du registre des minutes
call I2C_check
call I2C_start ; restart
call I2C_adress_read
call I2C_check
call I2C_read ; On lit les minutes
movf SSPBUF, 0;
movwf Minutes
call I2C_noack
call I2C_stop
return