51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示

这篇具有很好参考价值的文章主要介绍了51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

功能效果:1.时分秒的动态显示。2.用三个按键实现时分秒的修改,调节的数字闪烁提示。

一、仿真图:

51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示 

51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示文章来源地址https://www.toymoban.com/news/detail-502007.html

 二、源码

版本一:

#include <reg52.h>

#define u8 unsigned char
#define u16 unsigned int	

u8 WeiMa[6]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
u8 DuanMa[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//函数声明
void Delay_ms(u16 xms);
void ShuMaGuan(u8 wei,u8 duan);
void Display_Timer(u8 hour,u8 min,u8 sec);
u8 Key_Scan();

//引脚定义
sbit SW1=P3^2;
sbit SW2=P3^3;
sbit SW3=P3^4;

//函数功能:定时器初始化
void Time0init()
{
	TMOD|=0x01;				//设置定时器模式
	TF0=0;					//清除TF0标志
	TH0=(65536-50000)/256;  //设置定时初值
	TL0=(65536-50000)%256;	//设置定时初值
	TR0=1;					//定时器0允许计时
	ET0=1;					//中断允许
	EA=1;					//CPU中断允许位打开
}

u8 Hour,Min,Sec;//全局变量,时分秒
u8 mode;//全局变量:状态切换,0:时钟显示,1:调节时;2:调节分;3:调节秒
bit flash_tip=1;//数码管闪烁标志,为0时数码管熄灭,为一时数码管显示

//主函数
void main()
{
	u8 keynum;
	Time0init();//定时器
	Hour=0;
	Min=0;
	Sec=0;
	mode=0;//初始化
	while(1)
	{
		keynum=Key_Scan();//按键返回值
		if(keynum)   //非0表示有按键按下
		{
			switch(keynum)  //判断是哪个按键按下,按键一调节模式,按键2自加,按键3自减
			{
				case 1:if(++mode>=4) mode=0;break;  //++mode为先自增再判断是否大于4
				case 2:
					if(mode==1) 
					{
						Hour++;
						if(Hour>=24)//溢出判断
						{
							Hour=0;
						}
					}
					if(mode==2) 
					{
						Min++;
						if(Min>=60)//溢出判断
						{
							Min=0;
						}
					}
					if(mode==3) 
					{
						Sec++;
						if(Sec>=60)//溢出判断
						{
							Sec=0;
						}
					}
					break;										
				case 3:
					if(mode==1) 
					{
						Hour--;
						if(Hour==255)//溢出判断
						{
							Hour=23;
						}
					}
					if(mode==2) 
					{
						Min--;
						if(Min==255)//溢出判断
						{
							Min=59;
						}
					}
					if(mode==3) 
					{
						Sec--;
						if(Sec==255)//溢出判断
						{
							Sec=59;
						}
					}
					break;
				default:break;
			}
		}
		Display_Timer(Hour,Min,Sec);//数码管显示
	}
}

//软件延时函数
//xms为延时多少毫秒
void Delay_ms(u16 xms)
{
	
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 135;
		do
		{
			while (--j);
		} while (--i);
	}
}

//静态显示一位
//参数:wei控制位选duan控制段选,表示要显示的一个数字
void ShuMaGuan(u8 wei,u8 duan)
{
	P1=WeiMa[wei];    //位选
	P2=DuanMa[duan];  //段选
	Delay_ms(1); //间隔一段时间扫描
	P1=0xFF;    
	P2=0xFF;	   //消隐
}


