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

核心提示;**************************************;AT24C04测试程序 供参考;工作频率: 12.000MHz;**************************************SCL BIT

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

;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 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

 
友情链接
鄂ICP备19019357号-22