📄 i2cdemo.asm
字号:
;2004.10.24
;ZLG7290定义
SDA BIT P0.0
SCL BIT P0.1
ACK BIT 20H
CLK BIT P1.0 ;SPI:时钟信号
CS BIT P1.1 ;SPI:片选信号
DI BIT P1.2 ;SPI:输入信号
DO BIT P1.3 ;SPI:输出信号
KEYON BIT 21H
K1_ON BIT 22H
FLAG_S BIT 23H
MTD EQU 30H
MRD EQU 40H
;SCOUNT EQU 50H
;RCOUNT EQU 51H
ADRAMH EQU 52H
ADRAML EQU 53H
H8BIT EQU 54H
ROTCOUNT EQU 55H
TEMP EQU 56H
LED1 EQU 7BH
ZLG7290 EQU 70H
DISP_BUF EQU 60H
SLA DATA 1AH
SUBA DATA 1BH
NUMBYTE DATA 1CH
BLINK DATA 1DH
NUM DATA 1EH
MTD1 EQU 0E0H
;定义器件地址
PCF8563 EQU 0A2H
;**********程序开始
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP TINT0
ORG 0100H ;主程序开始
MAIN: MOV R4,#0F0H ;延时,等待芯片复位
DJNZ R4,$
SETB IT0
SETB EX0
SETB EA
CLR FLAG_S
SETB P0.2
SETB P0.3
MOV LED1,#00H
MOV 31H,#00H
MOV 32H,#00H
MOV 33H,#00H
MOV 34H,#00H
MOV 35H,#00H
MOV 36H,#00H
MOV 37H,#00H
MOV 41H,#00H
MOV 42H,#00H
MOV 43H,#00H
MOV 44H,#00H
MOV 45H,#00H
MOV 46H,#00H
MOV 47H,#00H
;设置PCF8563 的时间值
SET8563: ;装入数据准备发送给PCF8563
MOV MTD,#00H ;控制寄存器1置为普通模式芯片运行
MOV MTD+1,#1FH ;控制寄存器2置为报警及定时器中断,定时器中断为脉冲形式
MOV MTD+2,#30H ;秒为30
MOV MTD+3,#59H ;分59
MOV MTD+4,#15H ;15点
MOV MTD+5,#18H ;18日
MOV MTD+6,#04H ;星期4
MOV MTD+7,#07H ;7月
MOV MTD+8,#02H ;2002年
MOV MTD+9,#59H ;59分时报警
MOV SLA,#PCF8563
MOV SUBA,#00H
MOV NUMBYTE,#9
LCALL IWRNBYTE
NOP ;可在此设置点观察ACK 是否为1 为0 表示总线有误
MOV MTD,#81H ;启动定时器命令及时钟频率(64HZ)送发送缓冲区
MOV MTD+1,#64 ;倒计时为64
MOV SLA,#PCF8563
MOV SUBA,#0EH ;取定时器控制字节首地址
MOV NUMBYTE,#02 ;写两个字节
LCALL IWRNBYTE ;写PCF8563
; 读出PCF8563 的时间值
LCALL RD8563
LCALL DISPLAY
KEY: JB P2.0,KEY1
LCALL D20MS
JB P2.0,KEY1
JNB P2.0,$
LJMP MINUT
KEY1: JB P2.1,KEY2
LCALL D20MS
JB P2.1,KEY2
JNB P2.1,$
LJMP HOUS
KEY2: JB P2.2,KEY
LCALL D20MS
JB P2.2,KEY
JNB P2.2,$
LJMP THD
MINUT: MOV P0,#0E3H
MOV A,#9FH
LCALL SEND1247
LCALL D1MS
ACALL RECDATA
ACALL NORMAL
MOV A,ADRAMH
MOV B,A
SWAP A
ANL A,#0FH
MOV 56H,A
MOV A,B
ANL A,#0FH
MOV 57H,A
MOV A,ADRAML
MOV B,A
SWAP A
ANL A,#0FH
MOV 58H,A
MOV A,B
ANL A,#0FH
MOV 59H,A
MOV 5AH,#0EH
MOV 5BH,#0FH
LCALL DISPLAY
LJMP KEY
HOUS: MOV P0,#1FH
LJMP KEY
THD: MOV P0,#0FFH
LCALL RD8563
LCALL DISPLAY
LJMP KEY
RD8563: MOV SLA,#PCF8563
MOV SUBA,#02H
MOV NUMBYTE,#7 ;读入7 个时间信息值
LCALL IRDNBYTE
MOV A,MRD ;取秒字节
ANL A,#7FH ;屏蔽无效位
MOV MRD,A
MOV A, MRD+1 ;取分钟字节
ANL A,#7FH ;屏蔽无效位
MOV MRD+1,A
MOV A, MRD+2 ;取小时字节
ANL A,#3FH ;屏蔽无效位
MOV MRD+2,A
MOV A,MRD
MOV B,A
SWAP A
ANL A,#0FH
MOV 64H,A
MOV A,B
ANL A,#0FH
MOV 65H,A
MOV A,MRD+1
MOV B,A
SWAP A
ANL A,#0FH
MOV 62H,A
MOV A,B
ANL A,#0FH
MOV 63H,A
MOV A,MRD+2
MOV B,A
SWAP A
ANL A,#0FH
MOV 60H,A
MOV A,B
ANL A,#0FH
MOV 61H,A
RET
;在LED上显示数字0~8,
;入口参数:R6:复合命令的第一个字节,R7:复合命令的第二个字节。R2:要显示的LED数
DISPLAY:MOV R6,#60H ;复合命令第一个字节的初值,是按位下载数据并译码的指令代码
MOV R0,#60H ;复合命令的第二个字节,是要显示的数值,这里是0
MOV R2,#06H ;循环6次,即显示6位
LOOP1: MOV MTD,R6 ;将复合命令的第一个字节送发送数据缓冲区
MOV A,@R0
MOV MTD+1,A ;将复合命令的第二个字节送发送数据缓冲区
MOV 5CH,R0
LCALL SENDCMD ;调用发送命令函数
INC R6 ;指向下一个数码管
MOV R0,5CH
INC R0 ;数值加1
LCALL DELAY ;延迟
DJNZ R2,LOOP1 ;循环8次了吗?
RET
TINT0: PUSH ACC
PUSH PSW
LCALL RD8563
LCALL DISPLAY
CPL P0.4
CPL P0.5
CPL P0.6
CPL P0.7
;JNB FLAG_S,LIGHT
;SJMP BLACK
;LIGHT: MOV A,P0
;ANL A,#0FH
;MOV P0,A
;SETB FLAG_S
;SJMP TINT0A
;BLACK: MOV A,P0
;ORL A,#0F0H
;MOV P0,A
;CLR FLAG_S
TINT0A: POP PSW
POP ACC
RETI
INIT_SCI: SETB TR1 ;启动定时器T1
MOV SCON,#50H ;设通信方式1
MOV PCON,#00H ;SMOD=0 ;开放中断
RET
LEDTAB:DB 3FH,06H,5BH,4FH,66H ;0,1,2,3,4,
DB 6DH,7DH,07H,7FH,6FH ;5,6,7,8,9
;**********延时400MS子程序
D400MS: PUSH DPH ;保护现场
PUSH DPL
PUSH PSW
PUSH ACC
SETB RS1 ;应用寄存器第4组
SETB RS0
MOV R5,#60
D400: MOV R7,#255
D400_1: MOV R6,#50
D400_2: DJNZ R6,D400_2
DJNZ R7,D400_1
DJNZ R5,D400
POP ACC ;恢复现场
POP PSW
POP DPL
POP DPH
RET
;**********延时20MS子程序
D20MS: PUSH DPH ;保护现场
PUSH DPL
PUSH PSW
PUSH ACC
SETB RS1 ;应用寄存器第4组
SETB RS0
MOV R7,#200
DAY1: MOV R6,#50
DAY2: DJNZ R6,DAY2
DJNZ R7,DAY1
POP ACC ;恢复现场
POP PSW
POP DPL
POP DPH
RET
D1MS: MOV R7,#08H
DD1: NOP
NOP
DJNZ R7,DD1
RET
DELAY: PUSH PSW
PUSH ACC
MOV PSW,#10H
MOV R6,#250
DE1: NOP
NOP
DJNZ R6,DE1
POP ACC
POP PSW
RET
SEND1247: ;发送命令字子程序(A中为要发送的命令)
MOV ROTCOUNT,#08H
CLR DO
CLR CS ;将CS变低
ROT_NEXT:
NOP
NOP
CLR CLK ;将CLK变低
RLC A ;移出第一位
MOV DI,C
SETB CLK ;发送第一位
DJNZ ROTCOUNT,ROT_NEXT
NOP
CLR CLK ;启动转换
SETB CS ;将片选拉高
RET
RECDATA: ;数据接收子程序
CLR DI
CLR CS ;将片选拉低
NOP
NOP
SETB CLK
MOV ROTCOUNT,#08H
REC1_NEXT:
CLR CLK ;发送下降沿
NOP
NOP
MOV C,DO ;移入数据
RLC A
SETB CLK
NOP
DJNZ ROTCOUNT,REC1_NEXT
MOV H8BIT,A ;保存接收到的高位数据
NOP
MOV ROTCOUNT,#08H ;为接收作准备
REC2_NEXT:
CLR CLK ;发下降沿
NOP
NOP
MOV C,DO
RLC A
SETB CLK
NOP
DJNZ ROTCOUNT,REC2_NEXT
SETB CS
MOV B,A
MOV A,H8BIT ;出口:A:存高8位,B:存低8位
MOV ADRAMH,A
MOV ADRAML,B
RET
;**********************************************
;AD转换数据归一化,入口、出口均是ADRAMH、ADRAML
NORMAL: MOV R3,#04H
MOV R0,#ADRAMH ;ADRAMH存高二位,ADRAML存低八位
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -