;Programme de test pour la liaison I²C
;************************************************************
LIST P=18F452
#include <P18F452.INC>
listn=0; suppress list file page breaks
listST=off; suppress list file symbol table
;************************************************************
; Register File Assignment
EEADDRequ0x000; Address register
EEDATAequ0x001; data to read/write
EESLAVEequ0x002; Device address (1010xxxy)
DelayCtr1equ0x003; delay routine counter
DelayCtr2equ0x004; delay routine counter
SlaveAddrequ0xA0; slave address literal
;************************************************************
; Vector Assignment
ORG0x00000
gotoStart; Reset Vector
;************************************************************
; Main ProgramprgrPrincipal
ORG0x00040; Start of Program space
Start
; initialize PORTB
clrfLATB; Clear PORTB output latch
clrfTRISB; Set PORTB as all outputs
; configure SSP for hardware master mode I2C
bsfSSPSTAT,SMP; I2C slew rate control disabled
bsfSSPCON1,SSPM3; I2C master mode in hardware
bsfSSPCON1,SSPEN; enable SSP module
movlw0x09; set I2C clock rate to 100kHz
movwfSSPADD
bsfTRISC,3; I2C SCL pin is input
bsfPORTC,3; (will be controlled by SSP)
bsfTRISC,4; I2C SDA pin is input
bsfPORTC,4; (will be controlled by SSP)
movlwSlaveAddr; EEPROM I2C address
movwfEESLAVE
Mainprgr
clrfPORTB; initialize variables
clrfEEDATA
clrfEEADDR
WrEEPROMprgrd’écriture
bsfPORTB,7; indicate write, light TX LED
rcallDelay
bcfEESLAVE,0; write mode
rcallWakeSlave; gets slave attention
rcallWrADDR; sends EEPROM address
rcallWrDATA; sends data to slave
rcallStop; send stop bit
incfPORTB,F; increment count
incfEEDATA,F; increment data
incfEEADDR,F; Point to next address
btfssEEADDR,7; at end of EEPROM?
gotoWrEEPROM; no, write more data
RdLoop
clrfPORTB; initialize variables
clrfEEDATA
clrfEEADDR
RdEEPROMprgrde lecture
rcallDelay
bcfEESLAVE,0; write mode
rcallWakeSlave; gets slave attention
rcallWrADDR; sends EEPROM address
rcallStop; send stop bit
bsfEESLAVE,0; read mode
rcallWakeSlave; gets slave attention
rcallRdDATA; receive one data byte, leaves idle
movfEEDATA,W; get data
movwfPORTB; move received data to PORTB
xorwfEEADDR,W; compare data with address
bzGoodData; branch if DATA = ADDR
rcallErrorloop; DATA is wrong, indicate error
GoodDataprgrde vérification
incfEEADDR,F; Point to next address
btfssEEADDR,7; at end of EEPROM?
gotoRdEEPROM; no, read more data
gotoMain; do it all over again
;************************************************************
; TX LED flashes to indicate error while displaying received data.
;Errorloopprgrd’affichage donnée trasmise mauvaise
;rcallDelay
;btgPORTB,7; Toggle TX LED
;rcallDelay
;btgPORTB,7; Toggle TX LED
;rcallDelay
;btgPORTB,7; Toggle TX LED
;rcallDelay
;btgPORTB,7; Toggle TX LED
;rcallDelay
;btgPORTB,7; Toggle TX LED
;rcallDelay
;btgPORTB,7; Toggle sTX LED
;return
;************************************************************
; sends start bit, slave address
; if ACK not recieved, sends restart, tries again
; execution can get stuck in this loop if slave not present
; can be used to poll slave status (retries until slave responds)
WakeSlavess- prgrEvoi du bit de start
bsfSSPCON2,SEN; Send start bit
btfscSSPCON2,SEN; Has SEN cleared yet?
goto$-2; No, loop back to test.
rWakeSlave
bcfPIR1,SSPIF; clear interrupt flag
nop
movfEESLAVE,W
movwfSSPBUF; move slave address to SSPBUF
btfssPIR1,SSPIF; has SSP completed sending SLAVE Address?
goto$-2; no, loop back to test
btfssSSPCON2,ACKSTAT; was ACK received from slave?
return; yes, return to calling routine
bsfSSPCON2,RSEN; send repeated start bit
btfscSSPCON2,RSEN; has repeated start been sent yet?
goto$-2; no, loop back to test
brarWakeSlave; send slave address again
;************************************************************
; writes EEPROM memory address, hangs if no ACK
WrADDRss- prgrEcriture de l’adresse
bcfPIR1,SSPIF; clear interrupt flag
movffEEADDR,SSPBUF; move EEPROM address to SSPBUF
btfssPIR1,SSPIF; has SSP completed sending EEPROM Address?
goto$-2; no, loop back to test
btfscSSPCON2,ACKSTAT; has slave sent ACK?
goto$-2; no, try again
return
;************************************************************
; Sends one byte of data to slave, hangs if no ACK
WrDATAss- prgrEcriture de la donnée
bcfPIR1,SSPIF; clear interrupt flag
movffEEDATA,SSPBUF; move data to SSPBUF
btfssPIR1,SSPIF; has SSP completed sending data to EEPROM?
goto$-2; no, loop back to test
btfscSSPCON2,ACKSTAT; has slave sent ACK?
goto$-2; no, try again
return
;************************************************************
; receive one byte from slave
; do not send ACK, send stop bit instead
RdDATAss- prgrEcriture de la donnée
bcfPIR1,SSPIF; clear interrupt flag
bsfSSPCON2,RCEN; enable receive mode
btfssPIR1,SSPIF; has SSP received a data byte?
goto$-2; no, loop back to test
bsfSSPCON2,ACKDT; no ACK
bsfSSPCON2,ACKEN; send ACKDT bit
btfscSSPCON2,ACKEN; has ACKDT bit been sent yet?
goto$-2; no, loop back to test
bsfSSPCON2,PEN; send stop bit
btfscSSPCON2,PEN; has stop bit been sent?
goto$-2; no, loop back to test
movffSSPBUF,EEDATA; save data to RAM
bcfSSPCON2,RCEN; disable receive mode
return
;************************************************************
; Sends stop bit, waits until sent
Stopss- prgrEvoi du bit de stop
bsfSSPCON2,PEN; send stop bit
btfscSSPCON2,PEN; has stop bit been sent?
goto$-2; no, loop back to test
return
;************************************************************
; a delay of 98.57mS
Delayss- prgrTempo
movlw0x80
movwfDelayCtr2; preset
clrfDelayCtr1; clear counter
Delay1
decfszDelayCtr1; decrement counter
braDelay1; back to top of loop
decfszDelayCtr2; decrement counter
braDelay1; back to top of loop
return
END