51单片机的8位数码管电子时钟设计
51单片机的8位数码管电子时钟设计
概要
可实现时-分-秒自动走时功能,显示格式为 00-00-00。项目采用STC89C52单片机作为主控芯片,使用定时器0完成1秒精准计时,通过74HC138译码器驱动8位共阴极数码管实现动态显示。
硬件设计
1. 核心器件
- 主控芯片:STC89C52RC 单片机
- 显示模块:8位共阴极数码管
- 驱动芯片:74HC138 3-8译码器
- 辅助电路:晶振11.0592MHz、复位电路、电源电路
2. 电路连接方式
- 数码管段选:全部由 P0 口 控制(a~g、dp)
- 74HC138译码器位选: - P1.0 → A - P1.1 → B - P1.2 → C
- 数码管为共阴极,低电平点亮
- 8位数码管依次显示: 第1位:时十位 、第2位:时个位 、第3位:分隔符“-” 、第4位:分十位 、第5位:分个位 、第6位:分隔符“-” 、第7位:秒十位 、第8位:秒个位
可参考下图电路连接:

软件设计
1. 设计思路
- 使用定时器0工作在模式1,配置11.0592MHz晶振,实现1秒精准定时
- 每秒触发一次中断,秒单元+1,依次进位到分、时
- 小时最大23,分、秒最大59,超出自动归零
- 通过8位数码管动态扫描不断刷新显示,保证无闪烁
-固定显示格式:00-00-00,上电初始时间 00-00-00
2. 完整代码(带详细注释)
#include <reg52.h>
#include "delayms.H"
sbit W_A=P1^0;
sbit W_B=P1^1;
sbit W_C=P1^2;
// 共阴极数码管段码 0~9 + “-”
u8 code seg_table[] = {
0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,
0x40 // 第10位是 '-'
};
// 显示缓存:8位数码管
u8 disp_buf[8] = {0,0,10,0,0,10,0,0};//将hour分时的十位给到disp_buf[0]、时的个位给到disp_buf[1];依次。。。
// 时间变量(可自定义开始的时间)
u8 hour = 23;
u8 min = 59;
u8 sec = 40;
// 数码管位选:pos 0~7
void select_pos(u8 pos)
{
switch(pos)
{
case 0: W_C=0;W_B=0;W_A=0; break;
case 1: W_C=0;W_B=0;W_A=1; break;
case 2: W_C=0;W_B=1;W_A=0; break;
case 3: W_C=0;W_B=1;W_A=1; break;
case 4: W_C=1;W_B=0;W_A=0; break;
case 5: W_C=1;W_B=0;W_A=1; break;
case 6: W_C=1;W_B=1;W_A=0; break;
case 7: W_C=1;W_B=1;W_A=1; break;
}
}
// 数码管扫描显示
void display(void)
{
u8 i;
for(i=0;i<8;i++)//每一位数码管都要走一遍
{
P0 = 0x00; // 消隐
select_pos(i);
P0 = seg_table[disp_buf[i]];//给P0送段码(x)
delay_ms(1);
}
P0 = 0x00;
}
// 定时器0初始化:1ms@11.0592MHz
void Timer0_Init(void)
{
TMOD |= 0x01;//定时器T0方式一
TH0 = 0xFC;//定时时间配置
TL0 = 0x67;
ET0 = 1;//打开T0定时器中断(有中断函数)
TR0 = 1;//打开T0定时器运行(开始定时)
EA = 1;//打开总中断(像总大门一样)
}
// 定时器0中断:1ms进一次
u16 cnt_ms = 0;
void Timer0_ISR(void) interrupt 1
{
TH0 = 0xFC;
TL0 = 0x67;
cnt_ms++;
if(cnt_ms >= 999) // 1ms*1000=1秒
{
cnt_ms = 0;
sec++;//秒++
if(sec >= 60)//秒到60归零,并对分+1
{
sec = 0;
min++;//分++
if(min >= 60)//分到60归零,并对时+1
{
min = 0;
hour++;//时++
if(hour >= 24)//时到24归零
hour = 0;
}
}
}
}
// 把时间写入显示缓存
void time_to_buf(void)
{
// 格式:00-00-00
disp_buf[0] = hour / 10; // 时十位
disp_buf[1] = hour % 10; // 时个位
disp_buf[2] = 10; // -
disp_buf[3] = min / 10; // 分十位
disp_buf[4] = min % 10; // 分个位
disp_buf[5] = 10; // -
disp_buf[6] = sec / 10; // 秒十位
disp_buf[7] = sec % 10; // 秒个位
}
void main(void)
{
Timer0_Init();
while(1)
{
time_to_buf();//先获取定时器的时分秒。然后将时分秒取出时的十位个位、分的十位个位、秒的十位个位,放到缓存数组中
display();
}
}
编译下载
1.打开keil5项目工程,点击左上角的编译按键进行程序编译,编译结果显示0错误0警告就进行下一步的下载操作

2.打开proteus仿真工程,双击单片机进入配置页面,然后选择导入下载文件,最后点击OK,这样就下载好程序到单片机中了

3.效果演示:点击仿真运行按键,程序开始运行,可以看到数码管从 00-00-00开始自动走动。

小结
本次电子时钟设计,通过定时器0实现了高精度1秒计时,搭配74HC138译码器与8位数码管完成稳定显示。
最后,我已经把本次实验的完整源码、Proteus仿真文件、工程文件都整理好啦,需要的同学直接复制链接到百度网盘自取下载:
链接: https://pan.baidu.com/s/1n6evZDdHEJ8bg5DSY5zfAQ?pwd=ypt7 提取码: ypt7
⚠️ 特别提醒:本项目资料仅用于学习与技术交流分享,严禁用于任何商业用途或二次开发售卖,感谢理解!
更多推荐



所有评论(0)