📄 定时灯.c
字号:
/*定时灯(带数码管显示时间可以调节)程序要求如下:
两位数码管显示。时间0-99分钟可以调节。 (用3个按键, 分别调整上,下, 开始)
有一个灯的秒指示。
运行期间,时间同步在数码管减少。 当等于00时。 灯熄灭
程序要求有..注释。
凡第一个交作业并运行通过由本站送出ep51编程器散件一套。*/
/********************************************************************************
本作业用74HC164作为数码管的驱动,P1.1为位选按键,P1.2为调整按键,P1.3为确认按键。
P1.0为指示灯.另外我是用有点像电子表那种模式作为时间的调整,即一个按键作为选择
调整个位和十位的切换,用一个按键在0-9的范围内调整,本人觉得这种模式更灵活,而不
是用楼主的模式(用3个按键,分别调整上,下,开始)
*******************************************************************************/
#include<at89x51.h>
#define uint unsigned int
#define uchar unsigned char
uint count; //定义定时计数
uchar second; //定义一秒的计数
uchar mini; //定义一分钟的计数
uchar cnt; //定义确认按键的计数
uchar con; //定义位选按键的计数
uchar disp0,disp1; //定义调整时间按键的计数
uchar i;
uchar code dispcode[]={0xf7, //0
0x45, //1
0xdb, //2
0x5f, //3
0x6d, //4
0x3f, //5
0xbf, //6
0x55, //7
0xff, //8
0x7f //9
}; //段码
/****************************延时子程序,用于按键去抖动************************/
void delay(void)
{
uchar i,j;
for(i=10;i>0;i--)
for(j=248;j>0;j--);
}
/***************************数码管显示子程序***************************/
void display(void)
{
TI=0; //显示数码管的个位,把发送中断标志位清零
SBUF=0xee; //送个位的码子
while(TI==0); //判断数据送是否完,若没送完在原地等待
TI=0; //把发送中断标志位清零
SBUF=dispcode[mini%10]; //送段码
while(TI==0); //判断数据送是否完,若没送完在原地等待
delay(); //延时一段时间
TI=0; //显示数码管的十位,把发送中断标志位清零
SBUF=0xdd; //送十位的码子
while(TI==0); //判断数据送是否完,若没送完在原地等待
TI=0; //把发送中断标志位清零
SBUF=dispcode[mini/10]; //送段码
while(TI==0); //判断数据送是否完,若没送完在原地等待
delay(); //延时一段时间
}
void display1(void) //仅显示十位,不显示个位,让个位闪烁
{
TI=0; //显示数码管的十位,把发送中断标志位清零
SBUF=0xdd; //送十位的码子
while(TI==0); //判断数据送是否完,若没送完在原地等待
TI=0; //把发送中断标志位清零
SBUF=dispcode[mini/10]; //送段码
while(TI==0); //判断数据送是否完,若没送完在原地等待
delay(); //延时一段时间
}
void display2(void) //仅显示个位,不显示十位,用来让十位闪烁
{
TI=0; //显示数码管的个位,把发送中断标志位清零
SBUF=0xee; //送个位的码子
while(TI==0); //判断数据送是否完,若没送完在原地等待
TI=0; //把发送中断标志位清零
SBUF=dispcode[mini%10]; //送段码
while(TI==0); //判断数据送是否完,若没送完在原地等待
delay(); //延时一段时间
}
/**********************主程序*********************/
void main(void)
{
SCON=0x00; //设置串口
TMOD=0x02; //设置定时计数器0为方式2
TH0=0x06;
TL0=0x06;
EA=1;ET0=1; //开全局中断和定时中断
second=0; //初始化
count=0;
mini=99;
con=0;cnt=0;
while(1)
{
if(P1_3==0) //确认按键,确认输入的时间,并切换开始/停止定时
{
delay(); //延时一段时间
if(P1_3==0) //再判断是否有按键按下
{
cnt++;
if(cnt==2)
{
cnt=0;
}
while(P1_3==0); //判断按键是否释放,若没有释放在原地等待
}
}
if(cnt==0) //停止定时,并进入调整时间模式
{
TR0=0;
if(P1_1==0) //位选按键,选择需要调整数码管位数
{
delay(); //延时一段时间
if(P1_1==0) //再判断是否有按键按下
{
con++;
if(con==3)
{
con=0;
}
while(P1_1==0); //判断按键是否释放,若没有释放在原地等待
}
}
switch(con) //判断需要调整的数码管位数
{
case 0: //显示调整好的时间
display(); //延时一段时间
break;
case 1: //调整数码管的个位
{
if(P1_2==0) //调整按键,调整时间
{
delay(); //延时一段时间
if(P1_2==0) //再判断是否有按键按下
{
disp0++;
if(disp0==10)
{
disp0=0;
}
while(P1_2==0); //判断按键是否释放,若没有释放在原地等待
}
}
for(i=0;i<20;i++) //用来令数码管的个位闪烁
display1();
}
break;
case 2: //调整数码管的十位
{
if(P1_2==0) //调整按键,调整时间
{
delay(); //延时一段时间
if(P1_2==0) //再判断是否有按键按下
{
disp1++;
if(disp1==10)
{
disp1=0;
}
while(P1_2==0); //判断按键是否释放,若没有释放在原地等待
}
}
for(i=0;i<20;i++) //用来令数码管的个位闪烁
display2();
}
break;
}
mini=disp0+disp1*10; //把调整的时间放进mini里
}
else
{
TR0=1;
con=0; //把定时器0运行控制位,开始定时
disp0=0;
disp1=0;
}
if(TR0==0) P1_0=1; //当停止定时的时候,熄灭指示灯
else P1_0=0; //当开始定时的时候,点亮指示灯
for(i=0;i<20;i++) //显示时间
display();
}
}
/***********************中断延时程序***********************/
void timer0(void)interrupt 1 using 1
{
count++;
if(count==4000) //计算一秒的时间
{
count=0;
second++;
if(second==60) //计算一分钟的时间
{
second=0;
mini--; //按一分钟的时间减少
if(mini==0)
{
mini=99;
cnt=0;
TR0=0; //把定时器0运行控制位清零
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -