赞
踩
本系统由硬件系统和软件系统组成。
硬件系统包括按键控制模块、中央处理AT89C51系统、指示灯显示模块、LED数码管显示模块和扬声器提示模块。
软件系统包括主程序、定时器0中断服务程序、定时器1中断服务程序、延时程序、按键程序和显示程序。
为方便理解,系统框图如下图所示:
图1 系统框图
本次单片机课程设计选题是《八路抢答器》。本次课程设计是以八位选手抢答和主持人的控制为出发点。
①只有一个最先抢答有效,其余抢答无效。
②在主持人的控制下,10秒内抢答有效,用数码管显示抢答10秒倒计时,若有抢答直接结束,显示哪个编号抢到,并进入10秒的答题时间。
③若有提前抢答,则犯规,用蜂鸣器响1秒警示。
④有复位按键,用于复位作用,开始新的一轮。
⑤可以设置抢答时间和答题时间,可调范围是0到99秒,超出或低出范围会返回第10秒。
⑥LED警示灯、LED显示屏和蜂鸣器进行倒计时警示,三重的警示,带来极致的紧迫感。
⑦答题时间暂停,可以确定选手最后的答案耗时多长时间,促进选手的公平。
⑧如果选手在规定时间内或违规抢到第一位,不仅屏幕会显示号码,而且对应选手的LED灯会亮起。
①时钟电路模块:
图2 时钟电路
②复位电路模块:
图3 复位电路
③LED显示屏模块:
图4 LED显示屏
④选手抢答按键模块:
图5 选手抢答按键
⑤选手点灯模块:
图6 选手点灯
⑥蜂鸣器提示模块:
图7 蜂鸣器提示
⑦LED灯倒计时警示模块:
图8 LED灯倒计时警示
⑧主持人控制按键模块:
图9 主持人控制按键
本次硬件设计简单来说由:AT89C51最小系统、显示模块、按键模块LED灯和蜂鸣器模块组成。
当接通电源开始工作后,单片机中的程序开始运行,将对程序进行初始化。完成初始化后,将进行键盘扫描,同时判断开始按键、调节按键是否按下。最后完成倒计时和选手号码的显示等功能。
软件流程图如下图所示:
图10 软件流程图
1、选手违规抢答:以第1位选手违规抢答为例,对应选手的LED灯亮起,LED显示屏显示对应违规选手号码,蜂鸣器先响起1秒警示,如果未进行复位操作,则蜂鸣器将再会响起,同时倒计时警示LED灯会闪烁提示。(第1-8位选手都是如此)
2、抢答时间调整:如果按下抢答时间加键或抢答时间减键,LED显示屏显示对应的调整时间,时间调整范围为0-99秒,超过99秒或低出0秒则返回去10秒。本次将抢答时间增加到15秒。
3、答题时间调整:如果按下答题时间加键或答题时间减键,LED显示屏显示对应的调整时间,时间调整范围为0-99秒,超过99秒或低出0秒则返回去10秒。本次将答题时间减少到8秒。
4、主持人按下开始键:抢答时间开始倒计时,最后几秒抢答时间倒计时警示LED灯将闪烁,要是选手没有选择抢答,则蜂鸣器会不断响起,LED显示屏熄屏,除非按下复位键开启新的一轮。
5、主持人按下开始键:抢答时间开始倒计时,最后几秒抢答时间倒计时警示LED灯将闪烁,要是选手选择抢答,则对应选手的LED灯会亮起。
6、要是选手在抢答时间按下抢答键,进入答题时间:答题时间最后几秒倒计时LED灯亮起,蜂鸣器不断响起,提示按下复位键,开始新的一轮。
6、要是选手在抢答时间按下抢答键,进入答题时间:答题时间内主持人可以按下答题时间暂停键,则显示屏时间暂停,按下答题时间暂停键的第一瞬间LED显示屏熄屏,倒计时LED警示灯亮起,松下答题时间暂停键的第一瞬间LED显示屏显示暂停的时间,倒计时LED警示灯熄灭,除非按下复位键,开始新的一轮。
代码部分主要由四个模块组成,分别为主程序、显示子程序、时间按键调整子程序、选手按键子程序、开始键子程序、延迟子程序、定时器T0初始化子程序和蜂鸣器和LED灯子程序。
1、主程序:
主程序完成定时器0的初始化、74LS138芯片的初始化和扫描主持人按键,进行对应的操作。
2、显示子程序:
此函数大方向分为开始键按下和开始键没有按下的两种情况。同时两个大方向又各自细分两个小方向。当开始键按下,则有选手在抢答时间按下显示选手号码在LED显示屏上,要是没有则不显示号码。同时显示屏上显示抢答和答题的倒计时。当开始键没有按下,如果有人违规抢答,则显示屏显示违规号码。如果按下答题时间或抢答时间调整键,则对应显示屏进行更新数据操作。
3、时间按键调整子程序:
此函数很简单,要是按下抢答时间或答题时间调整键,则对应时间将进行操作,调整范围为0-99秒,超出99秒或低于0秒,则返回到10秒。
4、选手按键子程序:
以K1为例,程序一直判断按键引脚电压,按下按键电压为0。按键会产生抖动,需要进行消抖处理,先进行消抖延迟10ms,如果按键电压还是0,确定没问题K1进行操作,令按键数目num为1,供主函数处理按键消息。同时将74LS138的对应输入口赋值,数码管显示工作,定时器1和0也进行对应工作。K1-K8功能都是一样的操作。
5、开始键子程序:
如果按下开始键,程序一直判断按键引脚电压,按下按键电压为0。按键会产生抖动,需要进行消抖处理,先进行消抖延迟10ms,如果按键电压还是0,确定没问题K0进行操作.将对应的标志位进行开始工作,将清除违规标志位、开始抢答时间调整键标志位和答题计时时间调整键标志位停止运行。
6、延迟子程序:
确定51单片机为12MHz频率,以此确定ms的延迟子函数。
7、定时器T0初始化子程序:
将定时器T0进行初始化,运用方式1,即16位计数器。取高八位和第八位寄存器进行定时操作。
8、蜂鸣器和LED灯子程序:
用定时器0和定时器1确定蜂鸣器响多久和LED灯亮。
- #include<reg51.h>
-
- #define uchar unsigned char
- #define uint unsigned int
-
- char s;
- uchar num=0;//谁抢到的号码,初始化为0
- char snaptime=10;//抢答时间
- char answertime=10;//答题时间
- uint t0,t1; //T0,T1定时器
- bit flag,s_flag=1,b_flag,fall_flag;//标志位
- bit K_snaptimeflag,K_answertimeflag;//时间调整标志位
-
- sbit K0=P3^0;
- sbit beep=P3^7;//蜂鸣器输出口
- sbit led=P2^4;//指示灯输出口
- sbit K1=P1^0;
- sbit K2=P1^1;
- sbit K3=P1^2;
- sbit K4=P1^3;
- sbit K5=P1^4;
- sbit K6=P1^5;
- sbit K7=P1^6;
- sbit K8=P1^7;
- sbit K_Time=P2^5;//答题暂停键
- sbit K_startcount=P2^6;//开始抢答时间+调整键
- sbit K_timecount=P3^4;//答题计时时间+调整键
- sbit K_startcount0=P2^7;//开始抢答时间-调整键
- sbit K_timecount0=P3^5;//答题计时时间-调整键
- sbit G=P3^1;
- sbit H=P3^2;
- sbit I=P3^3;
- sbit J=P3^6;
- uchar code tabledu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- uchar code tablewe[]={0XFE,0XFD,0XFB,0XF7};
-
- void delay(uint n)//延时n毫秒
- {
- uint i=0,j=0;
- for(i=0;i<n;i++)
- for(j=0;j<123;j++);
- }
-
- void T0_Init(void)//定时器T0初始化
- {
- TMOD=0X01;//使用定时器T0的模式1
- TH0=(65536-2000)/256;
- TL0=(65536-2000)%256;
- TH1=(65536-2000)/256;
- TL1=(65536-2000)%256;
- ET0=1;
- ET1=1;
- EA=1;
- P0=0;
- }
-
- void Start_Scan(void) //开始键扫描
- {
- if(K0==0)
- {
- delay(10);
- if(K0==0)
- {
- while(!K0);
- TR0=1;//启动定时器0工作
- s=snaptime;
- t0=0;
- flag=1;
- s_flag=1;
- b_flag=1;
- num=0;
- beep=1;
- led=1;
- fall_flag=0;//清除违规标志位
- K_snaptimeflag=0;//开始抢答时间调整键停止运行
- K_answertimeflag=0;//答题计时时间调整键停止运行
- }
- }
- }
-
- void Select_Scan(void)//八路选择键扫描(哪个键先按下,哪个优先级最高)
- {
- if(K1==0)
- {
- delay(10);
- if(K1==0)
- {
- while(!K1);
- {
- G=0;
- H=0;
- I=0;
- J=1;
- num=1;//数码管显示第1位
- TR0=0;//关闭定时器0工作,时间停止
- TR1=1;//打开定时器1工作 。使扬声器响一声
- s_flag=0;//关闭开始键标志位,使再按其他七个键不会响应
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;
- }
- }
- }
- if(K2==0)
- {
- delay(10);
- if(K2==0)
- {
- while(!K2);
- {
- G=1;
- H=0;
- I=0;
- J=1;
- num=2;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;
- }
- }
- }
- if(K3==0)
- {
- delay(10);
- if(K3==0)
- {
- while(!K3);
- {
- G=0;
- H=1;
- I=0;
- J=1;
- num=3;
- TR0=0;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;
- }
- }
- }
- if(K4==0)
- {
- delay(10);
- if(K4==0)
- {
- while(!K4);
- {
- G=1;
- H=1;
- I=0;
- J=1;
- num=4;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;}
- }
- }
- if(K5==0)
- {
- delay(10);
- if(K5==0)
- {
- while(!K5);
- {
- G=0;
- H=0;
- I=1;
- J=1;
- num=5;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;
- }
- }
- }
- if(K6==0)
- {
- delay(10);
- if(K6==0)
- {
- while(!K6);
- {
- G=1;
- H=0;
- I=1;
- J=1;
- num=6;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;
- }
- }
- }
- if(K7==0)
- {
- delay(10);
- if(K7==0)
- {
- while(!K7);
- {
- G=0;
- H=1;
- I=1;
- J=1;
- num=7;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;}
- }
- }
- if(K8==0)
- {
- delay(10);
- if(K8==0)
- {
- while(!K8);
- {
- G=1;
- H=1;
- I=1;
- J=1;
- num=8;
- TR0=0;
- TR1=1;
- s_flag=0;
- delay(10);
- }
- while(!K_Time);
- {
- s=answertime;
- TR0=1;
- t0=0;
- TR1=1;
- }
- }
- }
- }
-
- void display(void)
- {
- if(flag==1)//开始键按下,开始计时抢答
- {
- if(num!=0)//如果有人抢答,则显示相应的号码
- {
- P0=tabledu[num];//显示几号抢到了
- P2=tablewe[0];
- delay(2);
- P0=0;
- P2=0XFF;
- }
- else//否则没人抢答,则前面不显示几号
- {
- P0=0;
- P2=0XFF;
- }
- P0=tabledu[s/10];//显示抢答倒计时的十位
- P2=tablewe[2];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=tabledu[s%10];//显示抢答倒计时的个位
- P2=tablewe[3];
- delay(2);
- P2=0XFF;
- P0=0;
- }
- if(flag==0)//如果开始键没有按下,若有违规者,则显示违规号码
- {
- if(fall_flag==1)//违规违规
- {
- if(num!=0)
- {
- P0=tabledu[num];//显几号违规了
- P2=tablewe[0];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=tabledu[15];
- P2=tablewe[2];
- delay(2);
- P0=0;//消隐
- P2=0XFF;
- P0=tabledu[15];
- P2=tablewe[3];
- delay(2);
- P0=0;
- P2=0XFF;
- }
- else
- {
- P0=0;
- P2=0XFF;
- }
- }
- else
- {
- if(K_snaptimeflag==1)
- {
- P0=0XF9;//第1位数码管(表示抢答时间调整)
- P2=tablewe[0];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=tabledu[snaptime/10];//第x位数码管(表示抢答时间调整)
- P2=tablewe[2];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=tabledu[snaptime%10];
- P2=tablewe[3];
- delay(2);
- P0=0;
- P2=0XFF;
- }
- else if(K_answertimeflag==1)
- {
- P0=0X07;//第x位数码管(表示答题时间调整)
- P2=tablewe[0];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=0X31;
- P2=tablewe[1];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=tabledu[answertime/10];
- P2=tablewe[2];
- delay(2);
- P0=0;
- P2=0XFF;
- P0=tabledu[answertime%10];
- P2=tablewe[3];
- delay(2);
- P0=0;
- P2=0XFF;
- }
- }
- }
- }
-
- void Time_Scan(void)//调整时间键扫描
- {
- if(K_startcount==0)//抢答时间调整
- {
- delay(10);
- if(K_startcount==0)
- {
- while(!K_startcount);
- snaptime++;
- if(snaptime==99||snaptime==0)
- {
- snaptime=10;
- }
- K_snaptimeflag=1; //将抢答时间标志位置1
- K_answertimeflag=0; //同时关闭答题时间标志位
- }
- }
- if(K_timecount==0) //答题时间调整
- {
- delay(10);
- if(K_timecount==0)
- {
- while(!K_timecount);
- answertime++;
- if(answertime==99||answertime==0)
- {
- answertime=10;
- }
- K_answertimeflag=1;
- K_snaptimeflag=0;
- }
- }
- if(K_startcount0==0)//抢答时间调整
- {
- delay(10);
- if(K_startcount0==0)
- {
- while(!K_startcount0);
- snaptime--;
- if(snaptime==99||snaptime==0)
- {
- snaptime=10;
- }
- K_snaptimeflag=1; //将抢答时间标志位置1
- K_answertimeflag=0; //同时关闭答题时间标志位
- }
- }
- if(K_timecount0==0) //答题时间调整
- {
- delay(10);
- if(K_timecount0==0)
- {
- while(!K_timecount0);
- answertime--;
- if(answertime==99||answertime==0)
- {
- answertime=10;
- }
- K_answertimeflag=1;
- K_snaptimeflag=0;
- }
- }
- }
-
- void main(void)
- {
- T0_Init();
- G=0;
- H=0;
- I=0;
- J=0;
- while(1)
- {
- Start_Scan(); //开始键扫描
- if((flag==0)&(s_flag==1)) //当开始键没按下及没有人违规时才可进行时间调整
- {
- Time_Scan();
- }
- if((flag==1)&(s_flag==0))//当开始键按下及有人抢答才进行开始回答计时倒计时
- {
- led=0;
- if(K_Time==0)
- {
- delay(10);
- if(K_Time==0)
- {
- while(!K_Time);
-
- TR0=0;
- t0=0;
- TR1=1;
- }
- }
- }
- if((flag==0)&(s_flag==1)) //违规
- {
- Select_Scan();
- if(num!=0) //开始键没有按下时,有人按下了抢答器,则置违规标志位
- {
- fall_flag=1;
- led=0;
- }
- }
- if((flag==1)&(s_flag==1)) //如果开始键按下且抢答键没有人按下,则进行八路抢答键扫描
- {
- Select_Scan();
- }
- display(); //显示到数码管上
- }
- }
-
- void timer0(void) interrupt 1//定时器0
- {
- TH0=(65536-2000)/256; //2ms
- TL0=(65536-2000)%256;
- if(b_flag) //开始(START)键按下,嘟一声(长1秒),表示开始抢答
- {
- beep=~beep;
- }
- else
- beep=1;
- if(s<5) //抢答时间快到报警,每1秒响一声且红灯闪烁,响5声
- {
- if(s%1==0)
- {
- b_flag=1;
- led=0;
- }
- else
- {
- b_flag=0;
- led=1;
- }
- }
- t0++;
- if(t0==500) //1秒
- {
- t0=0;
- s--;
- b_flag=0; //关闭开始键按下响一秒的嘟声
- if(s==-1)
- {
- s=20;
- TR0=0;
- flag=0; //显示F FF
- s_flag=1;
- num=0;
- led=1;
- }
- }
- }
-
- void timer1(void) interrupt 3 //定时器1处理有人按下抢答器嘟一声(长1秒)
- {
- TH1=(65536-2000)/256;
- TL1=(65536-2000)%256;
- beep=~beep;
- t1++;
- if(t1==500)
- {
- t1=0;
- TR1=0;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。