//函数功能:数码管动态显示
//flash_tip为数码管闪烁标志,为0时数码管熄灭,为一时数码管显示
//flash_tip每4.5秒进行取反
void Display_Timer(u8 hour,u8 min,u8 sec)
{
	if(mode!=1 || flash_tip==1) //mode=1时,左边的条件一直为假,当flash_tip=1时,或运算为真,进入if,数码管显示
	{
		ShuMaGuan(5,hour/10);
		ShuMaGuan(4,hour%10);
	}
	else P1=0xFF;
	
	
	if(mode!=2 || flash_tip==1)//mode=2时,左边的条件一直为假,当flash_tip=1时,或运算为真,进入if,数码管显示
	{
		ShuMaGuan(3,min/10);
		ShuMaGuan(2,min%10);
	}
	else P1=0xFF; 
	
	
	if(mode!=3 || flash_tip==1)//mode=3时,左边的条件一直为假,当flash_tip=1时,或运算为真,进入if,数码管显示
	{
		ShuMaGuan(1,sec/10);
		ShuMaGuan(0,sec%10);
	}
	else P1=0xFF;  
}


//独立按键检测
u8 Key_Scan()
{
	static u8 key_up=1; //按键按松开标志
	if(key_up && (SW1==0 || SW2==0 || SW3==0))
	{
		Delay_ms(10); //去抖动
		key_up=0; //松手标志为0,那么下次再检测,if结果为0,则不会进入这里的语句
		if(SW1==0) return 1;
		if(SW2==0) return 2;
		if(SW3==0) return 3;
	}
	else if(SW1 == 1 && SW2 == 1 && SW3 == 1) key_up=1; //松手标志
	return 0; // 无按键按下
}

//定时器中断服务函数
void Time0() interrupt 1
{
	static unsigned char flag_1,flag_2; 
	TH0=(65536-50000)/256;  
	TL0=(65536-50000)%256;//重新赋初值
	
	if(mode==0)flag_1++;  //mode为0时,数码管正常显示
	else flag_2++;   
	
	if(flag_1==20 && mode==0)  //每秒执行一次
	{
		flag_1=0;
		Sec++;
		{
			if(Sec>=60)
			{
				Sec=0;
				Min++;
				if(Min>=60)
				{
					Min=0;
					Hour++;
					if(Hour>=24)
					{
						Hour=0;
					}
				}
			}
		}
	}
	if(flag_2==9)
	{
		flash_tip=~flash_tip;//每4.5秒进行取反
		flag_2=0;
	}

}

版本二:

#include <reg52.h>

#define u8 unsigned char
#define u16 unsigned int	

u8 WeiMa[6]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
u8 DuanMa[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//函数声明
void Delay_ms(u16 xms);
void ShuMaGuan(u8 wei,u8 duan);
void Display_Timer(u8 hour,u8 min,u8 sec);
u8 Key_Scan();

//引脚定义
sbit SW1=P3^2;
sbit SW2=P3^3;
sbit SW3=P3^4;

//函数功能:定时器初始化
void Time0init()
{
	TMOD|=0x01;				//设置定时器模式
	TF0=0;					//清除TF0标志
	TH0=(65536-50000)/256;  //设置定时初值
	TL0=(65536-50000)%256;	//设置定时初值
	TR0=1;					//定时器0允许计时
	ET0=1;					//中断允许
	EA=1;					//CPU中断允许位打开
}

u8 Hour,Min,Sec;//全局变量,时分秒
u8 mode;//全局变量:状态切换,0:时钟显示,1:调节时;2:调节分;3:调节秒
bit flash_tip=1;//数码管闪烁标志,为0时数码管熄灭,为一时数码管显示

//主函数
void main()
{
	u8 keynum;
	Time0init();//定时器
	Hour=0;
	Min=0;
	Sec=0;
	mode=0;//初始化
	while(1)
	{
		keynum=Key_Scan();//按键返回值
		if(keynum)   //非0表示有按键按下
		{
			switch(keynum)  //判断是哪个按键按下,按键一调节模式,按键2自加,按键3自减
			{
				case 1:if(++mode>=4) mode=0;break;  //++mode为先自增再判断是否大于4
				case 2:
					if(mode==1) if(++Hour>=24) Hour=0;//++mode为先自增再判断是否大于4
					if(mode==2) if(++Min>=60) Min=0;//++Min先自增再判断是否大于60
					if(mode==3) if(++Sec>=60) Sec=0;//++Sec先自增再判断是否大于60
					break;										
				case 3:
					if(mode==1)	if(--Hour==255) Hour=23;//--Hour先自增再判断是否溢出
					if(mode==2) if(--Min==255) Min=59;//--Min先自增再判断是否大溢出
					if(mode==3) if(--Sec==255) Sec=59;//--Sec先自增再判断是否大溢出
					break;
				default:break;
			}
		}
		Display_Timer(Hour,Min,Sec);
	}
}

//软件延时函数
//xms为延时多少毫秒
void Delay_ms(u16 xms)
{
	
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 135;
		do
		{
			while (--j);
		} while (--i);
	}
}

