📄 01-15.asm
字号:
CJNE A,#08DH,NEXT8 ;星期调整项 范围:0-9
MOV A,#08DH
LCALL WRITE_COM
MOV R5,74H
MOV R6,#07H
LCALL DISP4
MOV 74H,R5
LJMP EXIT
NEXT8:
CJNE A,#0C4H,NEXT9 ;小时的十位调整项 范围:0-3
MOV A,#0C4H
LCALL WRITE_COM
MOV R6,#30H
LCALL DISP3
MOV 72H,R5
LJMP EXIT
NEXT9:
CJNE A,#0C5H,NEXT10 ;小时的个位调整项 范围:0-9
MOV A,#0C5H
LCALL WRITE_COM
MOV R5,72H
MOV R6,#25H
LCALL DISP4
MOV 72H,R5
LJMP EXIT
NEXT10:
CJNE A,#0C7H,NEXT11 ;分的十位调整项 范围:0-5
MOV A,#0C7H
LCALL WRITE_COM
MOV R6,#60H
LCALL DISP3
MOV 71H,R5
LJMP EXIT
NEXT11:
CJNE A,#0C8H,NEXT12 ;分的个位调整项 范围:0-9
MOV A,#0C8H
LCALL WRITE_COM
MOV R5,71H
MOV R6,#5AH
LCALL DISP4
MOV 71H,R5
LJMP EXIT
NEXT12:
CJNE A,#0CAH,NEXT13 ;秒的十位调整项 范围:0-5
MOV A,#0CAH
LCALL WRITE_COM
MOV R6,#60H
LCALL DISP3
MOV 70H,R5
LJMP EXIT
NEXT13:
CJNE A,#0CBH,EXIT ;秒的个位调整项 范围:0-9
MOV A,#0CBH
LCALL WRITE_COM
MOV R5,70H
MOV R6,#5AH
LCALL DISP4
MOV 70H,R5
LJMP EXIT
EXIT:RET
END
;------------------------------------------
;字符串显示子程序
;------------------------------------------
PROC DISP2
DISP2:
PUSH ACC
LOOP:
CLR A
MOVC A,@A+DPTR
JZ EXIT
LCALL WRITE_DATA
INC DPTR
SJMP LOOP
EXIT:
POP ACC
RET
END
;----------------------------------------------
;时间调整十位的子程序
;-------------------------------------
PROC DISP3
DISP3:
MOV A,KEYNAME
CJNE A,#015H,NEXT1
MOV A,#00
SJMP NEXT2
NEXT1:
CLR C
MOV A,KEYNAME
SUBB A,#0AH
JNC EXIT
ADD A,#0AH
ANL A ,#0FH
ADD A,#30H
LCALL WRITE_DATA
SUBB A,#30H
SWAP A
SUBB A,R6
JNC EXIT
ADD A,R6
MOV R5,A
SJMP EXIT
NEXT2:
MOV A,#30H
LCALL WRITE_DATA
MOV R5,#0
EXIT:RET
END
;---------------------------------------------
;时间调整的个位处理子程序
;-------------------------------------------
PROC DISP4
DISP4:
MOV A,R5
ANL A,#0F0H
MOV R5,A
MOV A,KEYNAME
CJNE A,#015H,NEXT1
SJMP NEXT2
NEXT1:
CLR C
MOV A,KEYNAME
SUBB A,#0AH
JNC EXIT
ADD A,#0AH
ANL A,#0FH
ADD A,#30H
LCALL WRITE_DATA
SUBB A,#30H
ADD A,R5
SUBB A,R6
JNC EXIT
ADD A,R6
MOV R5,A
SJMP EXIT
NEXT2:
MOV A,#30H
LCALL WRITE_DATA
EXIT:
RET
END
;------------------------------------------
;闹钟调整子菜单显示子程序
;-------------------------------------------
PROC DISP5
DISP5:
LCALL INITIAL
MOV A,#080H
LCALL WRITE_COM
MOV DPTR,#LINE12
LCALL DISP2
MOV A,#0C0H
LCALL WRITE_COM
MOV DPTR,#LINE13
LCALL DISP2
RET
END
;----------------------------------
;闹钟跳出选择菜单显示子程序
;----------------------------------
PROC DISP6
DISP6:
LCALL INITIAL
MOV A,#080H
LCALL WRITE_COM
MOV DPTR,#LINE14
LCALL DISP2
MOV A,#0C0H
LCALL WRITE_COM
MOV DPTR,#LINE15
LCALL DISP2
RET
END
;-----------------------------------------------
;等待键盘输入
;---------------------------------------------
PROC KEYWAIT
KEYWAIT:
LOOP:
MOV KEYNAME,#00H
LCALL KEYCHECK ;读键盘状态
MOV A, KEYNAME ;检查键盘有无输入
JNB ACC.7, LOOP2 ;ACC.7为0,键盘按键无效,就返回
;ACC.7为1,进入按键处理子程序
MOV A, KEYNAME ;读按键值
ANL A, #1FH ;保留
MOV KEYNAME, A ;清除按键处理标志
SJMP LOOP2
LOOP2:
RET
END
;---------------------------------------
;键盘输入错误处理子程序
;---------------------------------------
PROC KEYWRONG
KEYWRONG:
LCALL INITIAL
MOV A,#080H
LCALL WRITE_COM
MOV DPTR,#LINE3
LCALL DISP2
SETB RS0
CLR RS1
MOV R5,#30
LOOP:
LCALL DEL10MS ;延时子程序
DJNZ R5,LOOP
CLR RS0
LCALL INITIAL
RET
END
;==============================================================
;名称:SENDTIME
;描述:写入时钟信息给PCF8563:2000年1月1号星期一凌晨00点00分00秒
;PCF8563写地址(0A2H)在RTCADR中,单元地址首址在RTCREGADR中
;所发送的字节数在BYTECNT中,发送的数据装入SENDDATBUF为首的单元中
;===============================================================
PROC SENDTIME
SENDTIME:
LCALL SENDPCF8563
MOV RTCADR,#0A2H ;送PCF8563在I2C的写的地址
MOV BYTECNT,#09H ;7各时间信息+2个控制位=9位数据
MOV RTCREGADR,#00H ;寄存器从00H开始
LCALL SENDDATA ;写时间信息
RET
SENDPCF8563:
MOV 50H,#00H ;启动时钟
MOV 51H,#02H ;设置报警及定时器中断,定时器中断为脉冲形式
MOV 52H,70H ;分别将秒至年的时间写入发送缓冲区中
MOV 53H,71H
MOV 54H,72H
MOV 55H,73H
MOV 56H,74H
MOV 57H,75H
MOV 58H,76H
RET
END
;===============================================================
;名称:READTIME
;描述:读入时钟信息给单片机,PCF8563地址(0A2H)在RTCADR中,
;单元地址首址在RTCREGADR中,所发送的字节数在BYTECNT中,
;读入的数据装入RECVDATBUF(40H)为首的单元中
;注意:时间读出后需进行整理屏蔽无效位方能得出正确的信息
;===============================================================
PROC READTIME
READTIME:
MOV RTCADR,#0A2H ;送PCF8563在I2C的写的地址
MOV BYTECNT,#7 ;7个时间信息
MOV RTCREGADR,#02H ;寄存器从02H,秒开始读
ACALL RECEDATA ;读出数据并存到RECVDATBUF(40H)为首的单元中
MOV A, 40H ;取秒字节
ANL A,#7FH ;屏蔽无效位
MOV 40H,A
MOV A, 41H ;取分钟字节
ANL A,#7FH ;屏蔽无效位
MOV 41H,A
MOV A,42H ;取小时字节
ANL A,#3FH ;屏蔽无效位
MOV 42H,A
MOV A,43H ;取日字节
ANL A,#3FH ;屏蔽无效位
MOV 43H,A
MOV A,44H ;取星期字节
ANL A,#07H ;屏蔽无效位
MOV 44H,A
MOV A,45H ;取月字节
ANL A,#1FH ;屏蔽无效位
MOV 45H,A
RET
END
;===============================================================
;名称:SENDDATA
;描述:发送BYTECNT个字节子程序---发送数据或地址给PCF8563
;PCF8563地址(0A2H)在RTCADR中,单元地址在RTCREGADR中
;所发送的字节总数在BYTECNT中,发送的数据在以SENDDATBUF为首址单元中
;===============================================================
PROC SENDDATA
SENDDATA:
LCALL START ;发送I2C起始条件
WREG0:MOV A,RTCADR ;取PCF8563在I2C写的地址,为0A2写的地址
LCALL SENDBYTE ;发送PCF8563地址
JB FINISH,RETURN ;F0=1表示发送失败,返回
WREG1:MOV A,RTCREGADR ;取单元地址;单元地址会自动增加
LCALL SENDBYTE ;发送单元地址
JB FINISH,RETURN ;F0=1表示发送失败,返回
MOV R0,#SENDATBUF ;取发送数据的首地址
NEXT0:MOV A,@R0
LCALL SENDBYTE ;发送一数据
JB FINISH,RETURN ;F0=0发送失败,返回
INC R0
DJNZ BYTECNT,NEXT0 ;没发送完,继续
LCALL STOP ;全部发送完,发I2C停止信号
LCALL DEL10MS ;延时10ms,等待数据写完
RETURN:
RET
END
;===============================================================
;名称:RECEDATA
;描述:接收BYTECNT个字节子程序---从PCF8563中接收数据
;PCF8563地址在RTCADR中,需转成读地址0A3H;单元地址在RTCREGADR中
;所发送的字节数在BYTECNT中,接收数据到以RECDATBUF为首址单元中
;===============================================================
PROC RECEDATA
RECEDATA:
LCALL START ;发送I2C起始条件
WREG3:MOV A,RTCADR ;取PCF在I2C写的地址
LCALL SENDBYTE ;发送此地址
JB FINISH,RETURN ;F0=1,发送失败,返回
WREG2:MOV A,RTCREGADR ;取单元地址
LCALL SENDBYTE ;发送单元地址
JB FINISH,RETURN ;F0=1表示发送失败,返回
LCALL START ;重新发起I2C写的地址
WRRTC:MOV A,RTCADR ;取PCF8563在I2C写的地址
SETB ACC.0 ;转换为读的地址
LCALL SENDBYTE ;发送此地址
JB FINISH,RETURN ;F0=1,发送失败,返回
CLR ACK ;清接收非应答标志准备接收数据
MOV R1,#RECDATBUF
DJNZ BYTECNT,RCVNEXT ;如果还未接收数据则转去接收前ByteCnt)-1 个数据
SJMP RCVLAST ;只剩最后一个数据未接收转去接收最后一个数据
RCVNEXT:
LCALL RECVBYTE ;开始读数据
MOV @R1,A ;读出的数据放到接收数据缓冲区中
INC R1
DJNZ BYTECNT,RCVNEXT ;重复操作直到剩下最后一个数据
RCVLAST:
SETB ACK ;置接收非应答标志准备在接收完最后一个数据后发出非应答信号以停止接受数据
ACALL RECVBYTE ;接收最后一个数据
MOV @R1,A ;将最后一个数据放入接收缓冲区中
LCALL STOP ;发送I2C 总线停止条件
RETURN:
RET
END
;===============================================================
;名称:SENDBYTE
;描述:发送1字节子程序---发送数据或地址给PCF8563
;要发送的数据在A中
;BITCNT为要发送的位数:8位1字节
;===============================================================
PROC SENDBYTE
SENDBYTE:
MOV BITCNT,#8 ;要发送的位数
CLR FINISH
GOON0:CLR SCL
RLC A ;将要发送的数据移入CY中
JC SEND1 ;该位为1转发1程序
CLR SDA ;置数据线为0
SJMP SEND
SEND1:SETB SDA ;置数据线为1
NOP
SEND: NOP
SETB SCL ;拉高时钟线,使数据线上的数据有效
NOP ;延时》4US
NOP
NOP
NOP
NOP
CLR SCL ;拉低时钟线,准备发送下一数据
DJNZ BITCNT,GOON0 ;不够一字节继续
LCALL CHECKACK ;检查应答信号
RET
END
;===============================================================
;名称:RECVBYTE
;描述:接收1字节子程序---从PCF8563中接收一个字节数据
;接收到的数据在A中,接收完一字节要求发应答信号
;BITCNT为要接收的位数:8位1字节
;===============================================================
PROC RECVBYTE
RECVBYTE:
SETB SDA ;拉高数据线,SDA作为输入
MOV BITCNT,#08H ;接收一个字节,8位
GOON1:NOP
CLR SCL ;拉低时钟线,准备接收数据
NOP ;延时》4.7US
NOP
NOP
NOP
NOP
SETB SCL ;拉高时钟线,使数据线上的数据有效,开始接收数据
NOP
NOP
CLR CY ;CY清0
JNB SDA,RECV0 ;SDA为0,转接收0程序
SETB CY ;为1,置CY
RECV0:RLC A ;将SDA的的内容移入A中
NOP
NOP
DJNZ BITCNT,GOON1 ;不到一字节,继续
CLR SCL ;8 位接收完置时钟线和数据线为低准备发送应答或非应答信号
NOP
NOP
NOP
CLR SDA
JNB ACK,SENTACK ;判断是否需要继续接收字节数据若需要则转SENTACK 发送应答位
LCALL MNACK ;发送非应答信号
LJMP RETURN1
SENTACK:
LCALL MACK
RETURN1:
CLR ACK ;清接收非应答标志
RET
END
;===============================================================
;名称:START
;描述:启动I2C总线子程序---发送I2C起始条件
;===============================================================
PROC START
START:
SETB SDA ;发送起始条件的数据信号
NOP
SETB SCL ;发送起始条件的时钟信号
NOP ;等待》4.7US(即起始条件建立的时间大于4.7US)
NOP
NOP
NOP
NOP
CLR SDA ;发送起始信号
NOP ;等待》4.0US(既起始条件锁定的时间大于4.0US)
NOP
NOP
NOP
NOP
CLR SCL ;钳住I2C总线,准备发送或是接收数据
RET
END
;===============================================================
;名称:STOP
;描述:停止I2C总线子程序---发送I2C停止条件
;===============================================================
PROC STOP
STOP:
CLR SDA ;发送停止条件的数据信号
NOP
NOP
SETB SCL ;发送停止条件的时钟信号
NOP ; 等待》4.0US(既停止条件建立的时间大于4.0US)
NOP ;
NOP
NOP
NOP
SETB SDA ;发送停止信号
NOP ;等待》4.7US(即停止条件锁定的时间大于4.7US)
NOP
NOP
NOP
NOP
CLR SCL ;钳住I2C总线,停止发送或是接收数据
RET
END
;===============================================================
;名称:MACK
;描述:发送应答确认信号ACK---接收数据方每接收完一字节数据后发出
;===============================================================
PROC MACK
MACK:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -