基于51单片机的五路抢答器Protues仿真设计

打印 上一主题 下一主题

主题 552|帖子 552|积分 1656

目次
一、设计背景
二、实现功能
三、仿真演示
四、源步调(部分)


一、设计背景

        近年来随着科技的飞速发展,单片机的应用正在不停的走向深入。本文阐述了基于51单片机的五路抢答器设计。本设计中,51单片机充当了焦点控制器的角色,通过IO口与各个功能模块相连接。按键模块负责检测参与者的抢答动作,当有人按下抢答按钮时,会通过IO口电平的变化关照单片机,单片时机记载按键的序次,并通过数码管显示当前的抢答结果。
        为了包管抢答过程的准确性和公平性,设计中还必要思量到以下因素。首先,按键模块必要具备快速相应和高可靠性,以确保抢答者的动作能够被准确地捕捉到。其次,显示屏模块必要能够及时更新抢答结果,并显示相应的信息,比如参与者的编号和抢答时间。末了,在电路连接方面,必要注意各个模块之间的线路布局,以避免信号干扰和电气题目。
       软件系统采用C语言编写步调,包括显示步调,定时中断服务,延时步调等,并在KEIL5中调试运行,硬件系统利用PROTEUS8.11强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。
二、实现功能

        以51单片机为控制焦点,设计一种五路抢答器。整个系统包括MCU、晶振电路、时钟电路、蜂鸣器控制电路、指示灯控制电路、独立按键电路、矩阵键盘以及数码管显示电路等。可具体实现以下功能:
     (1)设定矩阵键盘的5个键作为5位选手的抢答按键,键的编号即选手编号,为1~5号,同时设定5个LED灯作为5位选手抢答状态指示;设定1个独立按键作为抢答开始键;选择两位数码管作为倒计时、选手编号及犯规显示;选择蜂鸣器作为开始、抢答、犯规和计时结束的提示。
     (2)只有当裁判按下开始键时才可以进入正常抢答,否则属于犯规抢答。抢答完毕,或计时时间到,停止抢答,数码管显示0。当裁判按下抢答开始键时,开始抢答,计时器开始倒计时,10秒倒计期间,若有抢答,则停止计时,相应选手的LED灯亮,数码管显示选手号;若倒计时结束时无人抢答,则停止抢答。
     (3)正确抢答时,抢答选手的LED灯迟钝闪烁,数码管显示抢答选手的编号;犯规抢答时,犯规选手的LED灯快速闪烁,低位数码管显示犯规选手的编号,高位数码管显示F(foul,犯规)。
       (4)开始抢答按键按下时、倒计时结束时和抢答键按下时蜂鸣器响1声,犯规时响2声。
三、仿真演示

未运行仿真时,数码管不显示。

运行仿真后,进入准备界面,数码管显示00。

按下启动按键,蜂鸣器响一声,进入抢答界面,开始10秒抢答倒计时。

在抢答倒计时范围内,按下序号为1~5的选手抢答按键,蜂鸣器响1声,数码管上显示抢答选手序号,而且相应序号的指示灯迟钝闪烁4次。
当裁判未按下开始键时,若有选手抢答视为犯规抢答,蜂鸣器响2声指示犯规抢答犯规选手的LED灯快速闪烁20次,低位数码管显示犯规选手的编号,高位数码管显示F。

无论是正常抢答还是犯规抢答,指示灯停止闪烁后,数码管显示00,表示一次抢答结束。

按下复位按钮规复到准备界面,以便进行下一次抢答。

