找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1508|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机八路抢答器代码与Proteus仿真

[复制链接]
跳转到指定楼层
楼主
8路抢答器设计难度分:9基本要求:8个选手抢答按键,1个主持人按键,4只LED数码管显示。系统复位状态LED显示“00 00”;主持人按下按键则抢答开始,系统显示3秒抢答时间倒计时,计时到无人抢答则系统发出报警后自动复位;8个选手最先按下者抢答成功,显示选手编号和答题时间10秒,支持人发出开始作答指令同时按下主持人键,答题时间开始倒计时并显示,若选手回答结束之后主持人按下主持人键复位系统,若倒计时结束选手未回答问题系统发出报警后自动复位。扩展要求:增加1个“√”键和1个“×”键,只在10秒回答时间内有效,若选手回答正确,主持人按下“√”键彩灯闪烁,若选手回答错误,主持人按下“×”键发出低沉报警音;系统复位后抢答开始前,选手不得提前抢答,否则发出违例报警,显示违例选手编号,由主持人复位系统;可修改答题时间。

仿真原理图如下(proteus8.10版本的仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. //头文件声明
  2. #include<reg52.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int  
  5.                         
  6. //code  uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  7. code  uchar seven_seg[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  8. code uchar seven_bit[] = {0xfe,0xfd,0xfb,0xf7};

  9. sbit run_key = P3^2;  //启动按键
  10. sbit buzzer = P3^5;   //报警
  11. sbit add_key = P3^6;  //加
  12. sbit dec_key = P3^7;  //减
  13. uchar player;    //定义选手按键的键值参数
  14. uint player_num = 0;  //选手号
  15. uchar now_time = 0;  //默认复位时间0S
  16. uchar next_time=10;  //默认答题时间10s
  17. bit run_flag = 0;    //主持人按下开始标志位
  18. bit time_off = 0;    //倒计时时间到,或者开始有人抢答成功标志位
  19. uint Count_A = 0;    //定时器计数参数
  20. uint Count_B = 0;                        //定时器计数参数


  21. void delay(uint ms)   //延时函数
  22. {
  23.         uint i,j;
  24.         for(i=ms;i>0;i--)
  25.                 for(j=110;j>0;j--);
  26. }



  27. void dispaly(uint a,uint b)         //a为选手号码,b为时间
  28. {
  29.         P2=seven_bit[0];
  30.         P0=seven_seg[a];    //显示选手号
  31.         delay(5);
  32.         P2=seven_bit[1];
  33.         P0=0x40;              //显示横杠
  34.         delay(5);
  35.         P2=seven_bit[2];
  36.         P0=seven_seg[b/10];     //显示倒计时时间
  37.         delay(5);
  38.         P2=seven_bit[3];
  39.         P0=seven_seg[b%10];
  40.         delay(5);
  41.         P2=0xff;
  42. }

  43. void keyScan()    //按键子程序
  44. {
  45.         if(run_key==0)   //如果启动按键按下
  46.         {
  47.                 delay(5);    //消抖
  48.                 if(run_key==0)
  49.                 {
  50.                         if(now_time!=next_time)
  51.                         {
  52.                          if(player_num!=0)
  53.                          {
  54.                             now_time=0;                    //答题结束按键按键复位
  55.                                 player_num=0;
  56.                                 time_off=0;//复位选手按下标志
  57.                          }
  58.                          else
  59.                          {
  60.                           player_num=0;
  61.                           run_flag=1;             //设置模式调整
  62.                           buzzer=0;//0.5S声音
  63.                           now_time=3;
  64.                           TR0=1;    //开启定时器
  65.                           TR1=1;
  66.                            }
  67.                         }
  68.                    else
  69.                    {
  70.                            buzzer=0;//0.5S声音
  71.                            TR0=1;    //开启定时器
  72.                         TR1=1;
  73.                   
  74.                    }


  75.                 }

  76.                 while(run_key==0);   //等待按键放开

  77.         }

  78.                         if(run_flag==0&&time_off==0)   //只有没开始抢答的时候可以加减
  79.         {
  80.                 if(add_key==0)
  81.                 {
  82.                         delay(5);
  83.                         if(add_key==0)
  84.                         {
  85.                                  next_time++;    //时间加上去
  86.                           
  87.                         }
  88.                         while(add_key==0)        dispaly(player_num,next_time);  //显示
  89.                 }
  90.                  if(dec_key==0)
  91.                 {
  92.                         delay(5);
  93.                         if(dec_key==0)
  94.                         {
  95.                                  next_time--;     //时间减下来
  96.                         
  97.                         }
  98.                         while(dec_key==0)         dispaly(player_num,next_time);  //显示
  99.                 }
  100.         }



  101. }


  102. void EX_Init()
  103. {
  104.         /*********初始化定时器/外部中断**********/
  105.         TMOD = 0x11;   //10ms
  106.         TH0 = 0x0D8;
  107.   TL0 = 0x0F0;
  108.         TH1 = 0x0D8;
  109.   TL1 = 0x0F0;
  110.         IE = 0x8b;                //IE  = 0x85;
  111.         IT0 = 1;
  112.         IT1 = 1;
  113.         PX0 = 1;
  114.         TR0  = 0;  //关闭定时器
  115.         TR1  = 0;
  116. }



  117. void main(void)
  118. {
  119.         EX_Init();    //初始化
  120.         buzzer=1;
  121.         P2=0xff;
  122.         P1=0xff;
  123.         P0=0xff;
  124.         while(1)       //死循环
  125.         {         
  126.                 keyScan();  //按键程序
  127.                 dispaly(player_num,now_time);  //显示
  128.         }
  129. }



  130. void Time0() interrupt 1
  131. {
  132.         TH0 = 0x0D8;                 //10ms
  133.   TL0 = 0x0F0;

  134.                
  135.                 if(run_flag==1)          //如果开始抢答
  136.                 {
  137.                         player=P1;   //读取端口
  138.                
  139.                         switch(player)
  140.                         {
  141.                                 case 0xfe:player_num=1;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break; //为第一个选手按下时,选手号=1,定时器停止,时间十秒
  142.                                 case 0xfd:player_num=2;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  143.                                 case 0xfb:player_num=3;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  144.                                 case 0xf7:player_num=4;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  145.                                 case 0xef:player_num=5;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  146.                                 case 0xdf:player_num=6;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  147.                                 case 0xbf:player_num=7;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  148.                                 case 0x7f:player_num=8;run_flag=0;time_off=1;TR0=0;TR1=0;now_time=next_time;break;
  149.                                 case 0xff:break;    //全高电平-无人按下,退出
  150.                                 default:player_num=9; break;     //出现其它情况,显示9
  151.                         }
  152.          }
  153. }
  154. void Time1() interrupt 3
  155. {
  156.         TH1 = 0x0D8;
  157.   TL1 = 0x0F0;   //10ms
  158.         Count_A++;
  159.         Count_B++;
  160.         if(Count_B<50)   //500ms的蜂鸣器提示
  161.                 buzzer=0;
  162.         else buzzer=1;
  163.         
  164.         if(Count_A==100)    //每秒钟减一,倒计时
  165.         {        Count_A=0;
  166.                 now_time--;   //当前倒计时时间 --
  167.                 if(now_time<=0)   //倒计时结束(到0),那么开始报警,其它复位
  168.                 {        now_time=0;run_flag=0;TR0=0;TR1=0;time_off=1;buzzer=0;        delay(1200);buzzer=1;}
  169.         }               
  170. }
复制代码

Keil代码与Proteus8.10仿真下载:
抢答器.rar (94.5 KB, 下载次数: 75)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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