;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