📄 i2c3.c
字号:
SDA BIT P2.1
SCL BIT P2.0
ORG 0000H
AJMP INIT
ORG 0100H
INIT: CLR RS0
CLR RS1
MOV R1,#30H
MOV A,#50H
MOV R7,#08H
MOV R3,#0A0H
MOV R4,#00H
LOOP: MOV @R1,A
INC R1
INC A
DJNZ R7,LOOP ;初始化存储器的值,将数据50H~57H发送到内部30H~37H单元
E2PW:MOV P2,#0FFH ; 置p2.0, p2.1 均为1
CLR P2.1 ; 发开始信号
MOV A,R3; 送器件地址
ACALL SUBS
MOV A,R4; 送片内字节地址
ACALL SUBS 调发送单字节子程序
MOV R1,#30H
MOV R7,#08H ; AT24C02一次可装载的字节数为8个
AGAIN:MOV A,@R1
ACALL SUBS
INC R1
DJNZ R7,AGAIN; 发送8个字节到IIC模块
CLR P2.1 ; 发送完8个数据后,先将SDA拉低,准备发停止位
ACALL DELAY
SETB P2.0 ; 将SCL拉高
ACALL DELAY
SETB P2.1 ; 在由主设备将SDA拉高,送出停止位
MOV R7,#08H ; 再一次给R7赋值,准备读数据
E2PR: MOV R1,#40H
MOV P2,#0FFH ; 置p2.0, p2.1 均为1
CLR P2.1; 发开始信号
MOV A,R3; 发器件地址
ACALL SUBS; 调发送单字节子程序
MOV A,R4; 送片内字节地址
ACALL SUBS
MOV P2,#0FFH; 置p2.0, p2.1 均为1
CLR P2.1; 再发开始信号
MOV A,R3
SETB ACC.0; 发读命令
ACALL SUBS
MORE: ACALL SUBR ; 进入读数据模式
MOV @R1,A
INC R1
DJNZ R7,MORE; 读8个字节到内部40H~47H
CLR P2.1
ACALL DELAY
SETB P2.0
ACALL DELAY
SETB P2.1; 送停止信号
ajmp $
SUBS: MOV R0,#08H;发送单字节子程序
LOOP1: CLR P2.0 ; 只有在SCL为低电平时才能改变SDA的值
RLC A
MOV P2.1 ,C
NOP
SETB P2.0 ; SCL置1,保持数据
ACALL DELAY; 需要保持一段时间
DJNZ R0,LOOP1;循环8次送8个位
CLR P2.0
ACALL DELAY
SETB P2.0 ; 进入第9个时钟脉冲
REP: JB P2.1,$; 判断答到否,未到则等待。这里SDA由接受端拉低
CLR P2.0
RET
DELAY: MOV R5,#20H;为满足传输速率要求延时子程序
DELAY2: MOV R6,#10H
DELAY3: DJNZ R6,DELAY3
DJNZ R5,DELAY2
RET
SUBR: MOV R0,#08H; 接收单字节子程序
LOOP2:SETB P2.0 ; 直接将SCL置1,准备接收
ACALL DELAY
MOV C, P2.1
RLC A ; 将收到的位循环到0位上
CLR P2.0
ACALL DELAY
DJNZ R0,LOOP2
CJNE R7 ,#01H, LOWA
SETB P2.1; 若是最后一个字节,置SDA=1
AJMP SETOK
LOWA: CLR P2.1; 否则置SDA=0
SETOK: ACALL DELAY
SETB P2.0
ACALL DELAY
CLR P2.0
ACALL DELAY
SETB P2.1; 应答完毕,SDA置1
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -