📄 i2c.asm
字号:
;***********************************************************
;
;***********************************************************
;* 本程序为I2C主控方式模块程序
;* 占用I/O RC3,RC4
;* 使用RAM 2个字节
;* 程序包括:
; :I2C_BYTE_READ ; 读一个字节函数
; :I2C_BYTE_WRITE ; 写一个字节函数
; :I2C_ACK_CHECK ; I2C 器件接收应答位检测
; :InitI2C ; 初始化I2C工作方式
; :StartI2C ; 启动I2C总线
; :StopI2C ; 停止I2C总线
; :RstartI2C ; 重启动I2C总线
; :RecI2C ; 允许I2C总线接收
; :ACKI2C ; 发送应答位
; :NACKI2C ; 发送非应答位
; :WaitI2C ; 等待SSPIF置位
; :入口参数 I2C_Data,I2C_Addr
; :出口参数 I2C_Data
;***********************************************************
#include p16f877a.inc ;定义所用单片机的头文件
;***********************************************************
I2C_Data EQU 0X20
I2C_Addr EQU 0X21
I2C_DATA_BACK EQU 0X22
ORG 0X0
NOP
BCF STATUS,RP1;
BSF STATUS,RP0;
BCF TRISB,0;
BCF STATUS,RP0;
BCF PORTB,0;
call InitI2C
BCF STATUS,RP1;
BCF STATUS,RP0;
movlw 0x00
movwf I2C_Addr ; 设定要写入的资料的地址
movlw 0x39
movwf I2C_Data ; 设定欲写入的数据
movwf I2C_DATA_BACK;
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 !!
; 中文 : 检查 WRITE 的动作是否已完成 !!
;若 EEPROM 完成写入会开始回应 ACK
BCF STATUS,RP1;
BCF STATUS,RP0;
clrf I2C_Data
movlw 0x00
movwf I2C_Addr ; 设定欲读取的地址
call I2C_BYTE_READ
movf I2C_Data,W
SUBWF I2C_DATA_BACK,W;
BTFSS STATUS,C;
GOTO FAIL;
BCF STATUS,RP1;
BSF STATUS,RP0;
BCF TRISB,0;
BCF STATUS,RP0;
BSF PORTB,0;
GOTO $;
FAIL
BCF STATUS,RP1;
BSF STATUS,RP0;
BCF TRISB,0;
BCF STATUS,RP0;
BCF PORTB,0;
goto $
;****************************************************************************
I2C_BYTE_READ
;****************************************************************************
;*从I2C_Addr所指定的地址读一个字节数据到I2C_Data
call StartI2C ; Set SSPCON2.SEN
call WaitI2C ; Wait PIR1,SSPIF
movlw B'10100000' ; Write Command
movwf SSPBUF
call WaitI2C ; Wait PIR1,SSPIF
bcf STATUS,RP0
movf I2C_Addr,W ; The Address you wish to "READ" from
movwf SSPBUF
call WaitI2C ; Wait PIR1,SSPIF
call RstartI2C ; Restart Condition !!
call WaitI2C ; Wait Until Restart OK !!
movlw B'10100001' ; Write Read Command
movwf SSPBUF
call WaitI2C ; Wait PIR1,SSPIF
call RecI2C ; Enable I2C Receive
call WaitI2C ; Wait Until Buffer Received
movf SSPBUF,W ; Save to I2C_Data First !!
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
;****************************************************************************
;*24C01的应答位检查
call StartI2C ; Set SSPCON2.SEN
call WaitI2C ; Wait PIR1,SSPIF
movlw B'10100001' ; Read Command
movwf SSPBUF
call WaitI2C
bsf STATUS,RP0
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
;****************************************************************************
;*把I2C_Data中的数据写到I2C_Addr所指定的位置
call StartI2C ; Set SSPCON2.SEN
call WaitI2C ; Wait PIR1,SSPIF
movlw B'10100000' ; Write Command
movwf SSPBUF
call WaitI2C
movf I2C_Addr,W ; The Address you wish to "READ" from
movwf SSPBUF
call WaitI2C
movf I2C_Data,W
movwf SSPBUF
call WaitI2C
call StopI2C ; Initial STOP Condition
call WaitI2C ; Wait Until STOP Condition Terminated
return
;**********************************************************************
;*以下函数是对I2C初始化及各种状态处理的子函数
;**********************************************************************
InitI2C ;初始化I2C子函数
banksel TRISC
movlw B'00011000' ; Initial PortC,bit 3 & 4 as Input
movwf TRISC ; RC3 = SCL , RC4 = SDA
banksel PORTC
movlw 0xFF ;使I2C总线空闲时,保持高电平
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -