optech
Member level 1
i2c connection
I am trying to make a i2c connection between 24C04 eeprom and pic16f877. I wrote the codes that need for. But I guess, it has some problem. But i can't find it.
When I simulated this code with proteus, I saw this : S 41 A 25 A Sr
S --> Start , 41 --> controlin adress , A --> ACK , 25 --> eeprom adress that will be read , Sr --> Restart .
The read procedure is :
" S --> ControlIN Adress(A0) --> ACK --> EEprom ADDR --> ACK --> Restart --> ControlOUT (A1) --> ACK --> DATA --> NACK --> P (Stop) "
Why I can't obtain this results (above)? Why the flow stops after Sr?
And final question: When I send A0 (ControlIN), I see 41. When I send hex 12 for Adress, I see 25 like I said above (Proteus simulation) Why?
Thanks in advance....
I am trying to make a i2c connection between 24C04 eeprom and pic16f877. I wrote the codes that need for. But I guess, it has some problem. But i can't find it.
Code:
#define LC01CTRLIN H'A0' ; I2C value for CONTROL BYTE when
; INputing data to the EEPROM
#define LC01CTRLOUT H'A1' ; I2C value for CONTROL BYTE when
; requesting OUTput from the EEPROM
#define LC01ADDR H'12' ; Sample value for ADDRESS BYTE
#define LC01DATA H'34' ; Sample data to write to EEPROM
#define BAUD D'100' ; Desired Baud Rate in kbps
#define FOSC D'4000' ; Oscillator Clock in kHz
LIST P=16F877
#include <p16F877.inc>
__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
ORG 00 ; Start of code (location 0)
GOTO BASLA
ORG 04
BCF STATUS,GIE
RETFIE
BCF STATUS, GIE
; *** Setup I/O ***
BANKSEL TRISB
MOVLW 0x06
MOVWF 0X9F ;ADCON1
movlw b'00000101'
movwf 0X85 ;TRISA
movlw b'10011000'
movwf 0X87 ;TRISC
; *** Setup Registers for I2C ***
; Configure MSSP module for Master Mode
BANKSEL SSPCON
movlw B'00101000' ; Enables MSSP and uses appropriate
; PORTC pins for I2C mode (SSPEN set) AND
; Enables I2C Master Mode (SSPMx bits)
movwf SSPCON ; This is loaded into SSPCON
; Configure Input Levels and slew rate as I2C Standard Levels
BANKSEL SSPSTAT
movlw B'10000000' ; Slew Rate control (SMP) set for 100kHz
movwf SSPSTAT ; mode and input levels are I2C spec,
; loaded in SSPSTAT
; Configure Baud Rate
; BANKSEL SSPADD
movlw (FOSC / (4 * BAUD)) - 1 ; Calculates SSPADD Setting for
movwf SSPADD ; desired Baud rate and sets up SSPADD
I2CRead
; Send RESTART condition and wait for it to complete
BANKSEL SSPCON2
bsf SSPCON2,SEN ; Generate START Condition
call WaitMSSP ; Wait for I2C operation to complete
; Send and Check CONTROL BYTE, wait for it to complete
; movlw LC01CTRLIN ; Load CONTROL BYTE (input)
movlw 0XA0 ; Load CONTROL BYTE (input)
call Send_I2C_Byte ; Send Byte
call WaitMSSP ; Wait for I2C operation to complete
; Now check to see if I2C EEPROM is ready
BANKSEL SSPCON2
btfsc SSPCON2,ACKSTAT ; Check ACK Status bit to see if I2C
goto I2CRead_AGAIN
; Send and Check ADDRESS BYTE, wait for it to complete
movlw LC01ADDR ; Load ADDRESS BYTE
call Send_I2C_Byte ; Send Byte
call WaitMSSP ; Wait for I2C operation to complete
BANKSEL SSPCON2
btfsc SSPCON2,ACKSTAT ; Check ACK Status bit to see if I2C
goto I2CFail ; failed, skipped if successful
; Send REPEATED START condition and wait for it to complete
bsf SSPCON2,RSEN ; Generate REPEATED START Condition
call WaitMSSP ; Wait for I2C operation to complete
; Send and Check CONTROL BYTE (out), wait for it to complete
movlw LC01CTRLOUT ; Load CONTROL BYTE (output)
call Send_I2C_Byte ; Send Byte
call WaitMSSP ; Wait for I2C operation to complete
BANKSEL SSPCON2
btfsc SSPCON2,ACKSTAT ; Check ACK Status bit to see if I2C
goto I2CFail ; failed, skipped if successful
; Switch MSSP module to I2C Receive mode
bsf SSPCON2,RCEN ; Enable Receive Mode (I2C)
; Get the DATA BYTE and wait for it to complete. Data is in SSPBUF when done.
; The receive mode is disabled at end automatically by the MSSP module.
call WaitMSSP ; Wait for I2C operation to complete
; Send NACK bit for Acknowledge Sequence
BANKSEL SSPCON2
bsf SSPCON2,ACKDT ; ACK DATA to send is 1, which is NACK.
bsf SSPCON2,ACKEN ; Send ACK DATA now.
; Once ACK or NACK is sent, the ACKEN is automatically cleared by the MSSP
; Send and Check the STOP condition and wait for it to complete.
bsf SSPCON2,PEN ; Send STOP condition
call WaitMSSP ; Wait for I2C operation to complete
; I2C Write and Read have both finished, the value is output on LEDs.
BANKSEL SSPBUF ; BANK 0
movf SSPBUF,W ; Get data from SSPBUF into W register
movwf REG
................................................
................................................
goto $ ; Wait forever at this location
I2CRead_AGAIN
bsf SSPCON2,PEN ; Send STOP condition
call WaitMSSP ; Wait for I2C operation to complete
GOTO I2CRead
I2CFail
BANKSEL SSPCON2
bsf SSPCON2,PEN ; Send STOP condition
call WaitMSSP ; Wait for I2C operation to complete
BANKSEL PORTB ; BANK 0
.........................................
.........................................
goto $ ; Wait forever at this location
; This routine sends the W register to SSPBUF, thus transmitting a byte.
; Then, the SSPIF flag is checked to ensure the byte has been sent successfully.
; When that has completed, the routine exits, and executes normal code.
Send_I2C_Byte
BANKSEL SSPBUF ; BANK 0
movwf SSPBUF ; Get value to send from W, put in SSPBUF
retlw 0 ; Done, Return 0
; This routine waits for the last I2C operation to complete.
; It does this by polling the SSPIF flag in PIR1.
WaitMSSP
BANKSEL PIR1 ; BANK 0
btfss PIR1,SSPIF ; Check if done with I2C operation
goto $-1 ; I2C module is not ready yet
bcf PIR1,SSPIF ; I2C module is ready, clear flag.
Retlw 0 ; Done, Return 0
END
When I simulated this code with proteus, I saw this : S 41 A 25 A Sr
S --> Start , 41 --> controlin adress , A --> ACK , 25 --> eeprom adress that will be read , Sr --> Restart .
The read procedure is :
" S --> ControlIN Adress(A0) --> ACK --> EEprom ADDR --> ACK --> Restart --> ControlOUT (A1) --> ACK --> DATA --> NACK --> P (Stop) "
Why I can't obtain this results (above)? Why the flow stops after Sr?
And final question: When I send A0 (ControlIN), I see 41. When I send hex 12 for Adress, I see 25 like I said above (Proteus simulation) Why?
Thanks in advance....