proteus论坛|仿真论坛
直播中

刘勇

9年用户 87经验值
擅长:嵌入式技术 连接器 EDA/IC设计
私信 关注

如何用51单片机设计八路抢答器?

本帖最后由 Mr叶 于 2024-3-12 09:41 编辑

设计要求
1)抢答器同时供8名选手或2个代表队比赛,分别用8个按钮S0-S7表示;
2)设置一个系统清除和抢答控制开关S,该开关由主持人控制;
3)抢答器具有锁存与显示功能。即选手按动按钮,锁存相应的编号,并在优先抢答选手的编号一直保持到主持人将系统清除为止;
4)抢答器具有定时抢答功能,且一次抢答的时间由主持人设定(如30s等)。当主持人启动“开始”按键后,定时器进行减计时,同时扬声器发出短暂的声响,声响持续时间为0.5s左右;
5)参赛选手在设定时间内进行抢答,抢答有效,定时器停止工作,显示器上显示选手编号和抢答时间,并保持到主持人将系统清除为止;

部分C代码
  1. /********************************************************
  2. 函数名称:void scan(void)
  3. 函数作用:按键检测函数
  4. 参数说明:
  5. ********************************************************/
  6. void scan(void)
  7. {        
  8.         uchar qiangda_num=0;
  9.         //主持人键
  10.         if(key_zhu==0)                   //按键按下
  11.         {
  12.                 delayms(7);                   //显示消抖
  13.                 if(key_zhu==0&&zhu_f!=2&&qiang_f==0&&wan_f==0)//判断是否有人犯规或者抢答是否开始或者抢答是否完成
  14.                 {
  15.                         zhu_f++;           //比赛阶段标记+1
  16.                         if(zhu_f==2)   //比赛正式开始
  17.                         {
  18.                                 TR0=1;           //比赛开始,开启定时
  19.                                 wan_f=0;   //清除比赛完成标志
  20.                                 bajing();  //提示比赛开始
  21.                         }                        
  22.                 }
  23.                 else
  24.                         if(key_zhu==0&&qiang_f==1)   //判断是否有人犯规
  25.                         {
  26.                                 buzz=1;                                         //清除报警
  27.                                 qiang_f=0;                                 //清除抢答标志
  28.                                 number=0;                                 //清除选手编号
  29.                                 time=EEPROM_read(0x2000);//重新读取存储的抢答总时长
  30.                                 led_kongzhi(0,0,0);
  31.                         }
  32.                         else                                                
  33.                                 if(key_zhu==0&&wan_f==1) //判断是否有人完成
  34.                                 {
  35.                                         buzz=1;                                 //清除报警
  36.                                         wan_f=0;                         //清除完成标志
  37.                                         number=0;                         //清除选手编号
  38.                                         time=EEPROM_read(0x2000);//重新读取存储的抢答总时长
  39.                                         led_kongzhi(0,0,0);
  40.                                 }
  41.                                 else
  42.                                         if(key_zhu==0&&zhu_f==2) //暂停比赛
  43.                                         {
  44.                                                 TR0=0;                                 //关闭定时
  45.                                                 zhu_f=1;                         //重新回到设置比赛时间阶段
  46.                                                 bajing();                         //提示暂停比赛
  47.                                         }
  48.                 while(!key_zhu);//检测按键松开
  49.         }
  50.         //加值键,支持连按
  51.         if(key_jia==0&&zhu_f==1&&qiang_f==0)         //判断是否在设置倒计时时间
  52.         {
  53.                 delayms(7);                                                         //延时消抖
  54.                 if(key_jia==0)                                                 //再次判断按键按下
  55.                 {
  56.                         if(time<99)                             //比赛时间最大值99S
  57.                                 time++;                                                  //比赛时间+1S
  58.                         EEPROM_delete(0x2000);                         //擦除EEPROM煽区
  59.                         EEPROM_write(0x2000,time);                 //写入【比赛时间】数据保存
  60.                         display(time/10,time%10,10,0);         //显示设置比赛时间
  61.                 }
  62.         }
  63.         //减值键,支持连按
  64.         if(key_jian==0&&zhu_f==1&&qiang_f==0)         //判断是否在设置倒计时时间
  65.         {
  66.                 delayms(7);                                                         //延时消抖
  67.                 if(key_jian==0)                                                 //再次判断按键按下
  68.                 {
  69.                         if(time!=0)                                                   //比赛时间最小值0S
  70.                                 time--;                                 //比赛时间-1S
  71.                         EEPROM_delete(0x2000);                         //擦除EEPROM煽区
  72.                         EEPROM_write(0x2000,time);                 //写入【比赛时间】数据保存
  73.                         display(time/10,time%10,10,0);         //显示设置比赛时间
  74.                 }
  75.         }
  76.         //选手按键
  77.         qiangda_num=qianda();
  78.         if(qiangda_num!=0)                              //判断是否有选手按下按键
  79.         {
  80.                 if(zhu_f!=2&&qiang_f==0&&wan_f==0)//如果还没有开始抢答时按下
  81.                 {
  82.                         zhu_f=1;
  83.                         buzz=0;                                                  //蜂鸣器报警
  84.                         qiang_f=1;                                          //抢答犯规标记
  85.                         number=qiangda_num;
  86.                         led_kongzhi(number,1,0);
  87.                 }
  88.                 else
  89.                         if(zhu_f==2&&wan_f==0)                         //在开始抢答时按下
  90.                         {
  91.                                 wan_f=1;                                         //标记抢答完成
  92.                                 zhu_f=0;                                         //主持人标记复位
  93.                                 TR0=0;                                                 //关闭倒计时定时器
  94.                                 number=qiangda_num;
  95.                                 led_kongzhi(number,1,0);
  96.                                 bajing();                                         //提示有人抢答完成
  97.                         }
  98.         }  
  99. }
  100. /*********************************************************
  101. 函数名称:void main()
  102. 函数作用:主函数函数
  103. 参数说明:
  104. *********************************************************/
  105. void main()
  106. {
  107.         uchar i=0;
  108.         T0_init();                                                 //定时器初始化
  109.         if(key_jian==0)         
  110.         {
  111.                 delayms(100);
  112.                 if(key_jian==0)
  113.                 {
  114.                         EEPROM_delete(0x2000);         //擦除EEPROM煽区
  115.                         EEPROM_write(0x2000,30); //写入【比赛时间】数据保存
  116.                 }
  117.         }
  118.         time=EEPROM_read(0x2000);                 //读取存储的【比赛时间】数据
  119.         for(i=0;i<9;i++)
  120.         {
  121.                 led_kongzhi(i,1,1);
  122.                 delayms(10);        
  123.         }
  124.         for(i=9;i>0;i--)
  125.         {
  126.                 led_kongzhi(i-1,0,1);
  127.                 delayms(10);        
  128.         }
  129.         led_kongzhi(0,0,0);
  130.         while(1)                                                 //死循环
  131.         {
  132.                 scan();                                                 //按键检测处理
  133.                 if(zhu_f==0&&wan_f==0)                 //判断是否还没进入比赛阶段

更多回帖

发帖
×
20
完善资料,
赚取积分