找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机八路抢答器程序

[复制链接]
跳转到指定楼层
楼主
ID:719206 发表于 2020-4-1 20:01 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
  1. //包含头文件
  2. #include<reg51.h>
  3. #include <intrins.h>
  4. //宏定义
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. #include "eeprom52.h"
  8. sbit start=P3^0;          //主持人按键开始
  9. sbit reset=P3^1;        //复位

  10. sbit add1=P3^2;           //抢答时间调整,加1
  11. sbit dec1=P3^3;           //抢答时间调整,减1
  12. sbit add2=P3^4;                   //答题时间调整,加1
  13. sbit dec2=P3^5;                //答题时间调整,减1

  14. sbit k1=P1^0;
  15. sbit k2=P1^1;
  16. sbit k3=P1^2;
  17. sbit k4=P1^3;
  18. sbit k5=P1^4;
  19. sbit k6=P1^5;      
  20. sbit k7=P1^6;
  21. sbit k8=P1^7;  //选手按键

  22. sbit beep=P3^6;   //蜂鸣器

  23. bit  qd;                        //抢答标志位,=1时开启抢答
  24. bit  dt;                        //答题标志位,=1时开启答题
  25. bit  disp_qd_dt;        //显示抢答还是答题时间标志位,=0时是显示抢答时间,=1时是显示答题时间                                

  26. //uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77};  //0-9代码
  27. unsigned char code tab[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x45,0xDF,0xD7,  0xCE,0xC7,0xDC}; //数字0-9的编码 和H q d
  28. uchar shiwei,gewei,xuanshou,count,p,second;
  29. uchar qd_time,dt_time;                                                //抢答时间,答题时间
  30. uint t,m,n,a,a1,a2,a3,a4,a5,a6,a7,a8;

  31. void Timer()
  32. {
  33.         TMOD=0x01;        //定义工作方式
  34.         TH0=0x3C;  //初值15536,计数50000次,每次1uS,总计50ms
  35.         TL0=0xB0;
  36.         IE=0x82;  //这里是中断优先级控制EA=1(开总中断),ET0=1(定时器0允许中断),这里用定时器0来定时
  37.         TR0=0;          //开启定时器定时
  38. }

  39. void tim(void) interrupt 1 using 1  //为定时中断T0
  40. {
  41.         TH0=0x3C;  //重新赋值
  42.         TL0=0xB0;
  43.         TR0=1;
  44.         count++;   //计数一次时50ms,20次为1s
  45.         if((second<=10)&&(count==10)&&(dt==1))        //计时到500ms时,根据需要蜂鸣器闪烁
  46.                 beep=0;
  47.         if(count==20) //20*50ms=1秒
  48.         {
  49.                 count=0;
  50.                 if(second>=1)
  51.                         second--; //秒减1
  52.                 else
  53.                         TR0=0;
  54.                 if((second<=10)&&(dt==1))                //当秒见到10以下时,控制蜂鸣器闪烁鸣响
  55.                         beep=1;
  56.         }
  57. }

  58. void delay(uint z)  //延时函数
  59. {
  60.         uint x,y;
  61.         for(x=z;x>0;x--)
  62.                 for(y=110;y>0;y--);                        //约1ms
  63. }

  64. /******************把数据保存到单片机内部eeprom中******************/
  65. void write_eeprom()
  66. {
  67.         SectorErase(0x2000);
  68.         byte_write(0x2000, qd_time);
  69.         byte_write(0x2001, dt_time);
  70.         byte_write(0x2060, a_a);        
  71. }

  72. /******************把数据从单片机内部eeprom中读出来*****************/
  73. void read_eeprom()
  74. {
  75.         qd_time = byte_read(0x2000);
  76.         dt_time = byte_read(0x2001);
  77.         a_a     = byte_read(0x2060);
  78. }

  79. /**************开机自检eeprom初始化*****************/
  80. void init_eeprom()
  81. {
  82.         read_eeprom();                //先读
  83.         if(a_a != 1)                //新的单片机初始单片机内问eeprom
  84.         {
  85.                 qd_time = 30;
  86.                 dt_time = 60;
  87.                 a_a = 1;
  88.                 write_eeprom();           //保存数据
  89.         }        
  90. }

  91. void display (void) //显示函数
  92. {
  93.         unsigned char shiwei,gewei,xuanshou;
  94.         shiwei=tab[second/10];                 //将秒数据拆开成两个一位数
  95.         gewei=tab[second%10];
  96.         xuanshou=tab[p];        

  97.         P0=gewei;                //送入P0口的gewei数据
  98.         P2=0x7F;                //个位位选
  99.         delay(5);                //延时5ms
  100.         P2=0xFF;                //关闭位选,防止出现鬼影           下同

  101.         P0=shiwei;                //显示十位
  102.         P2=0xBF;                   //打开显示时间十位的位选
  103.         delay(5);
  104.         P2=0xFF;

  105.         P0=0x80;                //显示横线
  106.         P2=0xDF;                  
  107.         delay(5);
  108.         P2=0xFF;
  109.         
  110.         P0=xuanshou;
  111.         P2=0xEF;            //选手位选
  112.         delay(5);
  113.         P2=0xFF;
  114. }


  115. void keyscan(void)           //按键扫描函数
  116. {
  117.         if(add1==0)                   //判断抢答时间加键是否按下
  118.         {
  119.                 display();           //延时去抖
  120.                 if(add1==0)           //再次判断按键是否按下
  121.                 {
  122.                         p=11;           //显示q 代表抢答时间设置
  123.                         disp_qd_dt=0;        //显示抢答时间
  124.                         qd_time++;                //抢答时间加
  125.                         if(qd_time>=99)        //最大值可以加到99
  126.                                 qd_time=99;
  127.                 }
  128.                 second=qd_time;                //将抢答时间赋值秒数据,用于计时
  129.                 do
  130.                         display();                //调用显示函数
  131.                 while(add1==0);                //按键释放
  132.                 write_eeprom();                           //保存数据
  133.         }

  134.         if(dec1==0)                                //键按键是否按下
  135.         {
  136.                 display();                        //用显示函数代替延时去抖,防止按下按键时屏幕的闪烁
  137.                 if(dec1==0)                        //再次判断按键是否按下
  138.                 {
  139.                         p=11;                        //显示q
  140.                         disp_qd_dt=0;        //标志位置0
  141.                         qd_time--;                //抢答时间减
  142.                         if(qd_time<=1)        //时间减最低值1
  143.                                 qd_time=1;
  144.                 }
  145.                 second=qd_time;                //将抢答时间赋值秒,用于倒计时
  146.                 do
  147.                         display();                //调用显示函数
  148.                 while(dec1==0);                //按键释放
  149.                 write_eeprom();                           //保存数据
  150.         }
  151.         if(add2==0)                                //答题时间设置参照抢答时间设置部分注释
  152.         {
  153.                 display();
  154.                 if(add2==0)
  155.                 {
  156.                         p=12;
  157.                         disp_qd_dt=1;
  158.                         dt_time++;
  159.                         if(dt_time>=99)
  160.                                 dt_time=99;
  161.                 }
  162.                 second=dt_time;
  163.                 do
  164.                         display();
  165.                 while(add2==0);
  166.                 write_eeprom();                           //保存数据
  167.         }

  168.         if(dec2==0)
  169.         {
  170.                 display();
  171.                 if(dec2==0)
  172.                 {
  173.                         p=12;
  174.                         disp_qd_dt=1;
  175.                         dt_time--;
  176.                         if(dt_time<=1)
  177.                                 dt_time=1;
  178.                 }
  179.                 second=dt_time;
  180.                 do
  181.                         display();
  182.                 while(dec2==0);
  183.                 write_eeprom();                           //保存数据
  184.         }
  185. }

  186. void init()                                                   //初始化函数
  187. {   
  188.         t=0;
  189.         beep=1;
  190.         p=10;                                                        //选手号初始为显示H,表示等待
  191.         second=qd_time;                                        //将抢答时间赋值秒
  192. }

  193. void main()                                                        //主函数
  194. {
  195.         uchar i;
  196.         init_eeprom();  //开始初始化保存的数据
  197.     init();                                                        //调用初始化函数
  198.         Timer();                                                //定时器设置
  199.         while(1)                                                //循环
  200.         {
  201.                 if((qd==0)&&(dt==0))               
  202.                         keyscan();                                //扫描按键
  203.                 display();                                        //显示函数

  204.                 if(start==0)                                  //主持人按下开始键
  205.                 {
  206.                         if((qd==0)&&(dt==0))        //在非抢答,非答题状态下
  207.                         {
  208.                                 p=10;                                //显示H
  209.                                 disp_qd_dt=0;                //标志位置0
  210.                                 second=qd_time;                //抢答时间赋值秒
  211.                                 qd=1;                                //开始抢答
  212.                         }
  213.                         beep=0;                                        //蜂鸣器长响一声
  214.                         for(i=0;i<20;i++)                //此处用于延时
  215.                         {
  216.                                 display();
  217.                         }
  218.                         beep=1;                                        //关闭蜂鸣器
  219.                         TR0=~TR0;                                //定时器开关取反(就是一个开关,按一个就计时,再按一下就停止)

  220.                         do
  221.                                 display();                        //调用显示函数
  222.                         while(!start);                        //等待释放按键        
  223.                 }

  224.                 if(reset==0)                                //复位按键按下时
  225.                 {
  226.                         display();                                //显示函数用做延时去抖
  227.                         if(reset==0)                        //再次判断按键是否按下
  228.                         {
  229.                                 disp_qd_dt=0;                //标志位置0
  230.                                 second=qd_time;
  231.                                 t=0;
  232.                                 p=10;                                //显示H
  233.                                 TR0=0;                                //停止计时
  234.                                 beep=1;
  235.                                 qd=0;
  236.                                 dt=0;                                //停止抢答和答题计时
  237.                         }
  238.                         do
  239.                                 display();
  240.                         while(!reset);
  241.                 }
  242.                 if(qd==1)                                        //开始抢答后,才检测选手按键的状态
  243.                 {
  244.                          if(k1==0)                         //1号选手按下时
  245.                         {
  246.                                 display();                //显示函数用作延时去抖
  247.                                 if(k1==0)                //再次判断按键是否按下
  248.                                 {
  249.                                         t=1;                        //抢答序号置1
  250.                                         qd=0;                        //停止抢答,该位置0后,选手按键按下无效
  251.                                         dt=1;                        //准备答题
  252.                                 }
  253.                         }
  254.                         else if(k2==0)                 //其他选手按键扫描参考1号选手按键注释
  255.                         {
  256.                                 display();
  257.                                 if(k2==0)
  258.                                 {
  259.                                         t=2;
  260.                                         qd=0;
  261.                                         dt=1;
  262.                                 }
  263.                         }
  264.                         else if(k3==0)
  265.                         {
  266.                                 display();
  267.                                 if(k3==0)
  268.                                 {
  269.                                         t=3;
  270.                                         qd=0;
  271.                                         dt=1;
  272.                                 }
  273.                         }
  274.                         else if(k4==0)
  275.                         {
  276.                                 display();
  277.                                 if(k4==0)
  278.                                 {
  279.                                         t=4;
  280.                                         qd=0;
  281.                                         dt=1;
  282.                                 }
  283.                         }
  284.                         else if(k5==0)
  285.                         {
  286.                                 display();
  287.                                 if(k5==0)
  288.                                 {
  289.                                         t=5;
  290.                                         qd=0;
  291.                                         dt=1;
  292.                                 }
  293.                         }
  294.                         else if(k6==0)
  295.                         {
  296.                                 display();
  297.                                 if(k6==0)
  298.                                 {
  299.                                         t=6;
  300.                                         qd=0;
  301.                                         dt=1;
  302.                                 }
  303.                         }
  304.                         else if(k7==0)
  305.                         {
  306.                                 display();
  307.                                 if(k7==0)
  308.                                 {
  309.                                         t=7;
  310.                                         qd=0;
  311.                                         dt=1;
  312.                                 }
  313.                         }
  314.                         else if(k8==0)
  315.                         {
  316.                                 display();
  317.                                 if(k8==0)
  318.                                 {
  319.                                         t=8;
  320.                                         qd=0;
  321.                                         dt=1;
  322.                                 }
  323.                         }
  324.                         if(t)                                        //有选手按下按键时,t的值不为0,进入此if语句
  325.                         {
  326.                                 switch(t)                        //判断t的值
  327.                                 {
  328.                                         case 1:                        //t的值为1时,就是选手1按下按键
  329.                                                 {
  330.                                                         TR0=0;        //停止计时
  331.                                                         p=1;        //数码管显示选手号码
  332.                                                         second=dt_time;          //答题时间赋值秒
  333.                                                         beep=0;                          //蜂鸣器响
  334.                                                         for(i=0;i<20;i++) //此处用于延时
  335.                                                         {
  336.                                                                 display();
  337.                                                         }
  338.                                                         beep=1;                          //蜂鸣器延时后关闭
  339.                                                         qd=0;break;                  //qd置0,抢答环节结束,跳出switch语句
  340.                                                 }
  341.                                         case 2:                                         //t为2时就是2号选手按下按键
  342.                                                 {
  343.                                                         TR0=0;                         //以下参考1号选手注释/|\即可
  344.                                                         p=2;
  345.                                                         second=dt_time;
  346.                                                         beep=0;
  347.                                                         for(i=0;i<20;i++)
  348.                                                         {
  349.                                                                 display();
  350.                                                         }
  351.                                                         beep=1;
  352.                                                         qd=0;break;
  353.                                                 }
  354.                                         case 3:
  355.                                                 {
  356.                                                         TR0=0;
  357.                                                         p=3;
  358.                                                         second=dt_time;
  359.                                                         beep=0;
  360.                                                         for(i=0;i<20;i++)
  361.                                                         {
  362.                                                                 display();
  363.                                                         }
  364.                                                         beep=1;
  365.                                                         qd=0;break;
  366.                                                 }
  367.                                         case 4:
  368.                                                 {
  369.                                                         TR0=0;
  370.                                                         p=4;
  371.                                                         second=dt_time;
  372.                                                         beep=0;
  373.                                                         for(i=0;i<20;i++)
  374.                                                         {
  375.                                                                 display();
  376.                                                         }
  377.                                                         beep=1;
  378.                                                         qd=0;break;
  379.                                                 }
  380.                                         case 5:
  381.                                                 {
  382.                                                         TR0=0;
  383.                                                         p=5;
  384.                                                         second=dt_time;
  385.                                                         beep=0;
  386.                                                         for(i=0;i<20;i++)
  387.                                                         {
  388.                                                                 display();
  389.                                                         }
  390.                                                         beep=1;
  391.                                                         qd=0;break;
  392.                                                 }
  393.                                         case 6:
  394.                                                 {
  395.                                                         TR0=0;
  396.                                                         p=6;
  397.                                                         second=dt_time;
  398.                                                         beep=0;
  399.                                                         for(i=0;i<20;i++)
  400.                                                         {
  401.                                                                 display();
  402.                                                         }
  403.                                                         beep=1;
  404.                                                         qd=0;break;
  405.                                                 }
  406.                                         case 7:
  407.                                                 {
  408.                                                         TR0=0;
  409.                                                         p=7;
  410.                                                         second=dt_time;
  411.                                                         beep=0;
  412.                                                         for(i=0;i<20;i++)
  413.                                                         {
  414.                                                                 display();
  415.                                                         }
  416.                                                         beep=1;
  417.                                                         qd=0;break;
  418.                                                 }
  419.                                         case 8:
  420.                                                 {
  421.                                                         TR0=0;
  422.                                                         p=8;
  423.                                                         second=dt_time;
  424.                                                         beep=0;
  425.                                                         for(i=0;i<20;i++)
  426.                                                         {
  427.                                                                 display();
  428.                                                         }
  429.                                                         beep=1;
  430.                                                         qd=0;break;
  431.                                                 }
  432.         
  433.                                 }
  434.                         }

  435.                         if(dt==1)                        //答题标志开启时
  436.                         {
  437.                                 if(start==0)        //开始按键此时按下时
  438.                                 {
  439.                                         display();
  440.                                         if(start==0)
  441.                                         {
  442.                                                 beep=0;                          //蜂鸣器鸣响一声
  443.                                                 for(i=0;i<20;i++)
  444.                                                 {
  445.                                                         display();
  446.                                                 }
  447.                                                 beep=1;
  448.                                                 TR0=1;                          //开启定时器计时答题时间
  449.                                         }
  450.                                 }
  451.                         }
  452.                 }

  453.                 if(second==0)                         //为0时报警
  454.                 {
  455.                         beep=0;                                //蜂鸣器报警
  456.                         qd=0;
  457.                         dt=0;                                //抢答和答题标志清零
  458.                 }
  459.         }
  460. }
复制代码

1-程序.rar

44.86 KB, 下载次数: 6, 下载积分: 黑币 -5

2-原理图.rar

211.74 KB, 下载次数: 9, 下载积分: 黑币 -5

4-制作过程照片.rar

2.46 MB, 下载次数: 4, 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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