//为了节约端口8个位接在了74hc138上,由P2.1 P2.0 P2.2控制译码器输出位选.
//本程序完全测试通过.完整代码下载地址: http://www.51hei.com/f/djsq.rar
/************************************************************************/
/************8位数码管倒计时显示 时间格式24—00—00~~00-00-00**************/
/************************************************************************/
#include
#define uchar unsigned char
#define uint unsigned int
sbit D0=P2^0; //定义数码管片选参数
sbit D1=P2^1;
sbit D2=P2^2;
sbit D3=P1^2; //定义蜂鸣器输出引脚
#define CLOCK_NUM 4 //动态定义闹钟的个数
struct SAVE_TIME {
uint save_hour;
uint save_minute;
uint save_second;
};
void key_scan_pro(void);
void Displaypro(void);
void Print_play_pro(void);
struct SAVE_TIME save_time[CLOCK_NUM]={0};
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极数码管0—9
uchar StrTab[8]; //定义缓冲区
static uint minute=0,hour=24,second=0; //定义并初始化为 24:00:00
static uchar num=0;
static uchar temp,count1=1;
static uchar time_save_value=0;
void delay(uint z) //按键消抖延时函数
{
uint x,y;
for(x=z; x>0; x--)
for(y=110; y>0; y--);
}
void hour_add_pro(void) //小时加一减一处理函数 KEY0
{
if(24==hour) { hour=24; minute=0; second=0; } //小时为24时,将分钟和秒置零
else { hour++; }
Displaypro();
}
void hour_sub_pro(void) //KEY1
{
if(0==hour) { hour=0; }
else { hour--; }
Displaypro();
}
void minute_add_pro(void) //分钟加一减一处理函数 KEY2
{
if(59==minute) { minute=59; }
else
{
if((24==hour)&&(minute==0)){} //分钟边界压力判断,当24:00:00,不允许往上加
else { minute++; }
}
Displaypro();
}
void minute_sub_pro(void) //KEY3
{
if(0==minute) { minute=0; }
else { minute--; }
Displaypro();
}
void second_add_pro(void) //秒加一减一处理函数 KEY4
{
if(60==second) { second=60; }
else //秒边界压力判断 当24:00:00,不允许往上加
{
if((24==hour)&&(minute==0)) {}
else { second++; }
}
Displaypro();
}
void second_sub_pro(void) //KEY5
{
if(0==second) { second=0; }
else { second--; }
Displaypro();
}
void begin_suspend_pro(void) //开始/暂停处理函数
{ TR0 ^=0x1; }
void time_save_pro(void) //定时值保存函数
{
if(time_save_value
save_time[time_save_value].save_hour = hour;
save_time[time_save_value].save_minute = minute;
save_time[time_save_value].save_second = second;
time_save_value++;
if(CLOCK_NUM==time_save_value) //循环调用闹钟
{ time_save_value=0; }
}
}
void clock_judge_pro(void) //闹钟值判断函数
{
uchar i;
for(i=0; i< CLOCK_NUM; i++)
{ if((hour==save_time[i].save_hour)&&(minute==save_time[i].save_minute)&&(second==save_time[i].save_second))
{ TR0=0; TR1=1; } }
}
void time_init_pro(void) //定时器初始化函数
{
TMOD |=0x01; //定时器0 10ms inM crystal 用于计时
TH0=0xd8; //定时器初值10ms
TL0=0xf0;
ET0=1; //定时器/计数器T0中断允许位
TR0=0; //TCON寄存器的TR0位 1:启动T1/0 0:停止T1/0
TMOD |=0x10; //定时器1用于处理蜂鸣器
TH1=0xd8; //初值20ms
TL1=0xf0;
ET1=1;
TR1=0; //定时器的允许位
EA =1; //开总中断
}
/********************************主函数***************************************/
void main(void)
{
time_init_pro(); //调用定时器初始化函数
Displaypro(); //调用显示函数
while(1)
{
key_scan_pro(); //不断扫描按键
}
}
/********************************主函数***************************************/
void key_scan_pro(void) //键盘扫描函数
{
D3=1;
Print_play_pro(); //调用显示处理函数
P1=0xfe; temp=P1; temp&=0xf0;
while(temp!=0xf0) //按键消抖
{
delay(6); temp=P1; temp&=0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee: num=0;
hour_add_pro(); //按键0,1控制小时
break;
case 0xde: num=1;
hour_sub_pro();
break;
case 0xbe: num=2; //按键2,3控制分钟
minute_add_pro();
break;
case 0x7e: num=3;
minute_sub_pro();
break;
default:
break;
}
while(temp!=0xf0)
{ temp=P1; temp&=0xf0; }
delay(6);
while(temp!=0xf0)
{ temp=P1; temp&=0xf0; }
}
}
P1=0xfd; temp=P1; temp&=0xf0;
while(temp!=0xf0)
{
delay(6); temp=P1; temp&=0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed: num=4; //按键4,5控制秒
second_add_pro();
break;
case 0xdd: num=5;
second_sub_pro();
break;
case 0xbd: num=6; //按键6控制开始/暂停处理函数
begin_suspend_pro();
break;
case 0x7d: num=7; //按键7控制定时保存函数
time_save_pro();
break;
default:
break;
}
while(temp!=0xf0)
{ temp=P1; temp&=0xf0; }
delay(6);
while(temp!=0xf0)
{ temp=P1; temp&=0xf0; }
}
}
}[page]
void Displaypro(void)
{
StrTab[0]=tab[hour/10]; //存储小时
StrTab[1]=tab[hour%10];
StrTab[2]=0x40; //存储"-"
StrTab[3]=tab[minute/10]; //存储分钟
StrTab[4]=tab[minute%10];
StrTab[5]=0x40; //存储"-"
StrTab[6]=tab[second/10]; //存储秒
StrTab[7]=tab[second%10];
}
void Print_play_pro(void) //动态扫描数码管
{
D0=1; D1=1; D2=1; //显示秒
P0=StrTab[7];
delay(3);
D0=0;D1=1; D2=1;
P0=StrTab[6];
delay(3);
D0=1;D1=0; D2=1; //显示"-"
P0=StrTab[5];
delay(3);
D0=0;D1=0;D2=1; //显示分
P0=StrTab[4];
delay(3);
D0=1;D1=1;D2=0;
P0=StrTab[3];
delay(3);
D0=0;D1=1;D2=0; //显示"-"
P0=StrTab[2];
delay(3);
D0=1;D1=0;D2=0; //显示小时
P0=StrTab[1];
delay(3);
D0=0;D1=0;D2=0;
P0=StrTab[0];
delay(3);
}
/*****************************定时器1中断*********************************/
void time1_isr(void) interrupt 3 //定时器1用来处理蜂鸣器
{
static uint count = 1; //位置待定
TH1=0xd8; //重入初值定时20ms
TL1=0xf0;
//Print_play_pro(); //抖动效果
count++;
D3=0; //产生闹钟方波
if(200==count)
{
TR0=1;
TR1=0;
count=1;
D3=1;
}
}
/***************************定时器0中断**********************************/
void tim(void) interrupt 1 //定时器0用来处理倒计时
{
static uchar count; //定义内部局部变量
TH0=0xd8; //重新赋值
TL0=0xf0;
count++;
switch (count)
{
case 80:Displaypro();break; //隔一定时间调用显示处理
default:break;
}
if (count==100)
{
clock_judge_pro(); //定时时间判断
count=0;
if((0==minute)&&(second==0)) //倒计时值处理
{
if(0==hour) { hour=0; }
else { hour--; }
minute=60;
}
if(0==second)
{
if(0==minute) { minute=59; }
else { minute-=1; }
}
if(0==second) { second=60; }
else { second-=1; }
if((0==hour)&&(0==minute)&&(0==second)) //倒计时到00:00:00,结束倒计时
{ hour=0; minute=0; second=0; Displaypro(); TR0=0; }
}
}
上一篇:DS1302芯片+1602液晶显示
下一篇:16键计算器 c51实现
推荐阅读最新更新时间:2024-03-16 14:25
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- USB Type-C® 和 USB Power Delivery:专为扩展功率范围和电池供电型系统而设计
- 景昱医疗耿东:脑机接口DBS治疗技术已实现国产替代
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光