(1)抢答器同时供 8 名选手比赛,分别用8个按钮 s1-s8表示(要求用户使用4*4键盘); (2)设置一个系统清除和抢答控制开关按键1和按键2。 (3)抢答器具有锁存与显示功能。即选手按下按钮,锁存相应编号,显示该选手编号至数码管,并且该编号保存至主持人按下清除键按键1清除为止。 (4)抢答器具有定时抢答功能,一次抢答设定的时间为X秒(X可自己设置)。主持人按下抢答控制开关按键2,抢答才能开始,启动定时器,并将倒数计时时间用数码管显示。若定时时间到,无人抢答,则该轮抢答结束,系统通过蜂鸣器报警,选手禁止抢答。(5)选手在设定的时间内进行抢答,抢答有效,定时器停止工作,蜂鸣器报警,数码管显示选手编号及倒计时剩余时间,并保持到主持人将系统清除为止。
Proteus仿真:
LY-51S开发板实物:
[ i]
单片机源程序如下:
- #include<reg52.h> //头文件
- #define uchar unsigned char //宏定义
- #define uint unsigned int //宏定义
- //单片机引脚定义
- #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
- #define KEY P3
- sbit LATCH1=P2^6;//定义锁存使能端口 段锁存
- sbit LATCH2=P2^7;// 位锁存
- sbit BEEP = P1^4;
- uchar code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
- uchar code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
- uchar TempData[8]; //存储显示值的全局变量
- #define TIMEINIT 10
- uchar time=TIMEINIT; //倒计时
- uchar player = 0;
- //延时函数
- void DelayMS(uint ms)
- {
- uchar t;
- while(ms--)
- {
- for(t=0;t<120;t++);
- }
- }
- //简单延时
- void Delay(unsigned int t)
- {
- while(--t);
- }
- //显示驱动
- void Display(unsigned char FirstBit,unsigned char Num)
- {
- unsigned char i;
- for(i=0;i<Num;i++)
- {
- DataPort=0; //清空数据,防止有交替重影
- LATCH1=1; //段锁存
- LATCH1=0;
-
- if(i<2)
- {
- DataPort=dofly_WeiMa[i+FirstBit]; //取位码
- LATCH2=1; //位锁存
- LATCH2=0;
- }else
- {
- DataPort=dofly_WeiMa[i+FirstBit+2]; //取位码
- LATCH2=1; //位锁存
- LATCH2=0;
- }
- DataPort=TempData[ i]; //取显示数据,段码
- LATCH1=1; //段锁存
- LATCH1=0;
-
- Delay(200); // 扫描间隙延时,时间太长会闪烁,太短会造成重影
- }
- }
- //按键扫描
- uchar Keys_Scan()
- {
- uchar KeyNO=16;
- uchar Tmp;
- KEY = 0x0f;
- DelayMS(10);
- Tmp = KEY ^ 0x0f;
- switch(Tmp)
- {
- case 1: KeyNO = 0; break;
- case 2: KeyNO = 1; break;
- case 4: KeyNO = 2; break;
- case 8: KeyNO = 3; break;
- default: KeyNO = 16;
- }
- KEY = 0xf0;
- DelayMS(1);
- Tmp = KEY >> 4 ^ 0x0f;
- switch(Tmp)
- {
- case 1: KeyNO += 0; break;
- case 2: KeyNO += 4; break;
- case 4: KeyNO += 8; break;
- case 8: KeyNO += 12;
- }
- return KeyNO;
- }
- //显示数据
- void Display_Data()
- {
- uint num = 1234;
- TempData[0]=dofly_DuanMa[player/10];//分解显示信息,如要显示68,则68/10=6 68%10=8
- TempData[1]=dofly_DuanMa[player%10];
-
- TempData[2]=dofly_DuanMa[(time)/10];
- TempData[3]=dofly_DuanMa[(time)%10];
- Display(0,4);
- }
- //初始化定时器
- void Init_Time()
- {
- TMOD=0x01; //设置定时器模式
- TH0=(65536-46080)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
- TL0=(65536-46080)%256;//46080的来历,为50000*11.0592/12 //设置初值
- ET0=1; //开T0定时器中断
- EA=1; //开总中断
- }
- void BeepON()
- {
- int i;
- for(i=0;i<20;i++)
- {
- BEEP = 0;
- Delay(5000);
- BEEP = 1;
- Delay(5000);
- }
- }
- //主函数
- main()
- {
- uchar flag = 0;
- uchar temp;
- BEEP = 1;
- Init_Time(); //初始化定时器
- while(1)
- {
- temp=Keys_Scan(); //获取选手
- if(temp!=16) //有按键按下
- {
- if(temp ==8) //抢答键,启动键
- {
- TR0 = 1; //启动定时器
- flag =1; //1:运行中
- }
- if(temp ==9) //清零键
- {
- time = TIMEINIT; //时间恢复为10,初始值
- player = 0; //选手号清零
- flag =0; //0:暂停
- TR0 = 0; //关闭定时器
- }
- if(temp ==10) //加键
- {
- if(flag == 0) //暂停
- {
- time+=1;; //时间加
- Delay(50000);
- }
- }
- if(temp ==11) //减键
- {
- if(flag == 0) //暂停
- {
- time-=1;; //时间减
- Delay(50000);
- }
- }
- if(temp<8) //选手按下按键
- {
- if((flag==1)&&(time>0)) //程序执行中
- {
- player=temp+1; //获取选手编号
- flag = 0; //暂停
- TR0 = 0; //停止计数
- /*
- BEEP = 0;
- Delay(35000);
- BEEP = 1;
- */
- BeepON();
- }
- }
- }
- if((flag==1)&&(time==0)) //结束报警
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei附件下载:
八路抢答器.7z
(2.25 MB, 下载次数: 72)
|