"); //-->
;*********************
;******IIC程序********
;*********************
ORG 0000H
SJMP MAIN
MAIN: SDA BIT P2.4;IIC的数据端
SCL BIT P2.5;IIC的时钟端
KV EQU 7FH;键值存储区
SV EQU 7EH;行扫描字暂存
IICSV EQU 7DH;IIC存储单元首址
DTSV EQU 77H;数据存储单元首址
KEYNUM EQU 71H;按键次数存储位
SLA EQU 70H;IIC器件的寻址字节
NUM EQU 6FH
BUZZER BIT P2.1;蜂鸣器位
;********初始化及调显示*************
MOV R2,#17
MOV R1,#7FH
CLRR: CLR A
MOV @R1,A
DEC R1
DJNZ R2,CLRR;初始化各存储单元
MOV R3,#6
MOV R1,#DTSV
CCLR00: MOV @R1,#15
DEC R1
DJNZ R3,CCLR00;DTSV初值附为15
MOV R2,#6
SCAN: MOV A,#11H
MOV SBUF,A
JNB TI,$
CLR TI
DJNZ R2,SCAN;调显示
;*******键扫主程序**********
KEY: MOV P1,#0F0H;令所有行为低电平
MOV R7,#0FFH;设置计数常数
DJNZ R7,$;延时
MOV A,P1;读取P1口列值
CJNE A,#0F0H,EKEY
SJMP KEY;无键按下返回
EKEY: LCALL D20MS
CLR BUZZER
SKEY: MOV A,#0;下面进行行扫描
MOV R4,A
MOV R5,A;行,列计数器清零
MOV R3,#0FEH;R3为行扫描字暂存
SKEY1: MOV A,R3
MOV SV,R3;行扫描字送SV暂存
MOV P1,A;扫描字送P1口
NOP
NOP
NOP
NOP
NOP;稳定P1口输出
MOV A,P1;读列值
CJNE A,SV,SKEY3;有键按下跳转
INC R4
SETB C;准备将行扫描左移一位
MOV A,R3
RLC A
MOV R3,A
MOV A,R4
CJNE A,#4,SKEY1
SJMP KEY
SKEY3: JNB ACC.4,SKEY5
JNB ACC.5,SKEY6
JNB ACC.6,SKEY7
JNB ACC.7,SKEY8
SJMP KEY
SKEY5: MOV A,#0
MOV R2,A
AJMP DKEY
SKEY6: MOV A,#1
MOV R2,A
AJMP DKEY
SKEY7: MOV A,#2
MOV R2,A
AJMP DKEY
SKEY8: MOV A,#3
MOV R2,A
DKEY: MOV A,R4
LCALL DECODE
;********判断功能键************
CJNE A,#15,ENT;是否是修改IIC键
LCALL DKEY1;关提示音.
;MOV R3,KEYNUM;按键次数送R3********************************
;MOV R0,#DTSV;数据存储首址送R0
IICLP: ;MOV A,@R0
LCALL WRBYTE
;DEC R0
;DJNZ R3,IICLP
MOV R2,#6
MOV R0,#DTSV
SCAN1: MOV DPTR,#TAB
MOV A,@R0
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
DEC R0
DJNZ R2,SCAN1;调显示
;LCALL DKEY1
MOV R3,#6
MOV KEYNUM,#0
MOV R1,#DTSV
CCLR0: MOV @R1,#15
DEC R1
DJNZ R3,CCLR0
AJMP KEY
SCAN2: MOV R2,#6
SCAN21: MOV A,#11H
MOV SBUF,A
JNB TI,$
CLR TI
DJNZ R2,SCAN21;调显示
LCALL DKEY1
MOV KEYNUM,#0
AJMP KEY
ENT: CJNE A,#14,RESV1
LCALL DKEY1
;MOV R3,KEYNUM;按键次数送R3
;MOV R0,#IICSV;数据存储首址送R0
RDIIC: LCALL RDBYTE
;MOV @R0,A
;DEC R0
;DJNZ R3,RDIIC
MOV R3,KEYNUM;按键次数送R3
MOV R4,IICSV;IIC存储首址
MOV R5,DTSV;输入数据存储首址
COMP: MOV A,R4
MOV SLA,R5;SLA中暂存数据地址
CJNE A,SLA,CCLR1
DEC R4
DEC R5
DJNZ R3,COMP
;MOV R3,KEYNUM
;MOV R1,#DTSV
;RESV2: MOV A,@R1
;LCALL RESV
;DEC R1
;DJNZ R3,RESV2
CLR BUZZER
LCALL D1M
SETB BUZZER
MOV R3,KEYNUM
CCLR1: MOV R1,#DTSV
CCLR: MOV @R1,#15
DEC R1
DJNZ R3,CCLR
;MOV KEYNUM,#0
SJMP SCAN2
RESV1: INC KEYNUM;按键次数存储位加1
LCALL RESV
MOV R3,A
MOV A,NUM
;INC A
;MOV NUM,A
MOV R0,#DTSV
ADD A,R0
MOV R0,A
MOV A,R3
MOV @R0,A
MOV A,NUM
INC A
MOV NUM,A
LCALL DKEY1
AJMP KEY
DKEY1: MOV A,#0F0H
MOV P1,A
NOP
NOP
NOP
MOV A,P1
CJNE A,#0F0H,DKEY1
SETB BUZZER ;判断键是否弹起
RET
;********调整键值************
DECODE: MOV A,R4
MOV B,#4
MUL AB
ADD A,R2
RET
RESV: MOV DPTR,#TAB;数字表头始址送DPTR
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
RET
;*********IIC子程序*******************
;********一字节数据发送***************
WRBYTE: PUSH PSW;保护现场
WRBYTE1:MOV PSW,#18H;改用第三组工作寄存器
MOV A,KEYNUM
CJNE A,#0,WRB1
RET
;MOV R3,A;将欲发送数据送R3
WRB1: MOV SLA,#0A0H;送总线寻址字节
LCALL STA ;发送起始条件
MOV A,SLA;读取写控制字
LCALL WRB;发送一个字节
LCALL CACK;检查应答位
JB F0,WRBYTE1;无应答,重发
MOV R0,#DTSV ;欲发送数据首址
MOV R5,KEYNUM;R5保存欲发送数据的字节数
WRDA: MOV A,@R0;读一个字节数据
LCALL WRB;发送写控制字节
LCALL CACK;检查应答位
JB F0,WRBYTE1;无应答,重发
DEC R0
DJNZ R5,WRDA;未发送完N个字节继续
LCALL STOP ;数据发送完毕,停止
POP PSW ;恢复现场
RET
;**********读存数据程序****************
RDBYTE: PUSH PSW;保护现场
RDBYTE1:MOV PSW,#18H;改用第三组工作寄存器
;MOV R3,A ;将欲发送数据送R3
MOV SLA,#0A1H;送总线寻址字节
LCALL STA ;发送起始条件
MOV A,SLA;读入读控制字
LCALL WRB;发送读控制字节
LCALL CACK;检查应答位
JB F0,RDBYTE1;无应答,重发
MOV R1,#IICSV
MOV R3,KEYNUM;欲传送字节数送R3
GO: LCALL RDB;读一个字节
MOV @R1,A
DJNZ R3,ACK
LCALL MNACK;已读完字节,发ACK非
;JB F0,RDBYTE1;无应答,重发
LCALL STOP ;数据发送完毕,停止
POP PSW ;恢复现场
RET
ACK: LCALL MACK;发ACK
DEC R1
SJMP GO;继续接收
;**********STA子程序*******************
STA: SETB SDA
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SDA
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
RET
;***********WRB发送子程序***************
WRB: MOV R7,#8;位计数器初值
WLP: RLC A;欲发送位送C
JC WR1 ;此位为1,转至WR1
CLR SDA ;此位为零,发送0
SETB SCL;时钟脉冲变为高电平
NOP
NOP
NOP
NOP
NOP;延时4微妙
CLR SCL;时钟脉冲变为低电平
DJNZ R7,WLP;未发送完8位,转至WLP
RET
WR1: SETB SDA ;此位为1,发送1
SETB SCL;时钟脉冲变为高电平
NOP
NOP
NOP
NOP
NOP;延时4微妙
CLR SCL;时钟脉冲变为低电平
DJNZ R7,WLP;未发送完8位,转至WLP
RET
;*********RDB主机接收子程序**************
RDB: MOV R7,#8;R7存放位计数器初值
RLP: SETB SDA;SDA输入
SETB SCL;SCL脉冲开始
MOV C,SDA; 读SDA值
MOV A,R6;取回暂存结果
RLC A;移入新接收位
MOV R6,A;暂存入R6
CLR SCL;SCL脉冲结束
DJNZ R7,RLP;未读完8位,转至RLP
RET
;**********CACK子程序************
CACK: SETB SDA;SDA作为输入
SETB SCL;第九个时钟脉冲开始
NOP
NOP
NOP
MOV C,SDA;读SDA线
MOV F0,C;转存入F0中
CLR SCL ;时钟脉冲结束
NOP
NOP
NOP
RET
;*********发送应答位和非应答位MACK,MNACK子程序*************
MACK: CLR SDA
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SETB SDA;保持数据时间,大于4微秒
RET
MNACK: SETB SDA
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
CLR SDA;保持数据时间,大于4微秒
RET
;*******STOP子程序**************
STOP: CLR SDA
SETB SCL
NOP
NOP
NOP
NOP
NOP
SETB SDA
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
RET
KTAB: DB 11H,12H,14H,18H,21H,22H,24H,28H
DB 31H,32H,34H,38H,41H,42H,44H,48H
TAB: DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D1H,10H,90H;0-9
DB 50H,1CH,39H,16H,38H,78H,70H,0FEH,0EFH,0FFH;A B, C, D, E, ,F ,P, -, ,. ,COLSE
DB 01H,0C7H,22H,82H,0C4H,88H,08H,0C3H,00H,80H;带小数点的字形码0.,1.,-----9.
D200MS: MOV R1,#10
D20MS1: MOV R7,#10H
DL201: MOV R6,#0FFH
DJNZ R6,$
DJNZ R7,DL201
DJNZ R1,D20MS1
RET
D20MS: MOV R7,#10H
DL20: MOV R6,#0FFH
DJNZ R6,$
DJNZ R7,DL20
RET
D1M: MOV R6,#13
D600MS1:MOV R3,#30
D10MS1: MOV R5,#10H
DL2011: MOV R4,#0FFH
DJNZ R4,$
DJNZ R5,DL2011
DJNZ R3,D10MS1
DJNZ R6,D600MS1
RET
END
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。