该项目基本满足以下要求
1.一个四位一体数码管显示比赛时间,时间格式如:15:00,两个三位一体数码管显示甲乙两对的比分,比分格式如:008。
2.比赛时间采用倒计时方式,以一秒的频率减时,上电时默认初值为15:00.
3.甲乙队比分采用三位数,上电初值为000,最大值为999,满足常理要求,未开始比赛以及比赛结束后比分无法加减,
4.比赛未开始之前,可以通过ADD1、DEC1键对比较时间的分钟进调时,通过ADD2、DEC2键对比较时间的秒进行调时。
5.可随时暂停/启动比赛时间。
6.比赛进行时,可以通过ADD1、DEC1键对甲队比分加、减,可以通过ADD2、DEC2对乙队比分加、减。每按一次键,加/减1分。
7.当一节比赛完后,可以通过(EXCHANGE)换场键换场,换场后,比分交换显示,交换后,下一节比赛开始时,相应的比分加减键也随之交换。
8.当比赛结束时,发出报警。
视频教程下载地址:http://www.51hei.com/bbs/dpj-100315-1.html
单片机源程序如下:
- /*
- 倒计时计算器,数码管显示 默认值15:00
- 共阳数码管
- */
- #include <reg52.h>
- void delay(int ms);
- void dispaly(char min,char sec,int sco1,int sco2);
- void key_scan(void);
- /*共阳极数码管的0-9数字编码*/
- code unsigned char table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- sbit s8 = P3^6;
- sbit s9 = P3^7;
- sbit buz = P3^4;
- char m = 15; //默认的分钟
- char sec = 0; //默认的秒钟
- int sc1 = 0; //默认甲方的比分
- int sc2 = 0; //默认乙方的比分
- char buz_flag = 0; //默认报警标志为0,不报警
- char status = 0; //状态标志,0的时候表示非比赛状态,1表示比赛状态
- int main(void)
- {
- /*使用定时器进行计时*/
- //初始化定时器0
- TMOD=0xf1; //设置T0为工作方式1 16位的定时器模式
- TH0=(65535-50000)/256; //50ms中断一次
- TL0=(65535-50000)%256;
- /*Timer0工作在模式0下时为13位定时/计数器,
- TL0只使用前5位,故对32进行求余/模 */
-
-
- ET0=1; //开定时器0中断
-
- P3 = 0x3f;
-
- /*外部中断0 的初始化*/
- IT0 = 1; //设置为下降沿触发
- EX0 = 1; //外部中断0中断允许位
-
-
- EA=1; //开总中断
- // TR0=1; //启动定时器0
- while(1)
- {
- dispaly(m,sec,sc1,sc2);
- key_scan();
- if(buz_flag)
- {
- buz = 0;
- }
- }
- }
-
- /*按键扫描*/
- void key_scan(void)
- {
- static char key_flag = 0; //按键按下标志 ,检测到按下之后为1,否则为0
- static char key_count = 0;
- static unsigned char key_val = 0; //检测到按键之后保存的按键值
- int t;
-
- P1 = 0xff;
-
- if(P1 != 0xff) //有按键按下了
- {
- if(key_flag == 1) //表示已经检测到按键了
- {
- key_count++;
- if(key_count > 15)
- {
- key_count = 0;
- if(P1 == key_val) //确实 有按键按下了
- {
- switch(key_val) //进行按键处理
- {
- case 0xfe:
- //add1
- if(status)
- {
- sc1 += 1;
- }
- else
- {
- m += 1;
- }
- break;
- case 0xfd:
- //dec1
- if(status)
- {
- if(sc1 > 0)
- {
- sc1 -= 1;
- }
- }
- else
- {
- if(m>0)
- {
- m -= 1;
- }
- }
- break;
- case 0xfb:
- //add2
- if(status)
- {
- sc2 += 1;
- }
- else
- {
- if(sec<59)
- {
- sec += 1;
- }
- }
- break;
- case 0xf7:
- //dec2
- if(status)
- {
- if(sc2 > 0)
- {
- sc2 -= 1;
- }
- }
- else
- {
- if(sec>0)
- {
- sec -= 1;
- }
- }
- break;
- case 0xef:
- //exchang
- t = sc1;
- sc1 = sc2;
- sc2 = t;
- break;
- }
- }
- else
- {
- key_val = 0; //还原默认值
- key_flag = 0; //还原默认值
- key_count = 0;
- }
- }
-
- }
- else
- {
- key_val = P1; //保存按键的值
- key_flag = 1; //检测到了按键
- }
- }
- else
- {
- key_val = 0; //还原默认值
- key_flag = 0; //还原默认值
- key_count = 0;
- }
-
- }
- void exint0() interrupt 0 //中断服务函数的书写格式
- {
- // if(IE0 == 1) //产生了外部中断,IE 自动置为1
- {
- if(status)
- {
- status = 0 ; //切换到非比赛状态
- TR0 = 0 ; //关闭定时器0
- }
- else
- {
- status = 1 ; //切换到非比赛状态
- TR0 = 1 ; //启动定时器1
- }
- }
- }
- char counter = 0;
- /******T0中断函数*******/
- void Timer0()interrupt 1
- {
- TH0=(65535-50000)/256; //50ms中断一次
- TL0=(65535-50000)%256;
- counter++;
- while(counter>=20)
- {
- counter=0;
- if(sec == 0)
- {
- m --;
- sec = 60;
- if(m == 0)
- {
- buz_flag = 1; //报警标志设置
- }
- }
- sec--;
- }
- }
- //led数码管显示,4个参数分别表示分钟秒钟,分数1和分数2
- void dispaly(char min,char sec,int sco1,int sco2)
- {
- char buf[10];
- char i;
-
- buf[0] = min/10%10; //分钟的十位
- buf[1] = min%10; //分钟的各位
- buf[2] = sec/10%10; //秒钟的十位
- buf[3] = sec%10; //秒钟的各位
- buf[4] = sco1/100%10; //分数1的百位
- buf[5] = sco1/10%10; //分数1的十位
- buf[6] = sco1%10; //分数1的个位
- buf[7] = sco2/100%10; //分数2的百位
- buf[8] = sco2/10%10; //分数2的十位
- buf[9] = sco2%10; //分数2的个位
-
- for(i=0;i<8;i++)
- {
- P0 = table[buf[i]];
- P2 = 1<<i;
- delay(1);
- P2 = 0;
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
4.bisaijifenqi.rar
(31.68 KB, 下载次数: 23)
4.bisaijifenqi-1208.rar
(25.22 KB, 下载次数: 19)
在单片机视频中的项目二部分,有源代码及完整的视频,谢谢大家,希望大家共同进步
|