1
控制/MCU
在之前的文章中我们学习了多位数码管的倒计时,下面我们将对多位数码管对实际生活中的时间来进行显示,该功能的实现也并不复杂,将数码管知识相结合并运用起来,就可以完成一个属于自己的时钟了。
一、功能概述
实现对时间的计数我们需要用到单片机中的定时器模块,定时器的本质上就是每经过一个单片机自己机械周期就会加一的寄存器。定时器也可以是一个中断,当到达了给定时时间后就会执行相对应的程序。
了解了定时器的原理和使用方法,我们就可以选择我们需要的多位数码管来进行电路的设计了。
二、显示原理
既然我们需要现实的是时分秒的时间,那么我们可以选用六位的数码管,每两个数码管分别显示时、分、秒。而控制每一个数码管都需要段码线和选位线来控制,这样也节省了我们所需要使用的单片机IO口。
三、电路连接
使用Proteus进行电路图仿真:
四 、程序设计
程序代码:
#include< reg51.h >
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code num[10]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 0~9字码
uchar miao=0, fen=0, shi=0; //进位标志位
uint i=0; //计时
uchar miao_L, miao_H, fen_L, fen_H, shi_L, shi_H; //时、分、秒的个位(xxx_L)和十位(xxx_H)
void delay(uint x){ //延时函数
while(x--);
}
void T0_init(){ //定时器 0 初始化
TMOD = 0x01; //工作方式 1
TH0 = 0x3c; //高八位赋初值 65536-50000=15536 = 3cb0H
TL0 = 0xb0; //底八位赋初值
EA = 1; //开总中断
ET0 = 1; //开 T0 中断
TR0 = 1; //启动 T0
}
void display(){ //显示
P2 = 0x20; //秒与分间隔线
P0 = 0xbf;
delay(500);
P2 = 0x04; //分与时间隔线
P0 = 0xbf;
delay(500);
P2 = 0x80; //数码管位选 1000 0000
P0 = num[miao_L]; //秒个位
delay(500);
P2 = 0x40; //数码管位选 0100 0000
P0 = num[miao_H]; //秒十位
delay(500);
P2 = 0x10; //数码管位选 0001 0000
P0 = num[fen_L]; //分个位
delay(500);
P2 = 0x08; //数码管位选 0000 1000
P0 = num[fen_H]; //分十位
delay(500);
P2 = 0x02; //数码管位选 0000 0010
P0 = num[shi_L]; //分个位
delay(500);
P2 = 0x01; //数码管位选 0000 0001
P0 = num[shi_H]; //分十位
delay(500);
}
void main(){
T0_init(); //定时器初始化
while(1){
display(); //显示
}
}
void timer0_int() interrupt 1{ //中断服务函数
i++;
if(i == 20){
i = 0; //满一秒清零
miao++; //i = 100 为一,秒标志位加 1
if(miao == 60){
miao = 0; //满一分清零
fen++;
if(fen == 60){
fen = 0; //满一时清零
shi++;