PDA

View Full Version : HARDWARE I2C SAMPLE CODE question



Michael Wakileh
- 16th June 2009, 16:58
Hi! I just found some nice code from microchip showing a simple write/read sequence to an I2C EEPROM using MSSP in mastermode. The code is well documented so I feel I will be able to use parts of it to replace PBP statements
even though I don't speak assembly language... Unfortunately I'm not at a computer where I can test, and I have a simple question...

In the code there are certain define statements-and it looks
like they are in some other compiler language....or are these in assembly?







; 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

Melanie
- 16th June 2009, 19:36
What you see is Microchip Assembler.

Michael Wakileh
- 16th June 2009, 22:07
thanks Mel!