你的程序中,有数码管扫描显示、按键扫描、RTC三部分。
在构建程序结构的时候,考虑到几个部分的特点,一般情况如下:
1、如果时间显示到秒,应在100ms左右读一次RTC。
2、为了保证显示不删,应在20ms以内完成一次显示刷新,假设你用了20个数码管显示日期和时间。
3、按键是随机的,需要检测,一般按键按下的时间不小于50ms,可以考虑在10ms检测一次按键。
程序可以定义一个1ms的定时器,设置几个变量对定时器进派和行计数。
每个1ms定时到时,自加对定时器的计数,并更新数码管显示,20ms更新完20个数码尘搜盯管。
每到10ms检测一次按键,记录状态,与上次状态进行比较,如果连续两次或三次检测到按键按下,设置按键动作的标记,并确定如何更改显示,改变显存。
如果不在设置状态,每100ms读一次RTC的值,将值更新到显存。
如果数码管需要调整亮度,可以将1ms定时器改为100us,分给每个数码管的1ms内,改变其点亮的时间,就可以调出十种亮度。
用这种架构做这个程序,处理器负担很轻,对所有的外设漏坦的响应一样迅速。你会感到51单片机还是能干很多活的。
可以实现,写好了,测试通过可以,加了些注释,帮助你看,不懂可以留言,帮你解答...希望可以帮到你,ASSUME CS:CODE,DS:DATA,SS:STACK
DATA SEGMENT
MESSAGE DB 'Please input a number?','$'
STR1 DB 0DH,0AH,'houyongtao080702211',0DH,0AH,'$'
STR2 DB 0DH,0AH,'112207080oatgnoyuoh',0DH,0AH,'$'
DAT_A DB 100
DB ?
DB 100 DUP(0)
DATA ENDS
STACK SEGMENT
STA DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
START:
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV SP,100
L: LEA DX,MESSAGE
MOV AH,09H
INT 21H
LEA DX,DAT_A
MOV AH,0AH
INT 21H
判断数据的合法性,不合法退出------------------------
LEA BX,DS:[DAT_A+2]
L0: MOV AL,DS:[BX]
INC BX
CMP AL,0DH 输入数值后跟的是个回车0D
JZ L3
CMP AL,'0'
JL OVER
CMP AL,'9'
JA OVER
JMP L0
L3: LEA SI,DS:[DAT_A+2] 从DX指向枝禅的单元读入
CALL ASCTDEC 调用ASCII码转换为十进制数
MOV DS:[BX],AX
TEST AX,1 判断该单元内的数字的最低位,为0,则是偶数
JZ L1 为偶数
JNZ L2
L1: LEA DX,STR2
MOV AH,09
INT 21H
JMP L
L2: LEA DX,STR1
MOV AH,09
INT 21H
JMP L
OVER:
MOV AH,4CH
INT 21H
ASCII转十进制数子程序-----------------------------------------
ASCTDEC:
PUSH BX
PUSH CX
PUSH DX
MOV AX,0 存放转换结果
MOV DL,DS:[SI]
ASCTDEC_L3:
AND DL,0FH 利用数字ASCII码与十进制的关系:ASCII低四位就是十进制数
MOV DH,0
ADD AX,DX
INC SI
MOV DL,DS:[SI]
CMP DL,'0'
JL ASCTDEC_L2
CMP DL,'9'滑搏
JG ASCTDEC_L2
CALL MUL10 调用乘10的子程猛让尘序
JMP ASCTDEC_L3
ASCTDEC_L2:
POP DX
POP CX
POP BX
RET
乘10的子程序----------------------------------------------
MUL10: MOV BX,AX
SHL AX,1 乘2
SHL AX,1 再乘2
ADD AX,BX 加上原来的数,相当于乘以5
SHL AX,1 再来乘2,总共乘了10
RET
CODE ENDS
END START
这是键盘显示芯片8279的驱动程序。程序中,原来有一些注释,其中的8279,都误写成了8259。
尽量加写了一些注释,其中对8279的一些命令、数据,没有多写,建议楼主参考8279的资料。
CPORT EQU5FFFH 8259 {应该是8279} 控制端口地址
DPORT EQU5EFFH ?? 应该是8279 数据端口地址
DBUFEQU30H
ORG 0000H
LJMPSTART主程序入口地址
ORG 0013H
LJMPINT1中断处理子程序入口
START: 主程序
MOV SP, #6FH???设定栈底
MOV DPTR, #CPORT 8259 {应该是8279} 控制端口
MOV A, #0DCH 清除命令字
MOVX@DPTR, A 清除{8279}的显示内容
CLEAN :
MOVX A, @DPTR 读{8279的}状态字
JB ACC.7, CLEAN 判断显示RAM是否可 *** 作
MOV A, #00H{8279}的方式命令字
MOVX@DPTR,A 写入{8279}
MOV A, #2AH{8279}的分频系数
MOVX@DPTR,A写入{8279}
=========================以上是设定8279的工作方式
MOV R7, #6H
MOV R0, #DBUF
MOV A, #10H设置显示缓存区内容
===========================================================
以下部分
CDBUF:
MOV @R0, A
INC R0
DJNZR7, CDBUF
=========================以上是清除显示缓存区内容
LCALL DISP调用显示子程序
CLR IT1IT1清0,开外中断1
NOP 空 *** 袜穗渗作
SETBEA
NOP空 *** 作
SETBEX1置EX1(外部中断1中断允许位)为1
NOP空 *** 作
CLEAN1:
LJMPCLEAN1等待中断
INT1: 外部中断程序
PUSHACC 保护现场
PUSHDPH
PUSHDPL
MOV DPTR, #CPORT 8279的告脊控制端口
MOV A, #40H 01000000B
MOVX@DPTR, A 将40H当做命令写入8279
MOV DPTR, #DPORT 8279的数族碰据端口
MOVXA, @DPTR 读出按键数值
MOV R7, #6H
MOV R0, #DBUF
MOV @R0, A 按键数值写入显示缓冲区
LCALL DISP显示
LCALL L_SHIFT显示缓冲区内容移位
POP DPL 恢复现场
POP DPH
POP ACC
RETI中断程序结束
L_SHIFT:显示缓冲区内容移位
MOV R7, #6H 移位6次
MOV R0, #DBUF+4
MOV R1, #DBUF+5
NEXT0:
MOV A, @R0 取第四个
MOV @R1, A 送到第五个
DEC R0
DEC R1 修改地址号码
DJNZR7, NEXT0循环6次移位
RET
以上部分
================================================================
DISP:
MOV DPTR, #CPORT
MOV A, #092H
MOVX@DPTR, A
MOV R0, #DBUF R0中存放的是缓冲区的首地址
MOV R7, #06H
NEXTC:
MOV A, @R0
INC R0
MOV DPTR, #DCODE
MOVCA, @A+DPTR
MOV DPTR, #DPORT
MOVX@DPTR, A
DJNZR7, NEXTC
RET 返回
DCODE: DB 0C0H,0F9H,0A4H,0B0H 字型编码表
DB 099H,092H,082H,0F8H
DB 080H,090H,088H,083H
DB 0C6H,0A1H,086H,08EH,0FFH
END
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)