历史上的今天
今天是:2025年04月11日(星期五)
2020年04月11日 | 基于51单片机的电子时钟(数码管显示)
2020-04-11 来源:eefocus
此次对于数码管进行一个简单的应用,同时可以设计一个电子小时钟,增加趣味性。
首先我们先进行原理图的讲解,这里我们直接使用的开发板,其原理连接图如下:


其中D(0~1)是连接在单片机的P0口上的。
从图中,我们可以看到,第一个74HC573是来控制8个数码管的位选的,就是说我要选种哪个数码管,这里的WE是低电平有效,比如说我想选中最后一个数码管,那么这里我就要将0x7f送到相应的I/O口。第二个74HC573是来控制数码管显示什么的这里0~9的16进制码如下:
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;
要想完成电子时钟,我们先要显示一个数值,
这里我们封装两个函数:
wirte_address(unsigned char);
write_date(unsigned int);
第一个函数是用来写地址的,就是用来选中数码管的;
第二个函数是用来写数据的,就是选中的数码管显示什么。
比如我们想在最后一个数码管上显示一个8;
那么则有:
write_address(0x7f);
write_date(0x7f);
这样就能在相应的位置上显示一个8了;
然后我们就要多个位置显示,这里我们硬件的P0口接的是数码管,同时我们要引进相应的延时函数delay(unsigned int);
我们利用发光管的余辉和人眼视觉暂留作用,让人眼无法分辨出来,从而达到“同时显示的效果”。
但是我们需要注意的是消影,在每次写入之前令P0=0xff,这是为了消除上次段选数据,否则会造成,显示混乱。
当我们能显示时,就需要了解定时器,让它来计时,然后将数值取出,进行显示。这里我们的晶振是12MHz,所以一个机械周期时1/12MHz=1us,为了使计时较为精确,我们这里选择定时器0的模式2,8位重装定时器,并且我们100us进入一次中断,定时器的初始化就该如下:
TMOD=0x02;
TH0=256-100;
TL0=256-100;
EA=1;
ET0=1;
TR0=1;
这样我们再定义一个n用来计数进入中断的次数,当n的10000时,就表示1s到了,所以我们需要对相应的变量进行处理。
那么我们需要对数据进行处理,比如,所得的秒的值,其十位=秒/10,其个位就等于秒%10,其它以此类推。
那么整个的程序代码如下:
#include #define uint unsigned int #define uchar unsigned char uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管位选数据 sbit dula=P2^6;//段选信号,写数码管数据 sbit wela=P2^7;//位选信号,选择数码管 uint miao=0; //秒 uint fen=0; //分 uint shi=0; //时 uint n=0; //计数 uint date[6]={0,0,0,0,0,0}; //定义一个有6个地址的数组,分别存时,分,秒的个位和十位。 void delay(uint z) //延时函数 { uint x,y; for(x=z;x>0;x--) for(y=50;y>0;y--); } void write_address(uchar address) //写地址函数,选择数码管 { wela=1; P0=address; wela=0; } void write_date(uint n) //写数据函数,送入段选信号 { dula=1; P0=table[n]; dula=0; } //显示函数 void display() { write_date(date[0]); P0=0xff; write_address(0x7f); delay(1); write_date(date[1]); P0=0xff; write_address(0xbf); delay(1); write_date(date[2]); P0=0xff; write_address(0xef); delay(1); write_date(date[3]); P0=0xff; write_address(0xf7); delay(1); write_date(date[4]); P0=0xff; write_address(0xfd); delay(1); write_date(date[5]); P0=0xff; write_address(0xfe); delay(1); } void time_init() //定时器初始化函数 { TMOD=0x02; //选择方式2 TH0=156; //重装初值为156 TL0=156; //运行值为156 EA=1; //开总中断 ET0=1; //开定时器0中断 TR0=1; //开定时器0 } void main() { dula=0; //先关闭位选,段选信号。 wela=0; time_init(); while(1) { display(); } } void timer() interrupt 1 //定时器0中断 { n++; if(n==10000) //当n=10000时,表示1s到了 { n=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; } } } date[0]=miao%10; date[1]=miao/10; date[2]=fen%10; date[3]=fen/10; date[4]=shi%10; date[5]=shi/10; } } 其效果图如下:

上一篇:51单片机开发中数码管显示与应用
下一篇:51单片机一位数码管汇编程序
史海拾趣
|
我用tlc4502搭了个积分电路,但是发现输出端1脚一直为电源电压。我以为是输出饱和,于是在电容两端并联大电阻,但是电阻从200K一直增加到40M输出端也没有变化。另外,当我去掉输入信号时,反相端2脚和正向端3脚电压不相等,3脚为偏置2.5V,而2脚还 ...… 查看全部问答> |
|
简单实用声控电子门铃电路 利用本电路作为门铃时,不需在门前安装按钮开关,来客只需叩一下大门,门铃便会发声。电路如图所示。 电路最大的特点就是利用扬声器做振动输入,又做门铃声输出。 晶体管V2、电位器KP和 ...… 查看全部问答> |
|
刚买了一块飞凌公司的ok2440iii开发板,手上有一本韦东山编的嵌入式linux应用开发完全手册,一本c++入门的书籍,刚在电脑上面装上了ubuntu10.04的虚拟系统。想往人机交互qt的方向发展,不过发现困难重重,首先就是arm的汇编指令还有makefile里面的 ...… 查看全部问答> |
|
我用INA128测信号,那个信号频率不定,范围从0~500Hz,INA128一般要接一个电阻,就是那个决定放大倍数的电阻,当我接100K或者是不接的时候,也就是放大倍数很小的时候,输出有波形,但是当我接小于20K的电阻时(高一点的放大倍数),那个就没 ...… 查看全部问答> |
|
手头有个项目需要压力、流量、密度变送器和电控阀门。 工作压力最大10Mpa,介质是水泥浆,有弱腐蚀性。压力变送器要求精度达到0.1%,流量变送器达到0.25%。实施现场情况比较恶劣,高温(最高70°)、高湿(水花四溅),灰尘比较多(伸手不见六指) ...… 查看全部问答> |




