51单片机定时报警器小设计

如需要源文件可以添加qq群聊获取:662177587

概要

实际设计图

设计内容

设计一个单片机控制的简易定时报警器。要求根据设定的初始值(1-59秒)进行倒计时,当计时到0时数码管闪烁“00”(以1Hz闪烁),按键功能如下:

(1)设定键:在倒计时模式时,按下此键后停止倒计时,进入设置状态;如果已经处于设置状态则此键无效。

(2)增一键:在设置状态时,每按一次递增键,初始值的数字增1。

(3)递一键:在设置状态时,每按一次递减键,初始值的数字减1。

(4)确认键:在设置状态时,按下此键后,单片机按照新的初始值进行倒计时及显示倒计时的数字。如果已经处于计时状态则此键无效。

整体架构流程

根据题目的要求,需要实现如下几个方面的功能。

计时功能:要实现计时功能则需要使用定时器来计时,通过设置定时器的初始值来控制溢出中断的时间间隔,再利用一个变量记录定时器溢出的次数,达到定时1秒中的功能。然后,当计时每到1秒钟后,倒计时的计数器减1。当倒计时计数器到0时,触发另一个标志变量,进入闪烁状态。

显示功能:显示倒计时的数字要采用动态扫描的方式将数字拆成“十位”和“个位”动态扫描显示。如果处于闪烁状态,则可以不需要动态扫描显示,只需要控制共阴极数码管的位控线,实现数码管的灭和亮。

键盘扫描和运行模式的切换:主程序在初始化一些变量和寄存器之后,需要不断循环地读取键盘的状态和动态扫描数码管显示相应的数字。根据键盘的按键值实现设置状态、计时状态的切换。

技术细节

  • 主函数.c
#include <STC89C5xRC.H>
#include "Timer0.h"
#include "Nexie.h"

unsigned char startnum=1;									 //³õÖµ£¬³õʼֵΪ1
unsigned char long_flag=0,long_flag1=0;//ÓÃÓÚ¼Ó¼õ5µÄÅжϱê־λ

bit set_flag=1;
bit zero_flag=0;
bit show_flag=1;

/**
  * @brief  °´¼üɨÃè
  * @param  ÎÞ
  * @retval ÎÞ
  */
void Key_Loop()
{
	static unsigned char count,count1,count2,count3;
	
	if(set_flag==1)	//ÅжÏÊÇ·ñΪÉèÖÃģʽ,·ñÔò¼Ó¼õ°´¼üʧЧ
	{
		if(P32==0)
		{
			count++;
			if(count>100) //˵Ã÷Êdz¤°´
			{							//Ö´ÐмӼõ5µÄ²Ù×÷
				long_flag=1;
				count--;		//ΪÁ˲»ÈüÆÊýÖµ³¬¹ý·¶Î§
			}
		}
		if(P32==1)
		{
			if(count>2) //˵Ã÷Ö»Êǵ¥»÷
			{						//Ö´ÐмӼõ1µÄ²Ù×÷
				startnum++;
				if(startnum>59)	//ÏÞÖÆƵÂÊ·¶Î§Îª1-200hz
				{startnum=1;}
			}
			long_flag=0;
			count=0;
		}
		
		if(P33==0)
		{
			count1++;
			if(count1>100) //˵Ã÷Êdz¤°´
			{							//Ö´ÐмӼõ5µÄ²Ù×÷
				long_flag1=2;
				count1--;		//ΪÁ˲»ÈüÆÊýÖµ³¬¹ý·¶Î§
			}
		}
		if(P33==1)
		{
			if(count1>2) //˵Ã÷Ö»Êǵ¥»÷
			{						 //Ö´ÐмӼõ1µÄ²Ù×÷
				startnum--;
				if(startnum<1)	//ÏÞÖÆƵÂÊ·¶Î§Îª1-200hz
				{startnum=59;}
			}
			long_flag1=0;
			count1=0;
		}
	}
	
	if(P30==0)//¸Ã°´¼üΪÉèÖð´¼ü
	{
		count2++;
	}
	if(P30==1)
	{
		if(count2>2) //˵Ã÷Ö»Êǵ¥»÷
		{
			if(zero_flag==1)//Èç¹û0µÄ±ê־λÖÃ1
			{startnum=1;}		//Ôò°´Ï°´¼üµÄ»°°Ñ¼ÆÊýÖµÖÃ1
			set_flag=1;			//°ÑÉèÖñê־λÖÃ1£¬±íʾĿǰΪÉèÖÃģʽ
			zero_flag=0;		//°Ñ0±ê־λÖÃ0ΪÏ´ε¹¼Æʱ׼±¸
			show_flag=1;		//ÏÔʾ±ê־λÖÃ1±íʾÏÔʾ
		}
		count2=0;
	}
	
	if(P31==0)//¸Ã°´¼üΪȷÈÏ°´¼ü
	{
		count3++;
	}
	if(P31==1)
	{
		if(count3>2) //˵Ã÷Ö»Êǵ¥»÷
		{	
			set_flag=0;	//°ÑÉèÖñê־λÖÃ1£¬±íʾĿǰΪ¼Æʱģʽ
		}
		count3=0;
	}
}
/**
  * @brief  ÊýÂë¹ÜÊý×ÖÏÔʾ
  * @param  ÎÞ
  * @retval ÎÞ
  */