四、源步调(部分)

  1. #include "reg52.h"
  2. #include "delay.h"
  3. #include "smg.h"
  4. #include "timer.h"
  5. sbit key1Led = P3^1;        //四位选手
  6. sbit key2Led = P3^2;
  7. sbit key3Led = P3^3;
  8. sbit key4Led = P3^4;
  9. sbit key5Led = P3^5;
  10. sbit start_stop = P3^6;        //抢答按钮
  11. sbit Beep = P3^7;        //抢答按钮
  12. _bool action = 0;
  13. _bool key1_flag = 0;
  14. _bool key2_flag = 0;
  15. _bool key3_flag = 0;
  16. _bool key4_flag = 0;
  17. _bool key5_flag = 0;
  18. _bool Rush_flag = 0;
  19. _bool reset_flag = 0; //复位标志位
  20. _bool start_stop_flag = 0; //抢答标志位
  21. _bool BeepF=0;       
  22. uint8 second = 0;        //时间
  23. uint8 timer0_count = 0;        //定时器1计数值
  24. uint8 LedFre0Count = 0;
  25. uint8 LedFre1Count = 0;
  26. uint8 number = 0; //队号
  27. uint8 number_display = 0;        //队号显示
  28. uint8 a = 0xff;        //按键值
  29. uint8 key_scan8(void);
  30. uint8 Fval = 0;
  31. void start_stop_keyscan(void);
  32. void keycheckdown(void);                                /* 反转法键盘扫描 */
  33. /*-----------------------------------------------------------
  34. 主函数
  35. ------------------------------------------------------------*/
  36. void LedDisplay(uint8 _number)
  37. {
  38.         switch(_number)
  39.         {
  40.                 case 1:
  41.                         key1Led=~key1Led;
  42.                 break;
  43.                 case 2:
  44.                         key2Led=~key2Led;
  45.                 break;
  46.                 case 3:
  47.                         key3Led=~key3Led;
  48.                 break;
  49.                 case 4:
  50.                         key4Led=~key4Led;
  51.                 break;
  52.                 case 5:
  53.                         key5Led=~key5Led;
  54.                 break;
  55.         }
  56. }
  57. void SMG_delay(uint8 t)
  58. {
  59.         while(t--)
  60.         {
  61.           display(second);
  62.         }
  63. }
  64. void SMG_Bdelay(uint8 t)
  65. {
  66.         while(t--)
  67.         {
  68.       P2 = 0xfe;
  69.                         P0 = table[number_display];
  70.                         Delay_ms(2);
  71.                        
  72.                         P2 = 0xfd;
  73.                         P0 = table[15];
  74.                         Delay_ms(2);               
  75.         }
  76. }
  77. void keycheckdown()                                /* 反转法键盘扫描 */
  78. {
  79.         short temp1,temp2,temp;
  80.         P1=0xf0;                                                /* 输入行值(或列值) */
  81.   SMG_delay(20);
  82.         temp1=P1;                                                /* 读列值(或行值) */
  83.         P1=0xff;
  84.   SMG_delay(20);
  85.         P1=0x0f;                                                /* 输入列值(或行值) */
  86.   SMG_delay(20);
  87.         temp2=P1;                                                /* 读行值(或列值) */
  88.         P1=0xff;
  89.         temp=(temp1&0xf0)|(temp2&0xf);        /* 将两次读入数据组合 */
  90.         switch(temp)                                        /* 通过读入数据组合判断按键位置 */
  91.         {
  92.                 case 0x77 :a=0x0a;break;//  按键+   
  93.                 case 0x7b :a=0x0e; break;// 按键=       
  94.                 case 0x7d :a=0;           break;// 按键0
  95.                 case 0x7e :a=0x0f; break;// 按键CE
  96.                 case 0xe7 :a=0x0d;break;//         按键/
  97.                 case 0xeb :a=0x9;break; //  按键9
  98.                 case 0xed :a=0x8;break; //  按键8
  99.                 case 0xee :a=0x7;break; //         按键7
  100.                 case 0xd7 :a=0x0c;break;//  按键*
  101.                 case 0xdb :a=0x6;break; //         按键6
  102.                 case 0xdd :a=0x5;Beep=0;SMG_delay(500);Beep=1;break; //         按键5
  103.                 case 0xde :a=0x4;Beep=0;SMG_delay(500);Beep=1;break; //         按键4
  104.                 case 0xb7 :a=0x0b; break;// 按键-
  105.                 case 0xbb :a=3;Beep=0;SMG_delay(500);Beep=1;break;        //  按键3
  106.                 case 0xbd :a=2;Beep=0;SMG_delay(500);Beep=1;break;        //  按键2
  107.                 case 0xbe :a=1;Beep=0;SMG_delay(500);Beep=1;break;        //  按键1
  108.                 default :a=0xff;
  109.         }
  110. }
  111. void main()
  112. {
  113.         ConfigTimer0();//定时器初始化
  114.         while(1)
  115.         {
  116.                 start_stop_keyscan();//开始按键
  117.                 keycheckdown();//键盘扫描       
  118.                 Fval=key_scan8();
  119.                 if(action)//有队抢答
  120.                 {
  121.                    second=10;
  122.                 }
  123.                 else
  124.                 {
  125.                         if(a!=0xff)
  126.                         {
  127.                            Rush_flag=1;//违规抢答
  128.                                  second=8;
  129.                                  TR0=1;
  130.                         }               
  131.                 }
  132.     while(Rush_flag==1)
  133.                 {
  134.                         if(BeepF==0)
  135.                         {
  136.                                 Beep=0;
  137.                                 SMG_Bdelay(200);
  138.                                 Beep=1;       
  139.                                 SMG_Bdelay(200);
  140.                                 Beep=0;
  141.                                 SMG_Bdelay(200);
  142.                                 Beep=1;       
  143.         BeepF=1;                               
  144.                         }
  145.                         P2 = 0xfe;
  146.                         P0 = table[number_display];
  147.                         Delay_ms(2);
  148.                        
  149.                         P2 = 0xfd;
  150.                         P0 = table[15];
  151.                         Delay_ms(2);               
  152.                         if(second==0)
  153.                         {
  154.                                 Rush_flag=0;
  155.                                 TR0=0;
  156.                                 key1Led = 1;       
  157.                                 key2Led = 1;
  158.                                 key3Led = 1;
  159.                                 key4Led = 1;
  160.                                 key5Led = 1;       
  161.         BeepF=0;                                       
  162.                                 break;
  163.                         }
  164.                 }
  165.                 while(action==1)//按下开始键为1,抢答结束为0
  166.                 {
  167.                         while(!key_scan8())        //无队抢答
  168.                         {
  169.                                 display(second);
  170.                                 TR0 = 1;
  171.                                 if(second == 0)
  172.                                 {
  173.                                         Beep=0;
  174.                             SMG_delay(200);
  175.                             Beep=1;
  176.                                         break;
  177.                                 }
  178.                                 keycheckdown();//键盘扫描       
  179.                         }
  180.                         if(number_display)//有队抢答
  181.                         {
  182.                                 second=8;
  183.                         }
  184.                         while(number_display)
  185.                         {
  186.                                 display(number_display);
  187.                                 if(second == 0)
  188.                                 {
  189.                                         key1Led = 1;       
  190.                                         key2Led = 1;
  191.                                         key3Led = 1;
  192.                                         key4Led = 1;
  193.                                         key5Led = 1;                                       
  194.                                         break;                       
  195.                                 }
  196.                         }
  197.                         TR0 = 0;//时间到
  198.                         second=0;
  199.                         display(second);
  200.                         action = 0;//抢答结束
  201.                         break;
  202.                 }
  203.                 display(second);       
  204.         }
  205. }
  206. /*-----------------------------------------------------------
  207. 中断服务函数
  208. ------------------------------------------------------------*/
  209. void timer0() interrupt 1
  210. {
  211.         TH0 = (65536-50000)/256; //50ms
  212.         TL0 = (65536-50000)%256;       
  213.         timer0_count ++;
  214.         if(timer0_count == 20)//1s
  215.         {
  216.                 timer0_count = 0;
  217.                 second--;        //10s倒计时
  218.                 if(second == 0)//计时结束
  219.                 {
  220.                         TR0 = 0;
  221.                         number_display = 0;
  222.                         action = 0;
  223.                         second = 0;
  224.                 }
  225.         }       
  226.         if(number_display!=0)
  227.         {
  228.                 if(Rush_flag==0)
  229.                 {  
  230.                          LedFre0Count++;
  231.                          if(LedFre0Count==20)
  232.                          {
  233.                                  LedFre0Count=0;
  234.                            LedDisplay(number_display);
  235.                          }
  236.                 }
  237.                 else
  238.                 {
  239.                          LedFre1Count++;
  240.                          if(LedFre1Count==5)
  241.                          {
  242.                                  LedFre1Count=0;
  243.                            LedDisplay(number_display);
  244.                          }       
  245.                 }
  246.         }
  247. }
  248. /*-----------------------------------------------------------
  249. 开始键扫描函数
  250. ------------------------------------------------------------*/
  251. void start_stop_keyscan(void)
  252. {
  253.         if(start_stop == 0)
  254.         {
  255.                 SMG_delay(800);
  256.                 if((start_stop == 0)&&(!start_stop_flag))
  257.                 {
  258.                         start_stop_flag = 1;
  259.                         action = 1;
  260.                         TR0 = 1;
  261.                         Beep=0;
  262.                         SMG_delay(200);
  263.                         Beep=1;
  264.                         reset_flag = 0;
  265.                 }
  266.         }
  267.         else
  268.         {
  269.                 start_stop_flag = 0;       
  270.         }
  271. }
  272. /*-----------------------------------------------------------
  273. 四位抢答键扫描函数
  274. ------------------------------------------------------------*/
  275. uint8 key_scan8(void)
  276. {
  277.         if((a == 1)&&(!key1_flag))
  278.         {
  279.                 key1_flag = 1;
  280.                 number  = 1;
  281.                 number_display = number;
  282.         }
  283.         else
  284.         {
  285.                 key1_flag = 0;
  286.                 number  = 0;       
  287.         }
  288.        
  289.         if((a == 2)&&(!key2_flag))
  290.         {
  291.                 key2_flag = 1;
  292.                 number  = 2;
  293.                 number_display = number;
  294.         }
  295.         else
  296.         {
  297.                 key2_flag = 0;
  298.                 number  = 0;       
  299.         }
  300.        
  301.         if((a == 3)&&(!key3_flag))
  302.         {
  303.                 key3_flag = 1;
  304.                 number  = 3;
  305.                 number_display = number;
  306.         }
  307.         else
  308.         {
  309.                 key3_flag = 0;
  310.                 number  = 0;       
  311.         }
  312.        
  313.         if((a == 4)&&(!key4_flag))
  314.         {
  315.                 key4_flag = 1;
  316.                 number  = 4;
  317.                 number_display = number;
  318.         }
  319.         else
  320.         {
  321.                 key4_flag = 0;
  322.                 number  = 0;       
  323.         }
  324.         if((a == 5)&&(!key5_flag))
  325.         {
  326.                 key5_flag = 1;
  327.                 number  = 5;
  328.                 number_display = number;
  329.         }
  330.         else
  331.         {
  332.                 key5_flag = 0;
  333.                 number  = 0;       
  334.         }                       
  335.        
  336.         if(number_display != 0)       
  337.         {
  338.                 return 1;
  339.         }
  340.         else
  341.         {
  342.                 return 0;
  343.         }       
  344. }
复制代码
仿真源文件及源步调百度网盘链接:https://pan.baidu.com/s/12J02HAeeTJgKW468viFx1g 
提取码:kc9n 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

滴水恩情

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表