//静态显示一位
//参数:wei控制位选duan控制段选,表示要显示的一个数字
void ShuMaGuan(u8 wei,u8 duan)
{
	P1=WeiMa[wei];    //位选
	P2=DuanMa[duan];  //段选
	Delay_ms(1); //间隔一段时间扫描
	P1=0xFF;    
	P2=0xFF;	   //消隐
}


//函数功能:数码管动态显示
//flash_tip为数码管闪烁标志,为0时数码管熄灭,为一时数码管显示
//flash_tip每4.5秒进行取反
void Display_Timer(u8 hour,u8 min,u8 sec)
{
	if(mode!=1 || flash_tip==1) //mode=1时,左边的条件一直为假,当flash_tip=1时,或运算为真,进入if,数码管显示
	{
		ShuMaGuan(5,hour/10);
		ShuMaGuan(4,hour%10);
	}
	else P1=0xFF;
	
	
	if(mode!=2 || flash_tip==1)//mode=2时,左边的条件一直为假,当flash_tip=1时,或运算为真,进入if,数码管显示
	{
		ShuMaGuan(3,min/10);
		ShuMaGuan(2,min%10);
	}
	else P1=0xFF; 
	
	
	if(mode!=3 || flash_tip==1)//mode=3时,左边的条件一直为假,当flash_tip=1时,或运算为真,进入if,数码管显示
	{
		ShuMaGuan(1,sec/10);
		ShuMaGuan(0,sec%10);
	}
	else P1=0xFF;  
}


//独立按键检测
u8 Key_Scan()
{
	static u8 key_up=1; //按键按松开标志
	if(key_up && (SW1==0 || SW2==0 || SW3==0))
	{
		Delay_ms(10); //去抖动
		key_up=0; //松手标志为0,那么下次再检测,if结果为0,则不会进入这里的语句
		if(SW1==0) return 1;
		if(SW2==0) return 2;
		if(SW3==0) return 3;
	}
	else if(SW1 == 1 && SW2 == 1 && SW3 == 1) key_up=1; //松手标志
	return 0; // 无按键按下
}

//定时器中断服务函数
void Time0() interrupt 1
{
	static unsigned char flag_1,flag_2; 
	TH0=(65536-50000)/256;  
	TL0=(65536-50000)%256;//重新赋初值
	
	if(mode==0)flag_1++;  //mode为0时,数码管正常显示
	else flag_2++;   
	
	if(flag_1==20 && mode==0)  //每秒执行一次
	{
		flag_1=0;
		if(++Sec>=60) //++Sec先自增再判断是否大于60  
		{
			Sec=0;
			if(++Min>=60)//++Min先自增再判断是否大于60
			{
				Min=0;
				if(++Hour>=24)//++Hour先自增再判断是否大于60
				{
					Hour=0;
				}
			}
		}
	}
	if(flag_2==9)
	{
		flash_tip=~flash_tip;//每4.5秒进行取反
		flag_2=0;
	}

}

