51单片机利用锁存器控制数码管显示年月日时分秒

发布者:GoldenSunrise最新更新时间:2022-06-28 来源: eefocus关键字:51单片机  锁存器控制  数码管显示 手机看文章 扫描二维码
随时随地手机看文章

数码管模块中的两片74hc573,一片锁存段码,一片锁存位码,这样才能驱动8位数码管。74hc573是锁存器,用于数码管显示时通常是采用段选、片选共用同一组并口的驱动方式。


驱动数码管需要两个信号,一个是段选信号,另一个是片选信号。段选信号是固定的8个(对于普通7段数码管),而片选信号数量是与数码管位数相同的。


对于8位数码管的动态扫描来说,片选信号要8根线,这样仅仅驱动数码管就占用了16个IO口,非常浪费。


原理

使用573锁存器后,只占用10个IO口,其中2个用于控制锁存器使能,另外8个用于输出信号。先关闭控制片选信号的573芯片的锁存功能,然后单片机输出片选信号。随后再开启锁存,此时无论573的输入端如何变化,输出端都是不变的,也就是原来输入的信号被锁住了。然后再关闭控制段选的573的锁存功能,输出段选信号再锁存,这样就巧妙地实现了数据线的复用,让一组IO口既输出段选又输出片选。

由于数码管数量有限,时分秒与年月日将隔两秒分别显示。


#include

#include

char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

 

sbit duan=P3^7;

sbit wei=P3^6;

 

 

void delay(int t)

{

int x,y;

 

for(x=t;x>0;x--)

for(y=10;y>0;y--);

}

void nop()

{

_nop_();

_nop_();

}

 

//这几个变量是全局变量,主要用在主函数中

//不会影响到disp函数中的几个变量

int  abc,time,num,sec,min,hour;

 

/*************************************************

*该函数的功能作用是在开发箱的数码管显示时分秒

*开发箱上面的数码管从左往右是第0位到第7位

*在选择第几位的时候就给P1赋值2的第几位次方

*比如,显示在数码管的第3位,就给P1赋值2的3次方也就是8这个数值

***********************************************32***/

void disp(int sec, int min, int hour)

{

 

duan=0;

P1=table[hour/10];//显示时间的十位

duan=1;

duan=0;

    

wei=0;

P1=1;//显示在数码管的第0位。2的0次方等于1

wei=1;

wei=0;

delay(10);

 

 

 

duan=0;

P1=table[hour%10];//显示时间的个位

duan=1;

duan=0;

     

wei=0;

P1=2;//显示在数码管的第1位。2的1次方等于2

wei=1;

wei=0;

delay(10);

 

 

P1=table[min/10];//显示分钟的十位

duan=1;

duan=0;

       

P1=4;//显示在数码管的第2位。2的2次方等于4

wei=1;

wei=0;

delay(10);

 

 

P1=table[min%10];//显示分钟的个位

duan=1;

duan=0;

       

P1=8;//显示在数码管的第3位。2的3次方等于8

wei=1;

wei=0;

delay(10);

 

 

 

P1=table[sec/10];//显示秒钟的十位

duan=1;

duan=0;

       

P1=16;//显示在数码管的第4位。2的4次方等于16

wei=1;

wei=0;

delay(10);

 

P1=table[sec%10];//显示秒钟的个位

duan=1;

duan=0;

       

P1=32;//显示在数码管的第5位。2的5次方等于32

wei=1;

wei=0;

delay(10);

}//100

 

int year,month,date;

 

void disp2()