void num_show()
{
	if(show_flag==1)//Èç¹ûÊÇÏÔʾ£¬ÔòÏÔʾÊý¾Ý
	{
	Nixie_SetBuf(1,startnum/10%10);
	Nixie_SetBuf(2,startnum%10);
	}
	else					//·ñÔòÏÔʾϨÃð
	{
	Nixie_SetBuf(1,10);
	Nixie_SetBuf(2,10);
	}
}

void main()
{
	Timer0_Init();		//¶¨Ê±Æ÷0³õʼ»¯
	
	while(1)
	{
		num_show();
	}
}

/**
  * @brief  ¶¨Ê±Æ÷0µÄÏà¹Ø²Ù×÷
	* @brief  ¶¨Ê±Æ÷0Ϊģʽ1,16Ϊ²»×Ô¶¯ÖØÔØ,1msÖжÏ
  * @param  ÎÞ
  * @retval ÎÞ
  */
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count0,T0Count1,T0Count2,T0Count3,T0Count4;//¶¨Ê±Æ÷Ïà¹Ø±äÁ¿
		TL0 = 0x18;				//ÉèÖö¨Ê±³õʼֵ
		TH0 = 0xFC;				//ÉèÖö¨Ê±³õʼֵ

		T0Count0++;T0Count1++;T0Count2++;T0Count3++;T0Count4++;//ÿ1ms½øÐÐÒ»´Î++£»
			
		if(T0Count0>=10)//10msµ÷ÓÃÒ»´ÎKey_Loop()º¯Êý
		{
			T0Count0=0;
			Key_Loop();
		}
		if(T0Count1>=2)//2msµ÷ÓÃÒ»´ÎNixie_Loop()º¯Êý
		{
			T0Count1=0;
			Nixie_Loop();
		}
		
		if(T0Count2>=250)//µ÷½Ú¸ÃÖµ¿É¸Ä±ä¼Ó¼õ5µÄËÙ¶È
		{
			T0Count2=0;
			if(long_flag==1)
			{
				startnum+=5;
				if(startnum>59)	//ÏÞÖÆ·¶Î§Îª1-59
				{startnum=1;}
			}
			if(long_flag1==2)
			{
				startnum-=5;
				if(startnum>59)	//ÏÞÖÆ·¶Î§Îª1-59
				{startnum=59;}
			}
		}
		if(T0Count3>=1000)//1sµ¹¼Æʱ
		{
			T0Count3=0;
			if(set_flag==0)
			{
				if(zero_flag==0)//Èç¹ûÉèÖúÍ0±ê־λ¶¼Îª0£¬Ôò½øÐÐÊý×ֵĵ¹¼Æʱ
				{
				startnum--;
				}
				if(startnum==0)//Èç¹ûÉèÖñê־λΪ0ºÍÊý×Ö¼õÉÙµ½0£¬Ôò¹ÒÆð0±ê־λ
				{
					zero_flag=1;
				}	
			}			
		}
		
	 if(T0Count4>=500)//µ÷½Ú¸ÃÖµ¿É¸Ä±äÉÁ˸ƵÂÊ
	{
		T0Count4=0;
			if(zero_flag==1)	//½øÐÐÉÁ˸ÏÔʾ
			{
				show_flag=!show_flag;
			}
			else				
			{
				show_flag=1;
			}
	}
}
  • 数码管.c