到了这里,关于51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机入门————数码管显示

    我们在马路上看到的红绿灯,就是由数码管来实现的,就是其中可能加入了一些延时和转换 数码管是通过控制138译码器与74HC245来控制数码管的亮灭与数字的显示 我们先讨论一个数码管 数码管有共阳极和共阴极,我们现在使用的STC89C52是共阴极的,说明数码管共用阴极 上面是

    2024年02月13日
    浏览(44)
  • 51单片机矩阵键盘——数码管显示

    当我们熟悉了数码管的位选与段选,并了解的矩阵键盘的扫描之后就可以编写程序了。 按下矩阵键盘S1并松开,数码管第一位(LED8)显示0;按下矩阵键盘S2并松开,数码管第一位显示1;...按下矩阵键盘S16并松开,数码管第一位显示F; 矩阵键盘扫描(输入扫描)     原理:

    2024年02月11日
    浏览(55)
  • 51单片机控制数码管动态显示

    首先打开proteus,导入8位数码管和89c51。 然后如图连线,分清断码和位码, 断码就是一个数码管的7个LED灯。 位码:就是第几位显示,由于是共阴极,所以哪位接地就显示哪位。 下面通过改变位码的接线就可以看出不同的效果 下面就编写程序,从第1位到第8位显示从0到7的八

    2023年04月21日
    浏览(46)
  • 51单片机数码管显示0-9

    初级代码:使用延时函数,延时; 进阶代码:使用定时器,延时:51单片机定时器控制数码管显示_学习笔记吧的博客-CSDN博客 初级代码: 电路接线图:  

    2024年02月12日
    浏览(40)
  • 【51单片机】矩阵按键实现数码管显示

    闲的没事看一看玩一玩········· 矩阵按键 数码管是一种导体发光器件,其基本单元是发光二极管。按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管 共阴极数码管是指将所有发光二极管的阴极接到一起形成共阴极的数码管,共阴极的数码管在应用时将公共

    2024年02月02日
    浏览(59)
  • 51单片机动态数码管显示自己学号

    实验题目:使用51单片机实现动态数码管显示自己8位学号,例如20220018 在此原理图又分两种连接方式: 第一种是8位数码管接38译码器来减少端口使用。 第二种是,没有端口要求接好就可以那就是,把位选端接P3口,段选端接P0口,这样占用端口多,一般实验都是使用第一种接

    2024年02月13日
    浏览(57)
  • 【51单片机-数码管】:用51单片机写一个八个数码管中选用任意相邻两个数码管,用来循环显示0-99之间的数据,数据显示间隔为0.5s

             用普中51单片机写一个八个数码管中选用任意相邻两个数码管,用来循环显示0-99之间的数据,数据显示间隔为0.5s。         随机数码管 00-99  循环0.5s  显示。        数码管是一种数字显示器件,它由多个发光二极管(LED)组成,可以显示数字、字母、符号等

    2024年02月07日
    浏览(54)
  • 51单片机按键控制数码管显示0-9

    实验题目:使用51单片机设计两个按键控制数码管显示0-9,当K1按下减1,当K2按下加1. 理解程序可参考我的另外两个文章; 51单片机数码管显示0-9_学习笔记吧的博客-CSDN博客 51单片机独立按键控制合集_学习笔记吧的博客-CSDN博客 两个文章一结合就是一个新的产物,所以51单片机

    2024年02月11日
    浏览(52)
  • 【51单片机实验笔记】2. 数码管的基本控制

    本节内容我们学习如何控制 数码管 ,先尝试点亮一个 数码管 ,并实现 倒计时 效果。 本节涉及到的 封装源文件 可在《模块功能封装汇总》中找到。 本节 完整工程文件 已上传 GitHub ,仓库地址,欢迎下载交流! 数码管 的英文为 Nixie Tube ,又称 辉光管 或 LED数码管 。其基

    2023年04月23日
    浏览(100)
  • 51单片机入门教程(3)——数码管显示学号

    目录 1、数码管简介 2、静态显示 3、动态显示 4、小结 相信经过了流水灯的实现,大家已经弄清楚了Keil和Proteus是如何联动使用的,并且对51单片机也有了一定的认识,在这一章里,我带大家利用51单片机玩下数码管,看最终你们能不能把自己的学号显示出来。 LED数码管(LE

    2023年04月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包