{

duan=0;

P1=table[year/1000];//显示年的千位

duan=1;

duan=0;

    

wei=0;

P1=1;//显示在数码管的第0位。2的0次方等于1

wei=1;

wei=0;

delay(10);

 

 

 

duan=0;

P1=table[year%1000/100];//百位

duan=1;

duan=0;

     

wei=0;

P1=2;//显示在数码管的第1位。2的1次方等于2

wei=1;

wei=0;

delay(10);

 

 

P1=table[year%100/10];//十位

duan=1;

duan=0;

       

P1=4;//显示在数码管的第2位。2的2次方等于4

wei=1;

wei=0;

delay(10);

 

 

P1=table[year%10];//个位

duan=1;

duan=0;

       

P1=8;//显示在数码管的第3位。2的3次方等于8

wei=1;

wei=0;

delay(10);

 

 

 

P1=table[month/10];//显示月的十位

duan=1;

duan=0;

       

P1=16;//显示在数码管的第4位。2的4次方等于16

wei=1;

wei=0;

delay(10);

 

P1=table[month%10];//显示月的个位

duan=1;

duan=0;

       

P1=32;//显示在数码管的第5位。2的5次方等于32

wei=1;

wei=0;

delay(10);

 

P1=table[date/10];//显示日期的十位

duan=1;

duan=0;

       

P1=64;//显示在数码管的第6位。2的6次方等于64

wei=1;

wei=0;

delay(10);

 

P1=table[date%10];//显示日期的个位

duan=1;

duan=0;

       

P1=128;//显示在数码管的第7位。2的7次方等于128

wei=1;

wei=0;

delay(10);

 

}

int show_flag = 0,show_time = 0;

 

void main (void)

{

//

 

/*定时器0初始化,定时时间50毫秒*/

TMOD=0x01;//定时器方式寄存器

TR0=1;//T0定时器/计数器的运行控制位

ET0=1;//中断允许寄存器中T0定时器/计数器的允许

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

 

EA=1;//中断控制的    总允许

/*********/

//时间初始化

year = 2021;

month = 5;

date = 24;

hour = 10;

min = 30;

sec = 50;

 

 

while(1) 

{

  if(sec==60)

{

sec=0;

min++;

if(min==60)

{

min=0;

hour++;

if(hour==24)

{

hour=0;

date++;

if((month==4 || month==6 || month == 9 || month == 11) && date==31)

{

month++;

date = 1;

}

else if(month == 2)

{

//判断年是否为闰年,以此来判断date是28+1进1还是29+1进一

}

else if(month==1 || month==3 || month == 5 || month == 7|| month == 8 || month == 10 || month == 12) && date==32)

{

month++;

date = 1;

}

 

}

}

}

 

//每隔两秒切换一次显示

if(show_flag == 0)

    disp(sec,min,hour);//显示时分秒

  else

disp2();//显示年月日

 

    }

}

//定时器0的中断服务函数,不需要主动调用

void time0() interrupt 1

{

 

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

time++;

//定时一次50毫秒,20次后是1秒,秒数+1

if(time==20)

{

 

  time=0;

show_time++;

sec++;

//每隔两秒改变show_flag的值,如果要修改切换的时间,修改下面的2为其他整数就好

if(show_time%2 ==0)

{

show_flag = !show_flag;

}

}


}


关键字:51单片机  锁存器控制  数码管显示 引用地址:51单片机利用锁存器控制数码管显示年月日时分秒

上一篇:矩阵式键盘扫描,单片机扫描按键是否被按下
下一篇:keil编译后生成的M51文件解析

推荐阅读最新更新时间:2024-11-13 07:31

