📄 i2c24xx.asm
字号:
;=============================================================================
;软件模拟I2C总线对24XX01/02/04/08/16/32/64系列串行EEPROM进行读写程序
;说明:24XX01的页操作缓冲区是8字节,24XX02/04/08/16的页操作缓冲区是16字节
; 24XX32/64的页操作缓冲区是32字节
;=============================================================================
SCL BIT P1.0 ;24系列串行EEPROM的时序控制端
SDA BIT P1.1 ;24系列串行EEPROM的数据控制端
WP BIT P1.2 ;24系列串行EEPROM的数据写操作使能控制端
;
EEPROM_ACK_LABL BIT MAIN_LABL0.0 ;24系列串行EEPROM写应答标志位,“0”表示正确应答
RCV_RUN_LABL BIT MAIN_LABL0.1 ;24系列串行EEPROM读请求标志位,“0”表示允许读数据
I2C_24XX_TYPE_LABL BIT MAIN_LABL0.2 ;24系列串行EEPROM的器件类型标志位,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
;
I2C_24XX_SLAVE_ADDR EQU 10100000B ;24系列串行EEPROM的器件从设备当前地址
;
;=============================================================================
; 延时子程序
;=============================================================================
DELAY5US: MOV R5,#3
DJNZ R5,$
RET
;=============================================================================
;发送I2C起始位程序
;=============================================================================
START_I2C: SETB SDA ;发送起始条件的数据信号
NOP
SETB SCL ;发送起始条件的时钟信号
CALL DELAY5US
CLR SDA ;发送起始信号
CALL DELAY5US
CLR SCL ;钳住I2C总线准备发送或接收数据
RET
;=============================================================================
;发送I2C停止位程序
;=============================================================================
STOP_I2C: CLR SDA ;发送停止条件的数据信号
NOP
SETB SCL ;发送停止条件的时钟信号
CALL DELAY5US
SETB SDA ;发送I2C总线停止信号
CALL DELAY5US
RET
;
;=============================================================================
;发送一个字节数据或地址给被控器(24XX01/02/04/08/16/32/64系列串行EEPROM)程序
;入口:待发送的数据在ACC中(被控制器的地址当前已指定)
;出口:标志位EEPROM_ACK_LABL=0表示发送数据正常,EEPROM_ACK_LABL=1表示发送数据失败、被控器无应答或损坏
;=============================================================================
SENT_BYTE: MOV R7,#08H ;要传送的数据长度为8位
SENT_BYTE_01: RLC A ;要发送的数据左移,发送位入C
JC SENT_BYTE_02 ;发送位为“1”转发送数据位“1”
CLR SDA ;发送数据位“0”
JMP SENT_BYTE_03 ;转发送数据位
SENT_BYTE_02: SETB SDA ;发送数据位“1”
NOP
SENT_BYTE_03: NOP
SETB SCL ;置时钟线为高通知被控器开始接收数据位
CALL DELAY5US
CLR SCL ;钳住总线准备接收下一个数据位
DJNZ R7,SENT_BYTE_01 ;8位没发送完继续发送
CLR EEPROM_ACK_LABL ;预先清发送数据状态标志
MOV R6,#6
SENT_BYTE_04: NOP
NOP
SETB SDA ;8位发送完后释放数据线准备收应答位
NOP
NOP
SETB SCL ;开始接收应答信号
NOP
NOP
JNB SDA, SENT_BYTE_END ;判断是否接收到应答信号正常转SENT_BYTE_END
DJNZ R6,SENT_BYTE_04
SETB EEPROM_ACK_LABL ;未收到应答置位错误标志
SENT_BYTE_END: NOP
CLR SCL ;发送结束钳住总线准备下一步发送或接收数据或进行其它处理
RET
;
;=============================================================================
;从被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)读取一个字节数据程序
;入口:RCV_RUN_LABL为是否允许后续再次读取数据标志位(被控制器的地址当前已指定)
;出口:读取的数据存放在ACC中
;=============================================================================
RCV_BYTE: SETB SDA ;置数据线为输入方式
MOV R7,#08H ;要传送的数据长度为8位
RCV_BYTE_01: NOP
CLR SCL ;置时钟线为低准备接收数据位
CALL DELAY5US
SETB SCL ;置时钟线为高使数据线上数据有效
CALL DELAY5US
CLR C ;准备将接收的数据位放入ACC中
JNB SDA,RCV_BYTE_02 ;读数据位若为“0”则置C=0并转RCV_BYTE_02接收数据位
SETB C ;读数据位若为“1”则置C=1
RCV_BYTE_02: RLC A ;接收的数据位放入ACC中
NOP
NOP
DJNZ R7,RCV_BYTE_01 ;8位没收完继续接收
CLR SCL ;8位接收完置时钟线和数据线为低准备发送应答或非应答信号
NOP
NOP
NOP
CLR SDA
JNB RCV_RUN_LABL,RCV_BYTE_03 ;判断是否需要继续接收字节数据若需要则转RCV_BYTE_03发送应答位
SETB SDA ;发送非应答信号
RCV_BYTE_03: NOP ;以下程序发送应答位
NOP
SETB SCL ;置时钟线为高使应答位有效
CALL DELAY5US
CLR SCL ;清时钟线钳住I2C总线以便继续接收字接数据或发送停止条件
CLR RCV_RUN_LABL ;清接收非应答标志
NOP
NOP
CLR SDA
RET
;
;=============================================================================
;向被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)写入多个字节数据程序
;入口:DPTR为待写入的数据的首地址,R0为待写入数据的存储缓存区首地址,R2为待写入数据的字节数,
; I2C_24XX_TYPE_LABL为当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
;出口:数据写入正常,标志位EEPROM_ACK_LABL=0;否则EEPROM_ACK_LABL=1
;说明:24XX01的页操作缓冲区是8字节,24XX02/04/08/16的页操作缓冲区是16字节
; 24XX32/64的页操作缓冲区是32字节
; 一次此操作过程只能对本页内地址进行数据的写入且字节数不能超过该器件页缓冲区的字节数。
;=============================================================================
WR_24XX_DATA: CLR WP ;写数据使能允许
CALL START_I2C ;发送I2C 总线起始条件
JB I2C_24XX_TYPE_LABL,WR_24XX_DATA_01;判断当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
MOV A,DPH ;待写入数据的高位地址
ANL A,#0FH ;屏蔽高位地址中的无效数据
CLR C ;确定写操作命令标志
RLC A
ORL A,#I2C_24XX_SLAVE_ADDR ;被控器总线地址,带写入数据的高位地址及写命令
CALL SENT_BYTE ;发送被控器总线地址及数据高位地址及命令
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
SJMP WR_24XX_DATA_02
WR_24XX_DATA_01:MOV A,#I2C_24XX_SLAVE_ADDR ;被控器总线地址
CLR C ;确定写操作命令标志
MOV ACC.0,C ;确定被控器总线地址及写命令
CALL SENT_BYTE ;发送被控器总线地址及命令
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
MOV A,DPH ;待写入数据的高位地址
CALL SENT_BYTE ;发送待写入数据的高位地址
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
WR_24XX_DATA_02:MOV A,DPL ;待写入的数据首字节地址低位字节
CALL SENT_BYTE ;发送待写入数据的低位地址
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
WR_24XX_DATA_03:MOV A,@R0
CALL SENT_BYTE ;发送待写入的数据字节
JB EEPROM_ACK_LABL,WR_24XX_DATA_END
INC R0
DJNZ R2,WR_24XX_DATA_03
CALL STOP_I2C ;发送I2C 总线停止条件
MOV R7,#28H ;延时10ms,等待数据写完
MOV R6,#00H
WR_24XX_DATA_04:DJNZ R6,WR_24XX_DATA_04
DJNZ R7,WR_24XX_DATA_04
WR_24XX_DATA_END:
SETB WP ;写数据使能禁止
RET
;
;=============================================================================
;从被控制器(24XX01/02/04/08/16/32/64系列串行EEPROM)中读取多个字节数据程序
;入口:DPTR为预读取的数据的首地址,R2为需要读取数据的字节数
; I2C_24XX_TYPE_LABL为当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
;出口:R0为读取的数据存储缓存区
;说明:24XX01的页操作缓冲区是8字节,24XX02/04/08/16的页操作缓冲区是16字节
; 24XX32/64的页操作缓冲区是32字节
; 一次此操作过程只能对本页内地址进行数据的读取且字节数不能超过该器件页缓冲区的字节数。
;=============================================================================
RD_24XX_DATA: CALL START_I2C ;发送I2C 总线起始条件
JB I2C_24XX_TYPE_LABL,RD_24XX_DATA_01;判断当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
MOV A,DPH ;待写入数据的高位地址
ANL A,#0FH ;屏蔽高位地址中的无效数据
CLR C ;确定写操作命令标志
RLC A
ORL A,#I2C_24XX_SLAVE_ADDR ;被控器总线地址,带写入数据的高位地址及写命令
CALL SENT_BYTE ;发送被控器总线地址及数据高位地址及命令
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
SJMP RD_24XX_DATA_02
RD_24XX_DATA_01:MOV A,#I2C_24XX_SLAVE_ADDR ;被控器总线地址
CLR C ;确定写操作命令标志
MOV ACC.0,C ;确定被控器总线地址及写命令
CALL SENT_BYTE ;发送被控器总线地址及命令
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
MOV A,DPH ;待写入数据的高位地址
CALL SENT_BYTE ;发送待写入数据的高位地址
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
RD_24XX_DATA_02:MOV A,DPL ;待写入的数据首字节地址低位字节
CALL SENT_BYTE ;发送地址低位字节
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
CALL START_I2C ;重复发送I2C 总线起始条件
JB I2C_24XX_TYPE_LABL,RD_24XX_DATA_03;判断当前24系列串行EEPROM的器件类型,“0”表示为24XX01/02/04/08/16,“1”表示为24XX32/64
MOV A,DPH ;待读取数据的高位地址
ANL A,#0FH ;屏蔽高位地址中的无效数据
SETB C ;确定读操作命令标志
RLC A
ORL A,#I2C_24XX_SLAVE_ADDR ;被控器总线地址,带写入数据的高位地址及写命令
SJMP RD_24XX_DATA_04
RD_24XX_DATA_03:MOV A,#I2C_24XX_SLAVE_ADDR ;被控器总线地址
SETB C ;确定读操作命令标志
MOV ACC.0,C ;确定被控器总线地址及写命令
RD_24XX_DATA_04:CALL SENT_BYTE ;发送被控器总线地址及命令
JB EEPROM_ACK_LABL,RD_24XX_DATA_END
CLR RCV_RUN_LABL ;预设置允许后续继续接收数据
RD_24XX_DATA_05:DJNZ R2,RD_24XX_DATA_06
SETB RCV_RUN_LABL ;设置禁止后续继续接收数据
CALL RCV_BYTE ;接收数据
MOV @R0,A
INC R0
CALL STOP_I2C ;发送I2C 总线停止条件
SJMP RD_24XX_DATA_END
RD_24XX_DATA_06:CALL RCV_BYTE ;接收数据
MOV @R0,A
INC R0
SJMP RD_24XX_DATA_05
RD_24XX_DATA_END:
RET
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -