基于Proteus学习单片机系列(五)——定时器实现电子表

获取更多资源,请关注微信公众号:嵌入式基地

获取项目资源:公众号后台回复:单片机仿真

基于Proteus学习单片机系列(一)——点亮LED

基于Proteus学习单片机系列(二)——驱动数码管

基于Proteus学习单片机系列(三)——按键

基于Proteus学习单片机系列(四)——中断

基于Proteus学习单片机系列(五)——定时器实现电子表

基于Proteus学习单片机系列(六)——I2C总线AT24C04

基于Proteus学习单片机系列(七)——实时时钟DS1302

基于Proteus学习单片机系列(八)——AD转换及其应用--TLC549

基于Proteus学习单片机系列(九)——DA转换及其应用--TLC5615

基于Proteus学习单片机系列(十)——LCD1602

基于Proteus学习单片机系列(十一)——LCD12864

项目下载

    点击下载

1. 电路图

  2. 程序

主函数

#include<reg51.h>
#include<DEFINE.c>
#include<KEY.c>
#include<DISPLAY.c>
void timer_isr()interrupt 1			  //中断服务函数
{
	TL0 = (65536-2000) %256;			  //TL0重置函数
	TH0 = (65536-2000)/256;			  //TH0重置函数
	cp++;
	if(cp>=250)       //0.5s
	{
		cp1++;
		cp = 0;
		flash = ~flash;        //0.5s  - 闪烁
		if(cp1>=2)    //1s
		{
			if(mode==0)		   //调整时,时间停止
			sec++;
			cp1 = 0;
			if(sec>=60)     //1min
			{
				min++;
				sec = 0;
				if(min>60)	 //1h
				{
					hour++;
					min = 0;
					if(hour>=24)hour = 0;
				}
			}
		}
	}
	P0 = 0xff;    //消隐
	switch(mode)
	{
		case 0:dis_play0();break;  //正常
		case 1:dis_play1();break;  //调时
		case 2:dis_play2();break;  //调分
		case 3:dis_play3();break;  //调秒
		case 4:dis_play4();break;  //调闹时
		case 5:dis_play5();break;  //调闹分
	}
	i++;
	if(i>=8)i = 0;	
}
void timer0_init()				   //中断初始化函数
{
	TMOD = 0x01;				  //方式一
	TL0 = (65536-2000)%256;		  //TL0 预置,65536十六进制低8位。
	TH0 = (65536-2000)/256;		  //TH0 预置,65536十六进制高8位。
	EA = 1;							//CPU中断开放 ,总中断打开
	ET0 = 1;						//定时计数器T0的溢出终端控制位,T0中断打开
	TR0 = 1;						//定时计数器T0的启停控制位,启动T0
}
void main()
{
	timer0_init();				   //timer0初始化,为中断做准备
	while(1)
	{
		key();
		if(hour == hour_n && min == min_n)	   //闹钟到时间,蜂鸣器响
		{
			P3_2 = !P3_2;
			delay(50);
		}
	}
 }

定义

#define uchar unsigned char;
#define uint unsigned int;
sbit key_set = P2^0;
sbit key_up = P2^1;
sbit key_down = P2^2;
sbit P3_0 = P3^0;
sbit P3_2 = P3^2; //蜂鸣器
sbit P2_4 = P2^4;
uchar sec = 45,min = 12,hour;
uchar sec_t,min_t,hour_t;
uchar min_n = 13,hour_n;
uchar cp,cp1;
uchar flash,mode,i;
code uchar seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
			0x82,0xf8,0x80,0x90};

 

按键函数

 

void delay(unsigned int x)	//延时函数
{
	while(x--);
}
void key()				   //按键函数
{
	P2_4 = 0;
	if(key_set==0)		   //如果调整按键按下
	{
		delay(300);		   //消抖
		if(key_set==0)	   //如果调整按键真的按下
		{
			while(key_set==0);
			mode++;
			if(mode>=6)mode = 0;   //mode=0,退出调整
			hour_t = hour;
			min_t = min;
			sec_t = sec;
		}
	}
	if(key_up==0)				  //如果增加按键按下
	{
		delay(300);				  //消抖
		if(key_up==0)			  //如果增加按键真的按下
		{
			while(key_up==0);
			if(mode==1)hour_t++;if(hour_t>24)hour_t = 23;hour = hour_t;
			if(mode==2)min_t++;if(min_t>60)min_t = 59;min=min_t;
			if(mode==3)sec_t++;if(sec_t>60)sec_t = 59;sec = sec_t;
			if(mode==4)hour_n++;if(hour_n>24)hour_n = 23;
			if(mode==5)min_n++;if(min_n>60)min_n = 59;

		}
	}
	if(key_down==0)				 //如果减小按键按下
	{							 
		delay(300);				 //消抖
		if(key_down==0)			 //如果减小按键真的按下
		{
			while(key_down==0);
			if(mode==1)hour_t--;if(hour_t<0)hour_t = 0;hour = hour_t;
			if(mode==2)min_t--;if(min_t<0)min_t = 0;min=min_t;
			if(mode==3)sec_t--;if(sec_t<0)sec_t = 0;sec = sec_t;
			if(mode==4)hour_n--;if(hour_n<0)hour_n = 0;
			if(mode==5)min_n--;if(min_n<0)min_n = 0;

		}
	}
}

显示函数