51单片机(AT89C52)一键多功能(短按、长按)
短按(按下持续时间小于3s)一次数码管显示加1,同时流水灯计数加1。 长按(按下持续时间大于3s)时,数码管显示每500ms加1,同时流水灯每500ms计数加1。 #include reg52.h typedef unsigned char uchar; typedef unsigned int uint; #define NOKEY 0 #define KEYDOWN 1 #define KEYUP 2 uchar keystate; sbit key=P2^7; void keyscan(void); uchar timeflag; uchar code table = { 0x80,0xf2,0x48,0x60,
[单片机]
基于51单片机的交通灯控制系统课程设计
一、设计要求: 1,十字路口的交通控制系统指挥着人和各种车辆的安全运行,对交叉口实行科学的管理与控制是交通控制工程的重要研究课题,是保障交叉口的交通安全和充分发挥交叉口的通行能力的重要措施,是解决城市交通问题的有效途径。交通灯信号灯的出现是人类历史上的一次重大改革,使人类的聚居生活,产生了深远的影响。使交通得以有效管制,对于疏导交通流量,提高道路通行能力,减少交通事故有明显效果。如何采用合适的控制方法,最大限度利用好耗费巨资修建的城市高速道路,缓解主干道与匝道、城区同周边地区的交通拥堵状况,越来越成为交通运输管理和城市规划部门亟待解决的主要问题。随着电子技术的发展,利用单片机技术对交通灯进行智能化管理,已成为目前广泛采用的方法。
[单片机]
基于<font color='red'>51单片机</font>的交通灯<font color='red'>控制</font>系统课程设计
51单片机驱动YL-69土壤湿度传感器
YL-69的资料内程序有51单片机和Arduino的测试程序,我用的是51的程序。先说我的模块吧,四线制的,如果你买的是三线制的也没关系,看完就懂。 VCC GND的连线就不说了。 DO —— 自己定于一个IO口,程序定义的是 key1=P0^1 , AO —— J9 4 (AIN1) 这个要对照单片机原理图自己找 模拟量转数字量,用于LCD1602 显示准确数值(显示的是电压值,具体湿度要自己定义) 测试AO的时候我发现如果接上DO,LCD显示会出错,所以我接了AO线就会拔掉DO线,其实就是两种模式二选一就好了。 我从卖家那里获得的资料程序很简单,其程序单纯用于判断 干 或 湿。我加了个LED灯亮灭,也
[单片机]
<font color='red'>51单片机</font>驱动YL-69土壤湿度传感器
51单片机学习过程记录】7 中断之 定时计数器0 操作前理解
声明:【51单片机学习过程记录】全是我自己学习、实践所记录的过程,我只是菜鸟,所有论点和观点仅代表我个人,不能确定是这个技术的真理。我的目的是学习和有可能成为可以向别人分享的经验,因此有错误我会虚心接受,并认真改正。 1 由数据手册可知,89c52rc单片机有六个中断,分别为 外部中断0 外部中断1定时计数器0 定时计数器1定时计数器2 以及串口中断,一共六个。 2 如何理解继而操作定时器0? A大概了解:定时器,其实就是单片机的机器周期计数器,工作原理就是 当给计数器设定初始值并开启后,定时计数器会自动计算,到达设定的时间后会产生中断。(当然,更详细还是需要专门查看定时计数器去深入了解) B操作:需要参考另外一个
[单片机]
【<font color='red'>51单片机</font>学习过程记录】7 中断之 定时计数器0 操作前理解
51单片机定时器工作方式1、2原理详解
写在前面 1.本篇博文旨在帮助那些像我一样刚入门51单片机,如果你对定时器有一定了解,但是其中的的工作方式不能理解,那么这篇文章很适合你,如果你是大神的话…直接绕行吧…… 2.我在学习的过程中由于知识上的不足很多的讲解看不懂,在翻找了许多资料真正理解之后,打算以一种简单易懂的方式进行解释,这是一份很 详尽基础 的讲解手册。 3.全文以定时器0为例,定时器1的用法与其相同。 4.由于是讲定时器实现原理,文章文字显得较多,不过都是很简单的文字,只要认真看都能看得懂。 知识填充 虽然看懂这篇博文不需要太多的知识储备,但是在这里还是做一个简单的知识普及,便于下文的讲解 4位二进制数可以和1位十六进制数相互转化,如二进制
[单片机]
51单片机1s延时程序设计
#include sbit P1_0 = P1^0; void Delay(); // 下面引用时一定要和这里的大小写一致否则会有警告或错误 void Main() { while (1) // 开始一直循环 { P1_0 = 0; Delay(); // 没有参数也要加 () 否则会有Warning P1_0 = 1; Delay(); } } void Delay() // 12M晶振1s延时 { unsigned char h, i, j, k; for (h = 5; h 》 0; h--) for (i = 4; i 》 0; i--) for (j = 116; j 》 0; j--) for (k = 214;
[单片机]
<font color='red'>51单片机</font>1s延时程序设计
51单片机驱动ADC0832模数转换程序-lcd1602显示
/*这个芯应用不多*/ #include reg51.h #define uchar unsigned char #define uint unsigned int uchar Chan0Value,Chan1Value; sbit RS=P1^0; //1602各控制脚 sbit RW=P1^1; sbit EN=P1^2; sbit Cs0832= P2^0; //0832各控制脚 sbit Clk0832= P3^6; sbit Di0832= P3^7; sbit Do0832= P3^7; void delay1ms(unsigned int ms)//延时1毫秒(不够精确的) { int i,j; for(
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved