Jump to content

Pic16f877 I2c Programming


transfomer

Recommended Posts

;****************************************************

;* 877I2CA.asm *

;* Very simple I2C sample program without Display *

;****************************************************

;*******************************************************************************

***********

; This source code provides a demonstration of the MSSP peripheral

; on the PIC16F877 MCU.

; The additional external subroutine are used for LCD Module

; PIC16F877 执行频率 : 4 Mhz

;

; The subroutines for I2C

; :I2C_BYTE_READ ; Read a Byte from Address I2C_Addr and put into I2C_Data

; :I2C_BYTE_WRITE ; Write to I2C_Addr with data @ I2C_Data

; :I2C_ACK_CHECK ; Wait until I2C device can accept further command

; :InitI2C ; Initial I2C Module

; :StartI2C ; Set START Condition !!

; :StopI2C ; Set STOP Condition

; :RstartI2C ; Set Restart Condition

; :RecI2C ; Enable I2C Receive

; :ACKI2C ; Initial ACK response

; :NACKI2C ; Initial NACK response

; :WaitI2C ; Wait until SSPIF Set

;*******************************************************************************

**************

 

list p=16f877

#include <p16f877.inc>

 

CBLOCK 0x20

 

I2C_Data

I2C_Addr

 

ENDC

 

w_temp EQU 0x72

status_temp EQU 0x73

pclath_temp EQU 0x74

 

 

;********************************************

; Locates startup code @ the reset vector

;********************************************

Reset_Addr

org 0x00

nop

goto Prog_Main

nop

nop

 

;***************************************************************************

;**** The Start Address of ISR is 0x004

;**** "PUSH" & "POP" 的使用范例 : 适用于像 PIC16F877 有SHARE BANK 的 PIC

;***************************************************************************

 

PUSH

movwf w_temp ; save off current W register contents

movf STATUS,w ; move status register into W register

movwf status_temp ; save off contents of STATUS register

movf PCLATH,W

movwf pclath_temp

 

 

POP

movf pclath_temp,W

movwf PCLATH

movf status_temp,w ; retrieve copy of STATUS register

movwf STATUS ; restore pre-isr STATUS register contents

swapf w_temp,f

swapf w_temp,w ; restore pre-isr W register contents

retfie ; return from interrupt

 

 

;----------------------------------------------------------------------

 

Prog_Main

 

BANKSEL TRISB ; Select Bank 1

movlw b'11000000' ; setup PORTB

movwf TRISB

 

BSF OPTION_REG,NOT_RBPU ; Disable PORTB pull-ups

BCF STATUS, RP0 ; Select Bank 0

 

call InitI2C

 

Main:

 

BANKSEL I2C_Addr

movlw 0x18

movwf I2C_Addr ;

 

BANKSEL I2C_Data ; Bank Switching, in case its bank is differ than I2C_Addr !!

movlw 0x99

movwf I2C_Data ;

call I2C_BYTE_WRITE ; Write to I2C Device when Address & Data are set OK

 

call I2C_ACK_CHECK ; Check the ACK response, Wait until the Device Acknowledge

; Issue !! The subroutine will not return until the device send ACK !!

;

;

BANKSEL I2C_Addr

movlw 0x18

movwf I2C_Addr ;

call I2C_BYTE_READ

 

nop ;

nop ;

goto $

 

 

;****************************************************************************

I2C_BYTE_READ: ; Read a Byte @ I2C_Addr to Buffer I2C_Data

;****************************************************************************

 

call StartI2C ; Set SSPCON2.SEN

call WaitI2C ; Wait PIR1,SSPIF

 

BANKSEL SSPBUF

movlw B'10100000' ; Write Command

movwf SSPBUF

call WaitI2C

 

BANKSEL I2C_Addr ; The "BANKSEL" may not necessary if I2C_Addr is @ the same bank with SSPBUF

movf I2C_Addr,W ; The Address you wish to "READ" from

 

BANKSEL SSPBUF

movwf SSPBUF

call WaitI2C

 

call RstartI2C ; Restart Condition !!

call WaitI2C ; Wait Until Restart OK !!

 

BANKSEL SSPBUF

movlw B'10100001' ; Write Read Command

movwf SSPBUF

call WaitI2C

 

