Code:
; I2C connected to 24C01C (or similar) EEPROM.
; Write to location 0x12, data 0x34 and read it back.
; The MSSP module is used in I2C MASTER mode.
#define LC01CTRLIN H'A0’ ; I2C value for CONTROL BYTE when!!!!!!!!!!!!!!!!!!!!!!!!!CONTROLBYTE for write
; INputing data to the EEPROM
#define LC01CTRLOUT H'A1’ ; I2C value for CONTROL BYTE when!!!!!!!!!!!!!!!!!!!!!!!!CONTROIBYTE for read
; requesting OUTput from the EEPROM
#define LC01ADDR H'12’ ; Sample value for ADDRESS BYTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Address byte
#define LC01DATA H’34’ ; Sample data to write to EEPROM!!!!!!!!!!!!!!!!!!!!!!!!!!!!Data to write to Address
#define BAUD D'100’ ; Desired Baud Rate in kbps
#define FOSC D'4000’ ; Oscillator Clock in kHz
#include <p16F877.inc> ; Processor Include file, for standard names
__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF &
_BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
ORG 0 ; Start of code (location 0)
; *** Setup I/O ***
clrf PORTB ; PORTB pins set to drive low when enabled
BANKSEL TRISC ; BANK 1
movlw B'00011000’ ; RC3, RC4 are inputs for PORTC
movwf TRISC ; Remaining PORTC I/O lines are outputs
clrf TRISB ; all PORTB pins configured for output mode
; (enables all PORTB drivers for driving LEDs)
; *** 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
; *** Begin I2C Data Transfer Sequences ***
I2CWrite
; Send START condition and wait for it to complete
BANKSEL SSPCON2 ; BANK 1
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 mode)
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 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 and Check DATA BYTE, wait for it to complete
movlw LC01DATA ; Load Data 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 and Check the STOP condition, wait for it to complete
BANKSEL SSPCON2
bsf SSPCON2,PEN ; Send STOP condition
call WaitMSSP ; Wait for I2C operation to complete
; The WRITE has now completed successfully. Begin the Read Sequence
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I2C READ
; Send RESTART condition and wait for it to complete
BANKSEL SSPCON2
bsf SSPCON2,RSEN ; Generate RESTART 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)
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 ; ACK Poll waiting for EEPROM write to complete
; 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 succe
ssful
; 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 PORTB ; Output W register to LEDs on PORTB
; Program has finished and completed successfully.
goto $ ; Wait forever at this location!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!CHANGE THIS
; *** SUBROUTINES & ERROR HANDLERS ***
; I2C Operation Failed code sequence - This will normally not happen,
; but if it does, a STOP is sent and the entire code is tried again.
I2CFail
BANKSEL SSPCON2
bsf SSPCON2,PEN ; Send STOP condition
call WaitMSSP ; Wait for I2C operation to complete
BANKSEL PORTB ; BANK 0
movlw 0xFF ; Turn on all LEDs on PORTB
movwf PORTB ; to show error condition
goto $ ; Wait forever at this location!!!!!!!!!!!!!!!!!!!!!!!!!!!!!CHANGE THIS
; 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.
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!BUT HOW TO DO THIS CODE IN THE BACKGROUND???
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
Bookmarks