基于51单片机的倒计时定时器
要求:设计一个能够完成计时系统的系统,并且满足以下基本要求:
◉数码管上显示计时的时间。
◉可以通过按键实现1小时内初始时间的设定(以秒为分度),并且完成计时。
◉可随时暂停并且重新设置计时时间。
◉其他扩展功能
本人初学51单片机,有不当之处,欢迎在评论区指出。
主程序
/******************************
本程序是以一个倒计时定时器(计时完毕放歌)
******************************/
#include <STC89C5xRC.H>
#include "Delay.h"
typedef unsigned char uchar;
typedef unsigned int uint;
void Smg_Xs();
void ShuZiJia();
void ShuZiJian();
void Song();
void timer0();
void timer1();
uchar code g_caSmg_nodot[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code g_caSmg_dot[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uint code Score[]={0,
64400,64463,64524,64580,64633,64684,64732,64777,64820,64860,64898,64934,
64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,
65252,65268,65283,65297,65311,65323,65335,65346,65357,65367,65377,65385};
uchar code suoyin[]=
{
//1
p,4+4,
p,2,m3,1,m3,1,m3,2,m2,1,m2,1,m2,2,m1,2,l6,2,m1,2,
p,2,m3,1,m3,1,m3,2,m2,2,m2,2,m1,1,m1,1,m5,2,m1,2,
//2
p,2,m1,1,m1,1,m1,2,m1,2,m1,2,l5,2,l5,2,m1,2,
l7,2,l7,2,l7,2,m3,2+2,m2,2,l6,2,m1,1,
0xff
};
uchar g_cMiao1=0,g_cMiao2=0,g_cFen1=0,g_cFen2=0;
uchar g_cNum=0;
uint g_cJiShu=0;
uint suoyin_choice=0,Score_choice=0 ;
void main()
{
while(1)
{
Smg_Xs();
if(P24==0) //按键1短按秒加一,长按秒持续加
{
while(P24==0)
{
Smg_Xs();
timer0();
Delay(10);
while(P24==0)
{
Smg_Xs();
}
Delay(10);
if(g_cNum!=20)
{
g_cNum=0;
ShuZiJia();
TR0=0;
}
else
{
g_cNum=0;
TR0=0;
}
}
}
if(P25==0) //按键2短按秒减一,长按秒持续减
{
while(P25==0)
{
timer0();
Delay(10);
while(P25==0)
{
Smg_Xs();
}
Delay(10);
if(g_cNum!=20)
{
g_cNum=0;
ShuZiJian();
TR0=0;
}
else
{
g_cNum=0;
TR0=0;
}
}
}
if(P26==0) //按键3开始倒计时
{
Delay(10);
while(P26==0)Smg_Xs();
Delay(10);
while(1)
{
Delay(1);
Smg_Xs();
g_cJiShu++;
if(g_cJiShu==350) //用Delay函数计时一秒,并是数码管数字减小
{
g_cJiShu=0;
ShuZiJian();
if(g_cFen1==0&&g_cFen2==0)
{
if(g_cMiao1==0&&g_cMiao2==0)
{
Song();
}
}
}
if(P24==0||P25==0)break;
if(P26==0||P27==0)break;
}
}
if(P27==0) //按键4短按分加一,长按分持续加
{
timer0();
Delay(10);
while(P27==0)
{
Smg_Xs();
}
Delay(10);
if(g_cNum!=20)
{
g_cNum=0;
g_cFen2++;
if(g_cFen2==10)
{
g_cFen2=0;
g_cFen1++;
if(g_cFen1==6 && g_cFen2==0)
{
g_cFen1=0;
g_cFen2=0;
g_cMiao1=0;
g_cMiao2=0;
}
}
TR0=0;
}
else
{
g_cNum=0;
TR0=0;
}
}
}
}
/******************************
*函数名称:Smg_Xs()
*函数功能:数码管动态显示
*函数调用:Smg_Xs();
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void Smg_Xs()
{
P20=0;P0=g_caSmg_nodot[g_cFen1]; Delay(1); P20=1;P0=0xff;
P21=0;P0=g_caSmg_dot[g_cFen2]; Delay(1); P21=1;P0=0xff;
P22=0;P0=g_caSmg_nodot[g_cMiao1]; Delay(1); P22=1;P0=0xff;
P23=0;P0=g_caSmg_nodot[g_cMiao2]; Delay(1); P23=1;P0=0xff;
}
/******************************
*函数名称:ShuZiJia()
*函数功能:数码管数字加
*函数调用:ShuZiJia();
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void ShuZiJia()
{
g_cMiao2++;
if(g_cMiao2==10)
{
g_cMiao2=0;
g_cMiao1++;
if(g_cMiao1==6)
{
g_cMiao1=0;
g_cFen2++;
if(g_cFen2==10)
{
g_cFen2=0;
g_cFen1++;
if(g_cFen1==6 && g_cFen2==0)
{
g_cFen1=0;
g_cFen2=0;
g_cMiao1=0;
g_cMiao2=0;
}
}
}
}
}
/******************************
*函数名称:ShuZiJian()
*函数功能:数码管数字减
*函数调用:ShuZiJian();
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void ShuZiJian()
{
g_cMiao2--;
if(g_cMiao2==-1)
{
g_cMiao1--;
g_cMiao2=9;
if(g_cMiao1==-1)
{
g_cFen2--;
g_cMiao1=5;
if(g_cFen2==-1)
{
g_cFen1--;
g_cFen2=9;
if(g_cFen1==-1)
{
g_cFen1=0;
g_cFen2=0;
g_cMiao1=0;
g_cMiao2=0;
}
}
}
}
}
/******************************
*函数名称:Song()
*函数功能:蜂鸣器放歌
*函数调用:Song();
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void Song()
{
timer1();
while(1)
{
suoyin_choice=0;
Score_choice=0;
while(1)
{
if(suoyin[suoyin_choice]!=0xff)
{
Score_choice=suoyin[suoyin_choice];
suoyin_choice++;
Delay1(130*suoyin[suoyin_choice]);
suoyin_choice++;
TR1=0;
Delay1(5);
TR1=1;
}
else
{
TR1=0;
Delay1(1000);
suoyin_choice=0;
Score_choice=0;
}
}
}
}
/******************************
*函数名称:timer0()
*函数功能:计时检测按键状态(长按短按)
*函数调用:timer0();
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void timer0()
{
TMOD=0x11;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
TR0=1;
TF0=0;
}
/******************************
*函数名称:timer0_Routine()
*函数功能:计时器中断函数,实现按键长按数字持续增加或减少
*函数调用:
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void timer0_Routine() interrupt 1
{
char l_cJiShu=0;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
g_cNum++;
if(g_cNum==20)
{
if(P24==0)
{
while(P24==0)
{
l_cJiShu++;
Smg_Xs();
if(l_cJiShu==15)
{
l_cJiShu=0;
Smg_Xs();
ShuZiJia();
}
}
TR0=0;
}
if(P25==0)
{
while(P25==0)
{
l_cJiShu++;
Smg_Xs();
if(l_cJiShu==15)
{
l_cJiShu=0;
Smg_Xs();
ShuZiJian();
}
}
TR0=0;
}
if(P27==0)
{
while(P27==0)
{
l_cJiShu++;
Smg_Xs();
if(l_cJiShu==15)
{
l_cJiShu=0;
Smg_Xs();
g_cFen2++;
if(g_cFen2==10)
{
g_cFen2=0;
g_cFen1++;
if(g_cFen1==5 && g_cFen2==10)
{
g_cFen1=0;
g_cFen2=0;
g_cMiao1=0;
g_cMiao2=0;
}
}
}
}
TR0=0;
}
}
}
/******************************
*函数名称:timer1()
*函数功能:控制蜂鸣器声音频率
*函数调用:timer();
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void timer1()
{
TMOD=0X11;
TF1=0;
TL1=0X00;
TH1=0X00;
TR1=1;
ET1=1;
EA=1;
}
/******************************
*函数名称:timer1_Routine()
*函数功能:控制蜂鸣器声音频率
*函数调用:
*参数表列:
*返回值:
*结果:
*备注:
******************************/
void timer1_Routine() interrupt 3
{
if(Score[Score_choice])
{
TL1=Score[Score_choice]%256;
TH1=Score[Score_choice]/256;
P36=!P36;
}
}
头文件
#ifndef _DELAY_H_
#define _DELAY_H_
void Delay(unsigned char i);
Delay1(unsigned int ms);
#define p 0
//低音
#define l1 1
#define l1_ 2
#define l2 3
#define l2_ 4
#define l3 5
#define l4 6
#define l4_ 7
#define l5 8
#define l5_ 9
#define l6 10
#define l6_ 11
#define l7 12
//中音
#define m1 13
#define m1_ 14
#define m2 15
#define m2_ 16
#define m3 17
#define m4 18
#define m4_ 19
#define m5 20
#define m5_ 21
#define m6 22
#define m6_ 23
#define m7 24
//高音
#define h1 25
#define h1_ 26
#define h2 27
#define h2_ 28
#define h3 29
#define h4 30
#define h4_ 31
#define h5 32
#define h5_ 33
#define h6 34
#define h6_ 35
#define h7 36
#endif
Delay函数
/******************************
*函数名称:Delay(unsigned char i)
*函数功能:延时
*函数调用:Delay(i);
*参数表列:i
*返回值:
*结果:
*备注:i=1延时0.5ms,i=2延时1ms
******************************/
void Delay(unsigned char i)
{
unsigned char j;
for(i;i;i--)
{
for(j=249;j;j--);
}
}
void Delay1(unsigned int ms) //@12.000MHz
{
while(ms)
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
}
while (--i);
ms--;
}
}
本程序倒计时因要求使用Delay函数实现(还可用定时器实现,请自行探索)