void display(unsigned char x1,x2)
{
	P3_0 = 0;	  //锁存器关
	P0 = x1;	  //输入位选			 
	P3_0 = 1;	  //锁存器开
	P3_0 = 0;	  //锁存器关
	P0 = x2;	  //输入段选		
}
void dis_play0()			  //mode = 0 正常  显示
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec%10]);break;	  //显示秒个位
		case 1:display(0x02,seven_seg[sec/10]);break;	  //显示秒十位
		case 2:display(0x04,0xbf|flash);break;			  //显示 -	  闪烁
		case 3:display(0x08,seven_seg[min%10]);break;	  //显示分个位
		case 4:display(0x10,seven_seg[min/10]);break;	  //显示分十位
		case 5:display(0x20,0xbf|flash);break;			  //显示 -    闪烁
		case 6:display(0x40,seven_seg[hour%10]);break;	  //显示时个位
		case 7:display(0x80,seven_seg[hour/10]);break;	  //显示时十位
	}
}
void dis_play1()			  //mode = 1 调时
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec_t%10]);break;	  //显示调秒个位
		case 1:display(0x02,seven_seg[sec_t/10]);break;	  //显示调秒十位
		case 2:display(0x04,0xbf);break;				  //显示 -
		case 3:display(0x08,seven_seg[min_t%10]);break;	  //显示调分个位
		case 4:display(0x10,seven_seg[min_t/10]);break;	  //显示调分十位
		case 5:display(0x20,0xbf);break;				  //显示 -
		case 6:display(0x40,seven_seg[hour_t%10]|flash);break;	 //显示调时个位	   闪烁
		case 7:display(0x80,seven_seg[hour_t/10]|flash);break;	 //显示调时十位	   闪烁
	}
}
void dis_play2()			  //mode = 2 调分
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec_t%10]);break;	  //显示调秒个位
		case 1:display(0x02,seven_seg[sec_t/10]);break;	  //显示调秒十位
		case 2:display(0x04,0xbf);break;				  //显示  -
		case 3:display(0x08,seven_seg[min_t%10]|flash);break;	  //显示调分个位   闪烁
		case 4:display(0x10,seven_seg[min_t/10]|flash);break;	  //显示调分十位   闪烁
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_t%10]);break;		  //显示调时个位
		case 7:display(0x80,seven_seg[hour_t/10]);break;		  //显示调时十位
	}
}
void dis_play3()			  //mode = 3 调秒
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec_t%10]|flash);break;	  //显示调秒个位  闪烁
		case 1:display(0x02,seven_seg[sec_t/10]|flash);break;	  //显示调秒十位  闪烁
		case 2:display(0x04,0xbf);break;						  //显示 -
		case 3:display(0x08,seven_seg[min_t%10]);break;			  //显示调分个位
		case 4:display(0x10,seven_seg[min_t/10]);break;			  //显示调分十位
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_t%10]);break;		  //显示调时个位
		case 7:display(0x80,seven_seg[hour_t/10]);break;		  //显示调时十位
	}
}		
void dis_play4()			  //mode = 4 调闹时
{
	switch(i)
	{
		case 0:display(0x01,0xbf);break;						  //显示 -
		case 1:display(0x02,0xbf);break;						  //显示 -
		case 2:display(0x04,0xbf);break;						  //显示 -
		case 3:display(0x08,seven_seg[min_n%10]);break;			  //显示闹分个位
		case 4:display(0x10,seven_seg[min_n/10]);break;			  //显示闹分十位
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_n%10]|flash);break;	  //显示闹时个位    闪烁
		case 7:display(0x80,seven_seg[hour_n/10]|flash);break;	  //显示闹时十位    闪烁
	}
}
void dis_play5()			  //mode = 5 调闹分
{
	switch(i)
	{
		case 0:display(0x01,0xbf);break;						  //显示 -
		case 1:display(0x02,0xbf);break;						  //显示 -
		case 2:display(0x04,0xbf);break;						  //显示 -
		case 3:display(0x08,seven_seg[min_n%10]|flash);break;	  //显示闹分个位    闪烁
		case 4:display(0x10,seven_seg[min_n/10]|flash);break;	  //显示闹分十位	闪烁
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_n%10]);break;		  //显示闹时个位
		case 7:display(0x80,seven_seg[hour_n/10]);break;		  //显示闹时十位
	}
}

 

 

 

  • 8
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32单片机是一种高性能、低功耗的32位微控制器,广泛应用于嵌入式系统的开发中。其原理是基于ARM Cortex-M系列的核心,具有丰富的外设和高性能的计算能力,可以实现多种功能。 STM32单片机的应用非常广泛。其可以应用于智能家居、医疗仪器、工业自动化等领域。它可以用来控制各种传感器,如温度传感器、湿度传感器等,实现对环境的监测和控制。同时,它也可以用于控制各种执行机构,如电机和执行器,实现对设备的控制和运动。此外,STM32单片机还可以应用于通信领域,如无线模块和网络模块的控制,实现设备之间的数据传输和通信。 基于Proteus的虚拟仿真可以帮助开发者在进行STM32单片机的开发过程中,不需要实际搭建硬件电路,即可进行软件开发和调试。Proteus是一款功能强大的虚拟仿真软件,可以模拟STM32单片机和外设的工作过程。它可以提供丰富的模型库和仿真环境,方便开发者进行程序的编写、调试和验证。 通过Proteus的虚拟仿真,开发者可以在电脑上实现对STM32单片机的全面测试,包括外设的连接和数据交互。开发者可以使用Proteus提供的虚拟示波器、虚拟显示器等工具,模拟实际硬件的工作状态,及时查看和调试程序。 总而言之,STM32单片机的原理和应用非常广泛,通过Proteus的虚拟仿真可以帮助开发者在进行STM32单片机的开发过程中,提高开发效率和减少成本,并且可以更好地进行软件开发和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点灯师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值