;**************************************
SCL BIT P3.4 ;AT24C04的时钟线
SDA BIT P3.5 ;AT24C04的数据线
BUF EQU 30H ;数据缓存区
;**************************************
ORG 0
JMP Reset
ORG 100H
Reset:
CALL AT24C04_WritePage ;写一页数据
CALL Delay5ms ;写一页数据需延时5ms
CALL AT24C04_ReadPage ;读一页数据
JMP $
;**************************************
;向AT24C04写1页(16字节)数据
;将TESTDATA开始的16个测试数据写如设备的00~0F地址中
;入口参数:无
;出口参数:无
;**************************************
AT24C04_WritePage:
CALL AT24C04_Start ;起始信号
MOV A,#0A0H ;发送设备地址+写信号
CALL AT24C04_SendByte ;发送
MOV A,#00H ;发送存储单元地址
CALL AT24C04_SendByte ;发送
MOV R0,#16 ;16字节计数器
MOV DPTR,#TESTDATA ;测试数据首地址
WriteNext:
CLR A ;读取测试数据
MOVC A,@A+DPTR
CALL AT24C04_SendByte ;写入设备
INC DPTR ;准备下一个数据的地址
DJNZ R0,WriteNext ;判断16字节是否完成
CALL AT24C04_Stop ;停止信号
RET
TESTDATA:
DB 000H,011H,022H,033H,044H,055H,066H,077H
DB 088H,099H,0AAH,0BBH,0CCH,0DDH,0EEH,0FFH
;**************************************
;从AT24C04读取1页(16字节)数据
;将设备的00~0F地址中的数据读出存放在DATA区的BUF中
;入口参数:无
;出口参数:无
;**************************************
AT24C04_ReadPage:
CALL AT24C04_Start ;起始信号
MOV A,#0A0H ;发送设备地址+写信号
CALL AT24C04_SendByte ;发送
MOV A,#00H ;发送存储单元地址
CALL AT24C04_SendByte ;发送
CALL AT24C04_Start ;起始信号
MOV A,#0A1H ;发送设备地址+读信号
CALL AT24C04_SendByte ;发送
MOV R0,#16 ;16字节计数器
MOV R1,#BUF ;数据缓冲区首地址
ReadNext:
CALL AT24C04_RecvByte ;读取数据
MOV @R1,A ;保存数据
CJNE R0,#2,$+3 ;判断回应ACK还是NAK
CALL AT24C04_SendACK ;发送应答信号
INC R1 ;缓冲区地址加1
DJNZ R0,ReadNext ;判断16字节是否完成
CALL AT24C04_Stop ;停止信号
RET
;**************************************
;入口参数:无
;出口参数:无
;**************************************
Delay5us: ;2
NOP ;1
RET ;2
;**************************************
;入口参数:无
;出口参数:无
;**************************************
Delay5ms: ;2
PUSH ACC ;2
PUSH DPL ;2
PUSH DPH ;2
MOV DPTR,#-500 ;2
Delay5ms1:
NOP ;1
NOP ;1
NOP ;1
NOP ;1
INC DPTR ;2
MOV A,DPL ;1
ORL A,DPH ;1
JNZ Delay5ms1 ;2
POP DPH ;2
POP DPL ;2
POP ACC ;2
RET ;2
;**************************************
;起始信号
;入口参数:无
;出口参数:无
;**************************************
AT24C04_Start:
SETB SDA
SETB SCL ;拉高时钟线
CALL Delay5us ;延时
CLR SDA ;产生下降沿
CALL Delay5us ;延时
CLR SCL ;拉低时钟线
RET
;**************************************
;停止信号
;入口参数:无
;出口参数:无
;**************************************
AT24C04_Stop:
CLR SDA
SETB SCL ;拉高时钟线
CALL Delay5us ;延时
SETB SDA ;产生上升沿
CALL Delay5us ;延时
RET
;**************************************
;发送应答信号
;入口参数:C (0:ACK 1:NAK)
;出口参数:无
;**************************************
AT24C04_SendACK:
MOV SDA,C ;写应答信号
SETB SCL ;拉高时钟线
CALL Delay5us ;延时
CLR SCL ;拉低时钟线
CALL Delay5us ;延时
RET
;**************************************
;接收应答信号
;入口参数:无
;出口参数:C
;**************************************
AT24C04_RecvACK:
SETB SCL ;拉高时钟线
CALL Delay5us ;延时
MOV C,SDA ;读应答信号
CLR SCL ;拉低时钟线
CALL Delay5us ;延时
RET
;**************************************
;向IIC总线发送一个字节数据
;入口参数:ACC
;出口参数:无
;**************************************
AT24C04_SendByte:
PUSH 0
MOV 0,#8 ;8位计数器
SendNext:
RLC A ;移出数据的最高位
MOV SDA,C ;送数据口
SETB SCL ;拉高时钟线
CALL Delay5us ;延时
CLR SCL ;拉低时钟线
CALL Delay5us ;延时
DJNZ 0,SendNext ;判断8位数据是否发送完成
POP 0
JMP AT24C04_RecvACK ;接收应答信号
; RET
;**************************************
;从IIC总线接收一个字节数据
;入口参数:无
;出口参数:ACC
;**************************************
AT24C04_RecvByte:
SETB SDA ;使能内部上拉,准备读取数据
PUSH 0
MOV 0,#8 ;8位计数器
RecvNext:
SETB SCL ;拉高时钟线
CALL Delay5us ;延时
MOV C,SDA ;读数据口
RLC A ;保存数据
CLR SCL ;拉低时钟线
CALL Delay5us ;延时
DJNZ 0,RecvNext ;判断8位数据是否接收完成
POP 0
RET
END