求解51单片机I2C对24c02读写汇编程序

求解51单片机I2C对24c02读写汇编程序,第1张

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

AT24C04测试程序 供参考

工作频率: 12.000MHz

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

SCL BIT P2.0 AT24C04的时钟线

SDA BIT P2.1 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

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

延时5微秒

不同的工作环境,需要调整此函数

入口参数:无

出口参数:无

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

Delay5us: 2 当改用1T的MCU时,请调整此延时函数

NOP 1

RET 2

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

延时5毫秒

不同的工作环境,需要调整此函数

入口参数:无

出口参数:无

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

Delay5ms: 2 当改用1T的MCU时,请调整此延时函数

PUSH ACC2

PUSH DPL2

PUSH DPH2

MOV DPTR,#-500 2

Delay5ms1:

NOP 1

NOP 1

NOP 1

NOP 1

INC DPTR2

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,#88位计数器

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,#88位计数器

RecvNext:

SETB SCL拉高时钟线

CALL Delay5us 延时

MOV C,SDA 读数据口

RLC A 保存数据

CLR SCL 拉低时钟线

CALL Delay5us 延时

DJNZ 0,RecvNext 判断8位数据是否接收完成

POP 0

RET

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

END

没有去查I2C的协议,但是读写位是LSB(低位)方向的,而读写位后发,所以可以推测应该是MSB(高位)先发的。

上面两段程序如果只从SDA的赋值情况的话(其他逻辑我没有细看),两段程序有可能都可以:

1. 先把最高位移到CY里面,再赋值,应该很好理解

2. 先由temp&0x80判断的temp的最高位,并把结果赋给SDA:这种赋值法要看编译器支持,因为SDA是一位,temp&0x80的结果是一个byte,也有写成SDA=(temp&0x80 != 0)就是把表达式的结果true or false当成1,0赋值给SDA, 实际上翻译过来就是

if(temp&0x80 != 0)

{

SDA=1

}

else

{

SDA=0

}

这些都要看编译器支持,然后才移位。怎么知道你的编译器是否支持这种写法呢?很简单,你要查看编译器生成的汇编文件,看看汇编代码是否正确。

不过强烈建议不要用这种写法,尽量让你的代码比较通用。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11070729.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存