
A36基于51单片机汇编语言六位数码管时钟Proteus设计
用51单片机汇编语言做一个六位数码管电子钟:显示格式HH.MM.SS,用小数点当分隔符,定时器0工作在方式2每100微秒中断一次,累计10000次正好1秒,秒满60进分、分满60进时、时满24归零。没有按键校时,纯走时逻辑,最适合拿来吃透定时器。
一、设计实现功能
本设计功能简介:使用51单片机和汇编语言设计一个数码管时钟的proteus仿真,要求以下功能:
1、使用汇编语言编写程序。
2、六位数码管显示时、分、秒,格式HH.MM.SS。
3、定时器0方式2提供100微秒时基,中断累计10000次为1秒。
4、秒、分、时按60、60、24进制自动进位。
二、资源汇总
1、仿真文件:Proteus工程,7.8和8.6两个版本都能直接打开。
2、程序文件:main.asm汇编源码,以及编译好的cx.hex。
3、修改日期小工具:购买资料后赠送,用于修改文件创建日期,下载地址在文章最后。
三、设计介绍
拿到压缩包之后先解压,没有解压软件的直接搜"压缩",下载解压软件后先解压文件,再运行仿真和程序。
图1 Proteus仿真总览

时分秒各占一个字节:HOUR在40H、MINUTE在41H、SECOND在42H,显示缓存从30H开始放6个段码,位选走P3、段码走P0。
时基的产生是整段程序的重点。方式2下8位定时器自动重装,重装值256-100=156,也就是每100个机器周期溢出一次,12MHz晶振下正好100微秒:
| 项目 | 值 | 说明 |
| 工作方式 | TMOD=02H | 方式2,8位自动重装 |
| 重装值 | TH0=TL0=156 | 256-100,溢出周期100微秒 |
| 每秒中断次数 | 10000 | 100微秒×10000=1秒 |
| 计数器 | C100us(43H、44H两个字节) | 16位,存10000 |
10000超过了8位,所以程序用两个字节拼成16位计数器,中断里先减低位、低位减到0再减高位,两个字节都为0就说明1秒到了:
`asm
T0INT: PUSH PSW
PUSH ACC
MOV A,C100us+1
JNZ GOON ;低字节不为0,跳过借位
DEC C100us ;低字节为0,高字节借1
GOON: DEC C100us+1
MOV A,C100us
ORL A,C100us+1 ;两字节相或,为0表示减完
JNZ EXIT
MOV C100us,#HIGH(TICK) ;重装10000
MOV C100us+1,#LOW(TICK)
INC SECOND
...`
进位链是三个CJNE:秒到60清零并进位分,分到60清零并进位时,时到24清零。三个判断串在一起,只有前一级归零才会走到下一级:
| 计数 | 满值 | 处理 |
| SECOND | 60 | 清0,MINUTE加1 |
| MINUTE | 60 | 清0,HOUR加1 |
| HOUR | 24 | 清0 |
中断服务程序进出都做了PUSH PSW、PUSH ACC保护现场,是因为主程序正在用A做除法拆位,中断里改A会把显示拆错。这是51中断编程的基本功,很多人漏掉这句就会出现"偶尔闪一个乱码"。
显示部分把时、分、秒各自除10取十位个位,查段码表以后放进缓存,再在小时和分钟的个位后面ORL A,#80H点亮小数点,六个数字就变成HH.MM.SS的样子。扫描用R2从01111111B开始每次RR A右移一位,低电平逐位选中:
`asm
LOOP: MOV A,#0
MOV P0,A ;先关段码,消隐
MOV A,@R0
MOV P0,A ;送段码
MOV A,R2
MOV P3,A ;送位选
MOV R6,#01H
CALL DELAY
MOV A,R2
RR A ;位选右移一位`
先关段码再换位选,是为了防止上一位的段码串到下一位上形成"鬼影"。
特别注意: 时间走得快一倍或慢一半,先查晶振,100微秒时基是按12MHz算的,用11.0592MHz要改成256-92;数码管只亮一位或者全亮,检查位选码,程序用的是01111111B右移,P3.7先选中第一位;显示有重影,就是消隐没做,MOV P0,#0必须在送段码之前;走时不准但很稳定,是中断响应延迟造成的累计误差,可以改成"每次中断重装时补差值",或者用方式1加自动重装补偿;一上电就显示乱码,先看LEDBUF有没有初始化,程序在MLOOP里每次都重算所以问题不大,但如果改了结构记得清缓存。
四、日期修改
资料中提供修改日期的小工具,购买资料赠送修改文件创建日期的小工具,三个下载地址都在文章最后。
五、资料下载
付费后获取下载链接,直接下载到电脑上,然后解压即可!每个链接前面都配了二维码,手机扫码可以直接跳转。
/