call RecI2C ; Enable I2C Receive

call WaitI2C ; Wait Until Buffer Received

BANKSEL SSPBUF

movf SSPBUF,W ; Save to I2C_Data First !!

BANKSEL I2C_Data

movwf I2C_Data

 

call NACKI2C ; Initial NACK Response !!

call WaitI2C ; Wait until NACK sent out

call StopI2C ; Initial STOP Condition

call WaitI2C ; Wait Until STOP Condition Terminated

return

 

;****************************************************************************

I2C_ACK_CHECK: ; Read a Byte @ I2C_Addr to Buffer I2C_Data

;****************************************************************************

 

call StartI2C ; Set SSPCON2.SEN

call WaitI2C ; Wait PIR1,SSPIF

 

BANKSEL SSPBUF

movlw B'10100001' ; Read Command

movwf SSPBUF

call WaitI2C

 

BANKSEL SSPCON2

btfss SSPCON2,ACKSTAT ; Check ACKSTAT bit , 0 = ACK , 1 = NACK

goto ACK_Return

call StopI2C

call WaitI2C

goto I2C_ACK_CHECK

 

ACK_Return:

call StopI2C ; Initial STOP Condition

call WaitI2C ; Wait Until STOP Condition Terminated

return

 

;****************************************************************************

I2C_BYTE_WRITE: ; Write a Byte to I2C_Addr with I2C_Data

;****************************************************************************

 

call StartI2C ; Set SSPCON2.SEN

call WaitI2C ; Wait PIR1,SSPIF

 

BANKSEL SSPBUF

movlw B'10100000' ; Write Command

movwf SSPBUF

call WaitI2C

 

BANKSEL I2C_Addr ; The "BANKSEL" may not necessary if I2C_Addr is @ the same bank with SSPBUF

movf I2C_Addr,W ; The Address you wish to "READ" from

BANKSEL SSPBUF

movwf SSPBUF

call WaitI2C

 

BANKSEL I2C_Data

movf I2C_Data,W

BANKSEL SSPBUF

movwf SSPBUF

call WaitI2C

 

call StopI2C ; Initial STOP Condition

call WaitI2C ; Wait Until STOP Condition Terminated

return

 

 

;**********************************************************************

; The following subroutines perform commonly used I2C functions.

;**********************************************************************

 

InitI2C: ; The subroutine of I2C Initialization

BANKSEL TRISC

movlw B'00011000' ; Initial PortC,bit 3 & 4 as Input

movwf TRISC ; RC3 = SCL , RC4 = SDA

 

BANKSEL PORTC

movlw 0xff

movwf PORTC

 

movlw 0x09 ; This gives 100KHz I2C clock @ 4MHz

banksel SSPADD

movwf SSPADD

movlw b'10000000' ; Disable slew rate control.

banksel SSPSTAT

movwf SSPSTAT

movlw b'00000000' ;

movwf SSPCON2 ; Setup MSSP for continuous reception.

movlw b'00101000' ; Enable MSSP and setup for I2C master

banksel SSPCON ; mode.

movwf SSPCON

return

 

 

StartI2C ; Initiate the I2C START condition.

banksel SSPCON2

bsf SSPCON2,SEN

return

 

StopI2C ; Initiate the I2C STOP condition.

banksel SSPCON2

bsf SSPCON2,PEN

return

 

RstartI2C ; Initiate the I2C restart condition.

banksel SSPCON2

bsf SSPCON2,RSEN

return

 

NACKI2C

banksel SSPCON2

bsf SSPCON2,ACKDT ; Set the ACK bit

bsf SSPCON2,ACKEN ; Initiate the NACK sequence.

return

 

ACKI2C

banksel SSPCON2

bcf SSPCON2,ACKDT ; Clear the ACK bit

bsf SSPCON2,ACKEN ; Initiate the NACK sequence.

return

 

RecI2C

banksel SSPCON2 ;

bsf SSPCON2,RCEN ; Set the receive enable bit.

return

 

 

WaitI2C ; Poll for SSPIF

banksel PIR1

FLoop btfss PIR1,SSPIF

goto FLoop

bcf PIR1,SSPIF

return

 

 

;----------------------------------------------------------------------

 

end ; *********** End Of Program !!!!!

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...