#include <STC89C5xRC.H>
#include "Delay.h"
unsigned char Nixie_Buf[4]={0,10,10};//0ÊÇΪÁËÕÕÓ¦loopÖÐi=1
unsigned char NixieNumb[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
													
/**
  * @brief  Íⲿµ÷ÓöÔÊý×éNixie_Buf[4]¸³Öµ
  * @brief  ʹµÃloopº¯ÊýÑ­»·¶Ôscanº¯Êý¸³ÖµÊ±¶Áµ½ÏàÓ¦Êý¾Ý
  * @brief  δ¸³ÖµµÄÊý×éλ¼´Îª10£»¶ÔÓ¦NixieNumb[]ÖеÄ0£»
  * @param Table,NumberÔÚNixie_BufÊý×éµÄÏÂ±ê ¸³µÄÖµ£¨¸ÃÖµ¼´¶ÔÓ¦NixieNumb[]ÖеÄÖµ£©
  * @retval ÎÞ
  */
void Nixie_SetBuf(unsigned char Table,Number)
{
	Nixie_Buf[Table]=Number;
}

/**
  * @brief  ÊýÂë¹ÜÏÔʾ
  * @param  Table,NumberÏÔʾµÄλÖà ÏÔʾµÄÊý×Ö
	* @param Á½²ÎÊýÓɶ¨Ê±Æ÷°´ÖÜÆÚɨÃèʱ¸ø¶¨
  * @retval ÎÞ
  */
void Nixie_Scan(unsigned char Table,Number)
	{
		P0=0x00;//ÏûÒþ
		switch(Table)
		{//     P2_4=C-4,P2_3=B-2;P2_2=A-1
			case 1:P24=1;P23=1;P22=1;break;
			case 2:P24=1;P23=1;P22=0;break;
		}
		P0=NixieNumb[Number];//²»ÓÃdelayÔÙÏûÒþ£¬ÒòΪ¶¨Ê±Æ÷½øÀ´ÓÐʱ¼ä¼ä¸ô
		
	}
/**
  * @brief  ¶¨Ê±Æ÷µ÷Óõĺ¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  */
	void Nixie_Loop(void)//¶¨Ê±Æ÷ÿ½øÒ»´Î¾Íµ÷ÓÃÒ»´Îscanº¯Êý
	{										//ʹµÃ3¸öÊýÂë¹ÜÒÀ´Î¿ìËÙÏÔʾ
		static unsigned char i=1;
		Nixie_Scan(i,Nixie_Buf[i]);
		i++;
		if(i>=3)i=1;
	}
  • 数码管.h
#ifndef __NEXIE_H__
#define __NEXIE_H__

void Nixie_Scan(unsigned char Table,Number);
void Nixie_Loop(void);
void Nixie_SetBuf(unsigned char Table,Number);

#endif
  • 定时器.c
#include <STC89C5xRC.H>

/**
  * @brief  ¶¨Ê±Æ÷³õʼ»¯
  * @param ÎÞ
  * @retval ÎÞ
  */
	void Timer0_Init(void)		//100us@12.000MHz
	{
		TMOD &= 0xF0;			//¶¨Ê±Æ÷ʱÖÓ12Tģʽ
		TMOD |= 0x01;			//ÉèÖö¨Ê±Æ÷ģʽ
		TL0 = 0x18;				//ÉèÖö¨Ê±³õʼֵ
		TH0 = 0xFC;				//ÉèÖö¨Ê±³õʼֵ
		TF0 = 0;				//Çå³ýTF0±êÖ¾
		TR0 = 1;				//¶¨Ê±Æ÷0¿ªÊ¼¼Æʱ
		ET0=1;
		EA=1;
		PT0=0;
	}
	
  • 定时器.h
#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0_Init(void);
	
#endif

小结

设计一个单片机控制的简易定时报警器。要求根据设定的初始值(1-59秒)进行倒计时,当计时到0时数码管闪烁“00”(以1Hz闪烁)

如需要源文件可以添加qq群聊获取:662177587

希望对你有所帮助!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SFR-小曾

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

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

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

打赏作者

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

抵扣说明:

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

余额充值