📄 24i2c.asm
字号:
;程序名: MCS51实验板配套程序-24系列EEPROM读写
;电路介绍:由p1.7=sda,p1.6=scl;显示电路同前面例子
;功能操作:按S3加数,按S1将i2c指定地址数据读出、显示,按S2将指定数据写入
;www.01mcu.net www.01mcu.com 2003/5/12编写
;********************************************************************
xsdat bit p1.4 ;定义驱动74164的数据脚为p1.4
xsclk bit p1.5 ;74164的时钟
gw bit p1.0 ;个位显示控制脚
sw bit p1.1 ;十位
bw bit p1.2 ;百位
qw bit p1.3 ;千位
sda bit p1.7
scl bit p1.6
read bit p3.2 ;读按键
wri bit p3.3 ;写按键
sadd bit p3.4 ;+数键
sjgw equ 30h ;显示数据存储器
sjsw equ 31h
sjbw equ 32h
sjqw equ 33h
i2cadd equ 20h ;i2c的地址
jstem equ 21h ;i2c的数据
;*****************************************************
mov sp,#40h
mov i2cadd,#10h ;对i2c的10H地址进行操作
mov sjgw,#0
mov sjsw,#0
mov sjbw,#0
mov sjqw,#0
lcall i2cread
mov jstem,r7 ;开始显示为读i2c 10H的数据
acall b2c
main : lcall display
jb sadd,n1
ljmp addkey
n1: lcall display
jb read,n2
ljmp readkey
n2: lcall display
jb wri,main
ljmp wrikey
;-+1----------------------------
addkey: mov r4,#5
addl1: lcall display
jnb sadd,addl1
djnz r4,addl1
inc jstem ;+1
acall b2c ;转换
ljmp main
;--read------------------------
readkey: mov r4,#5
readl1: lcall display
jnb read,readl1
djnz r4,readl1
lcall i2cread ;将i2cadd地址指定的数据读出
mov jstem,r7
acall b2c ;转换
ljmp main
;--wri-------------------------
wrikey: mov r4,#5
wril1: lcall display
jnb wri,wril1
djnz r4,wril1
lcall i2cwri ;将jstmp写到i2cadd
ljmp main
;***转换程序**********************************
b2c: mov a,jstem
mov b,#100
div ab
mov sjbw,a
mov a,b
mov b,#10
div ab
mov sjsw,a
mov sjgw,b
ret
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;写24C01.(传递的地址在I2CADD,数据在JSTEM中,子程序内用R7).
;**************************************************************
I2CWRI: SETB SDA
SETB SCL ;置SDA/SCL=1
ACALL R2STAR ;写开始状态字
MOV R7,#10100000B ;SET 2401=写
ACALL R2SEND ;送
MOV ACC,I2CADD ;I2CADD指向2401的起始地址
MOV R7,ACC ;将要写2401的起始地址送到R7
ACALL R2SEND
MOV R0,I2CADD
MOV ACC,JSTEM ;写第一个号
MOV R7,ACC ;数据传递到R7
ACALL R2SEND ;写具体号码
ACALL R2STOP ;停止
ACALL D10MS ;等待一定时间使24C01内部写完成
RET
;------------------------------------------
;写到2401 本程序开始及结束SDA & SCL 均=0 ,发送数据在R7
;------------------------------------------
R2SEND: PUSH ACC ;保存ACC
MOV ACC,R7 ;将R7中的数发送出去
MOV R6,#08H ;往2401发送数据
R2SLOP1: RLC A ;将ACC中的数据移到数据线上
MOV SDA,C ;送出数据
ACALL D15US
SETB SCL ;发送串行时钟进行写操作
ACALL D15US
CLR SCL
DJNZ R6,R2SLOP1 ;串行发送8 BIT
SETB SDA ;准备接收ACK
ACALL D15US
SETB SCL ;接收ACK的时钟
ACALL D15US
R2SLOP2: MOV C,SDA ;写完后等待确认信号 ACK
JC R2SLOP2
CLR SCL ;为下一步其它操作做准备
CLR SDA
POP ACC ;还原ACC
ACALL D1MS ;等待内部写完
RET
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;读2401.地址在I2CADD;读出数据在R7
;------------------------------------------------------------------
I2CREAD: ACALL R2STAR ;写状态字
MOV R7,#10100000B ;SET 2401=WRI
ACALL R2SEND ;送出状态字
MOV A,I2CADD ;上程序传来的读取地址
MOV R7,A ;地址数据送R7
ACALL R2SEND ;送出数据
SETB SDA
SETB SCL ;保证SDA/SCL起始=1
ACALL R2STAR
MOV R7,#10100001B ;0A1H ;读状态
ACALL R2SEND
ACALL R2READ ;读所需的数
ACALL R2STOP
RET
;**************************************************************
;设置开始 ,初始SDA &SCL=1,结束 SDA & SCL=0
;--------------------------------------------------------------
R2STAR: ACALL D15US ;对2401操作开始
CLR SDA ;在SCL=1时,SDA由1变为0表示开始
ACALL D15US
CLR SCL
ACALL D15US
RET
;----------------------------------------------------------------
;读取1字节数据
;----------------------------------------------------------------
R2READ: PUSH ACC ;保存ACC
MOV R6,#08H
R2RLOP1: SETB SDA ;置数据线=1
ACALL D15US
SETB SCL ;输出一个串行时钟
ACALL D15US
MOV C,SDA ;读数据线上的数据到 C
RLC A ;移到 ACC
ACALL D15US
CLR SCL
DJNZ R6,R2RLOP1 ;读 8 BIT 数据
ACALL D15US
CLR SDA
MOV R7,ACC ;将接收到的数据保存到R7
POP ACC ;还原ACC
RET
;----------------------------------------------------------------
;设置结束 在SEND & READ 后DSA & SCL均=0 ,本程序退出后 SDA & SCL=1
;----------------------------------------------------------------
R2STOP: ACALL D15US ;对2401操作结束
SETB SCL ;在SCL=1时,SDA由0变为1表示结束
ACALL D15US
SETB SDA
ACALL D15US
RET
;*****************************************************************
;I2C串行时钟延时程序
;------------------------
D15US: PUSH PSW ;3区
SETB RS0
SETB RS1
MOV R4,#08H
DJNZ R4,$
POP PSW
RET
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;************************************************************************
;74164显示程序,使用RS1=1,RS0=0的1区
;---------------------------------------------------------
display: PUSH ACC ;保存ACC
push psw
clr rs1
setb rs0 ;使用第一区工作寄存器
mov dptr,#xstab
mov a,sjgw ;取得数据
movc a,@a+dptr ;提取字模
acall dsout ;调用送出子程序
clr gw
acall ds1ms ;调用显示1ms延时程序
setb gw
mov a,sjsw
movc a,@a+dptr ;提取字模
acall dsout ;送出
clr sw
acall ds1ms ;显示1ms
setb sw
mov a,sjbw
movc a,@a+dptr ;提取字模
acall dsout ;送出
clr bw
acall ds1ms ;显示1ms
setb bw
mov a,sjqw
movc a,@a+dptr ;提取字模
acall dsout ;送出
clr qw
acall ds1ms ;显示1ms
setb qw
pop psw
POP ACC ;出栈
ret ;返回调用
;---送出循环----------
dsout:
MOV R0,#8 ;传送一个字节8位
dSLOOP: RLC A ;左移
MOV xsdat,C ;送数据到数据口
SETB xsclk ;送一时钟
CLR xsclk
DJNZ R0,dSLOOP
RET
;---显示延时----------
ds1ms: mov r1,#10
ds1lo: mov r2,#100
djnz r2,$
djnz r1,ds1lo
ret ;延时返回
;************************************************************************
D10MS: PUSH PSW ;3区
SETB RS0
SETB RS1
mov r2,#10
d10lo: MOV R3,#0FFH
DJNZ R3,$
djnz r2,d10lo
POP PSW
RET
;*****************************************************************
D1MS: PUSH PSW ;3区
SETB RS0
SETB RS1
MOV R3,#100
DJNZ R3,$
POP PSW
RET
;************************************************************************
;显示字表(共阴)
xstab: DB 3FH,06H,5BH,4FH ;"0","1","2","3"
DB 66H,6DH,7DH,07H ;"4","5","6","7"
DB 7FH,6FH,77H,7cH ;"8","9","A","B"
DB 39H,5eh,79h,71h ;"C","D","E","F"
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -