以单片机为核心,设计一个8位竞赛抢答器:同时供8名选手或8个代表队比赛,分别用8个按钮S0-S7表示。
设置一个系统清除和抢答控制按钮,由主持人控制。
抢答器具有锁存与显示功能。即选手按按钮,锁存相应编号,并在优先抢答选手的编号一直保持到主持人将系统清零。
抢答器具有定时抢答功能,且一次抢答的时间由主持人设定。
当主持人启动“开始”键后,定时器进行减计时,同时扬声器发出短暂的声响,声响持续的时间为0.5s左右。
参赛选手在设定时间内进行抢答,抢答有效,定时器停止工作,显示器上显示选手的编号和抢答时间,并保持到主持人将系统清除为止。
如果定时时间已到,无人抢答,本次抢答无效,系统报警并禁止抢答,定时显示器上显示00.
通过按键改变抢答时间。
单片机源程序如下:- #include "reg51.h"
- #include "max7219.h"
- sbit beep=P3^7;//蜂鸣器
- sbit k1=P2^0;//清零/设置
- sbit k2=P2^1;//开始
- uint beep_time=0;//蜂鸣器延时
- uchar mode=0;//模式,0复位,1开始,2设置,3停止,4超时错误
- uchar sec=0,miao=10,miao_set=10;//倒计时
- uchar num=0;
- void main()
- {
- TMOD|=0X01;
- TH0=0X3C;
- TL0=0XB0;
- TH1=0XFC;
- TL1=0X18;
- ET1=1;
- ET0=1;//打开定时器0中断允许
- EA=1;//打开总中断
- TR0=1;//打开定时器
- TR1=1;
- max_init(4);
- max_send_byte(1,miao/10);//初始化显示
- max_send_byte(2,miao%10);
- max_send_byte(3,num/10);
- max_send_byte(4,num%10);
- while(1)
- {
- if(mode>2)//开始模式
- {
- if(!k1)//复位
- {
- mode=0;//复位模式
- miao=miao_set;//复位倒计时
- num=0;
- max_send_byte(1,miao/10);//显示
- max_send_byte(2,miao%10);
- max_send_byte(3,num/10);
- max_send_byte(4,num%10);
- while(!k1);
- }
- }
- if(mode==0)//复位状态
- {
- if(!k2)//开始
- {
- mode=1;//开始模式
- miao=miao_set;
- beep_time=500;//启动蜂鸣器
- while(!k2);
- }
- if(!k1)//设置时间
- {
- if(miao_set<30)
- miao_set++;
- else
- miao_set=0;
- max_send_byte(1,miao_set/10);//显示
- max_send_byte(2,miao_set%10);
- while(!k1);
- }
- }
- if(mode==1)//抢答模式
- {
- switch(P1)
- {
- case 0xfe:mode=3;num=1;//选手1
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0xfd:mode=3;num=2;//选手2
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0xfb:mode=3;num=3;//选手3
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0xf7:mode=3;num=4;//选手4
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0xef:mode=3;num=5;//选手5
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0xdf:mode=3;num=6;//选手6
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0xbf:mode=3;num=7;//选手7
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- break;
- case 0x7f:mode=3;num=8;//选手8
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- beep_time=3000;//启动蜂鸣器
- }
- }
- }
- }
- void Timer0() interrupt 1//定时器中断
- {
- TH0=0X3C;//重装50ms
- TL0=0XB0;
- if(mode==1)//开始模式
- {
- if(sec<20) //计时1s
- sec++;
- else
- {
- sec=0;
- if(miao>0)//倒计时
- {
- miao--;
- max_send_byte(1,miao/10);//显示
- max_send_byte(2,miao%10);
- }
- else
- {
- mode=4;//超时
- num=0;
- beep_time=3000;
- max_send_byte(1,miao/10);//显示
- max_send_byte(2,miao%10);
- max_send_byte(3,num/10);//显示
- max_send_byte(4,num%10);
- }
- }
- }
- }
- void Timer1() interrupt 3//定时器1中断
- {
- TH1=0XFC; //重装定时器
- TL1=0X18;
- if(beep_time>0)//蜂鸣器响
- {
- beep_time--;//蜂鸣器计时减一
- beep=!beep; //蜂鸣器取反,产生500HZ频率
- }
- else
- beep=1; //关闭蜂鸣器
- }
复制代码- #include "max7219.h"
- #include "intrins.h"
- //数码管地址从1到8
- void max_send_byte(uchar addr,uchar i) //发送i到addr
- {
- uchar k=0;
- uchar a;
- a=addr;
- max_load=0;
- for(k=0;k<8;k++)
- {
- if((a & 0x80)>0)
- max_din=1;
- else
- max_din=0;
- a<<=1;
- max_clk=0;
- _nop_();
- max_clk=1;
- }
- a=i;
- for(k=0;k<8;k++)
- {
- if((a & 0x80)>0)
- max_din=1;
- else
- max_din=0;
- a<<=1;
- max_clk=0;
- _nop_();
- max_clk=1;
- }
- max_load=1;
- }
- //初始化
- //i设置数码管个数
- void max_init(uchar i)
- {
- max_send_byte(0x0b,i);//设置个数
- max_send_byte(0x09,0xff);//译码方式
- max_send_byte(0x0a,0x0f);//最亮
- max_send_byte(0x0c,0x01);//开启显示
- max_send_byte(0x00,0x00);//关闭测试功能
- }
复制代码
仿真程序:
资料.7z
(2.96 MB, 下载次数: 0)
|