单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 23|回复: 1
收起左侧

单片机四路抢答器(倒计时)基于51单片机

[复制链接]
123456ld 发表于 2019-11-10 12:03 | 显示全部楼层 |阅读模式
本帖最后由 123456ld 于 2019-11-11 15:09 编辑

基于c51的四路抢答器,本实验通过数码管结合矩阵按键及独立按键组成四路抢答器。对不同选手的判断从而在数码管上显示那位选手抢答成功暂停计时,或哪三位选手犯规触发蜂鸣器报警。其中倒计时的开始由独立按键K1实现,对抢答或倒计时的恢复由独立按键K3实现。程序源码为本人自创,如有不懂,请留言发问。篇幅有限仅提供部分代码。详情请下载后查阅。

该程序适用stc89c51单片机

单片机源程序如下:
  1. /****************************************************
  2. *                    实验内容
  3. *                   四路抢答器
  4. **************************************************/

  5. #include <reg52.h>

  6. typedef unsigned int u16;
  7. typedef unsigned char u8;

  8. /***********************************************
  9. *
  10. *               变量及引脚定义声明
  11. *************************************************/
  12. sbit AA = P2^2;
  13. sbit BB = P2^3;
  14. sbit CC = P2^4;
  15. sbit k3 = P3^2;
  16. sbit k4 = P3^3;
  17. sbit beep = P1^5;
  18. int i=0;      //初始状态控制毫秒的两位数码管为0
  19. int j=10;     //初始状态控制秒的两位数码管为10
  20. int jishu=0;  //以10ms为一个剂量,精准控制毫秒的99-0
  21. int cishu=0; //消除最后一秒带来的影响
  22. int xuanshou=0;  //选手编号
  23. int biaozhi=1;    //控制抢答开始后只有一个人可以被记录
  24. int wei1=0 , wei2=0 , wei3=0;
  25. enum position {zero, one, two, three, four, five, six, seven};

  26. u16 code duanxuan[16] = { 0x3f,0x06,0x5b,0x4f,
  27.                           0x66,0x6d,0x7d,0x07,
  28.                                               0x7f,0x6f,0x77,0x7c,
  29.                           0x39,0x5e,0x79,0x71};

  30. /*****************************************************
  31. *
  32. *                   子函数申明
  33. ******************************************************/                                                                                                        
  34. void delay(u16 i);      //延时函数         
  35. void jvzhen();                        //矩阵键盘选手确定                                                
  36. void weixuan( u16 i );  //数码管位选
  37. void timer0();          //定时器初始化
  38. void xianshi();         //数码管倒计时显示
  39. void int0();            //中断0倒计时开始
  40. void int1();                        //中断1问题结束恢复数码管                                                        
  41. void panduan();         //答题选手的判断
  42. void qiangda();         //选手抢答时的判断
  43.                                                                                                 
  44. /*****************************************************
  45. *                     主函数
  46. *******************************************************/                                                                                                        
  47. void main()
  48. {
  49.         int0();
  50.         int1();
  51.         timer0();        
  52.         while(1)
  53.         {
  54.                 xianshi();
  55.                 jvzhen();
  56.                 panduan();
  57.                 qiangda();
  58.         }
  59. }

  60. void qiangda()
  61. {
  62.         if( j==10&&xuanshou!=0 )
  63.         {
  64.         wei1 = xuanshou;
  65.         while(1)
  66.         {
  67.             xianshi();
  68.             weixuan(7);
  69.             P0 = duanxuan[wei1];           
  70.             delay(1);
  71.             P0 = 0x00;
  72.             
  73.             beep=~beep;
  74.             delay(1);
  75.             jvzhen();
  76.             if( xuanshou!=wei1 )
  77.             {
  78.                 break;
  79.             }
  80.             if( k4==0 )
  81.             {               
  82.                 break;
  83.             }
  84.         }
  85.         wei2 = xuanshou;
  86.         while(1)
  87.         {
  88.             xianshi();
  89.             
  90.             weixuan(7);
  91.             P0 = duanxuan[wei2];           
  92.             delay(1);
  93.             P0 = 0x00;
  94.          
  95.             weixuan(6);
  96.             P0 = duanxuan[wei1];
  97.             delay(1);
  98.             P0 = 0x00;
  99.             
  100.             beep=~beep;
  101.             delay(1);
  102.             jvzhen();
  103.             if( xuanshou!=wei2 )
  104.             {
  105.                 break;
  106.             }
  107.             if( k4==0 )
  108.             {               
  109.                 break;
  110.             }
  111.         }
  112.         wei3 = xuanshou;
  113.         while(1)
  114.         {
  115.             xianshi();
  116.             
  117.             weixuan(7);
  118.             P0 = duanxuan[wei3];           
  119.             delay(1);
  120.             P0 = 0x00;
  121.          
  122.             weixuan(6);
  123.             P0 = duanxuan[wei2];
  124.             delay(1);
  125.             P0 = 0x00;
  126.             
  127.             weixuan(5);
  128.             P0 = duanxuan[wei1];
  129.             delay(1);
  130.             P0 = 0x00;
  131.             
  132.             beep=~beep;
  133.             delay(1);
  134.             jvzhen();
  135.             if( k4==0 )
  136.             {               
  137.                 break;
  138.             }
  139.         }     
  140.         }        
  141. }

  142. /*        延时           */
  143. void delay(u16 i)
  144. {
  145.         u16 a;
  146.         while(i--)
  147.         {
  148.                 for(a = 0; a < 100; a++)
  149.                 {
  150.                         ;
  151.                 }               
  152.         }        
  153. }

  154. /* 显示哪位选手按键暂停     */
  155. void panduan()
  156. {
  157.         if( i!=0 && xuanshou!=0 )
  158.         {
  159.                 switch( xuanshou )
  160.                 {
  161.                         case 1 : TR0=0; weixuan(7); P0=duanxuan[1]; delay(1); P0 = 0x00; break;
  162.                         case 2 : TR0=0; weixuan(7); P0=duanxuan[2]; delay(1); P0 = 0x00; break;
  163.                         case 3 : TR0=0; weixuan(7); P0=duanxuan[3]; delay(1); P0 = 0x00; break;
  164.                         case 4 : TR0=0; weixuan(7); P0=duanxuan[4]; delay(1); P0 = 0x00; break;
  165.                 }
  166.                 biaozhi=0;
  167.         }
  168. }

  169. /*      矩阵键盘选手确定        */
  170. void jvzhen()
  171. {
  172.         P1 = 0x0f;
  173.         if( (P1!=0x0f&&biaozhi==1) )
  174.         {               
  175.                 delay(5);
  176.                 if( (P1!=0x0f)  )
  177.                 {
  178.                         switch( P1 )
  179.                         {
  180.                                 case 0x07 : xuanshou = 1; break;
  181.                                 case 0x0b : xuanshou = 2; break;
  182.                                 case 0x0d : xuanshou = 3; break;
  183.                                 case 0x0e : xuanshou = 4; break;
  184.                         }
  185.                         P1=0xf0;
  186.                         switch( P1 )
  187.                         {
  188.                                 case (0x70) : xuanshou = xuanshou;    break;        
  189.                         }
  190.                 }
  191.         }        
  192. }

  193. /* 数码管位选*/
  194. void weixuan( u16 i )
  195. {
  196.         switch(i)
  197.         {
  198.                 case (zero):  CC = 0; BB = 0; AA = 0; break;        //第零位
  199.                 case (one):          CC = 0; BB = 0; AA = 1; break;        //第一位
  200.                 case (two):   CC = 0; BB = 1; AA = 0; break;        //第二位
  201.                 case (three): CC = 0; BB = 1; AA = 1; break;        //第三位
  202.                 case (four):  CC = 1; BB = 0; AA = 0; break;        //第四位
  203.                 case (five):  CC = 1; BB = 0; AA = 1; break;        //第五位
  204.                 case (six):   CC = 1; BB = 1; AA = 0; break;        //第六位
  205.                 case (seven): CC = 1; BB = 1; AA = 1; break;        //第七位
  206.         }
  207. }

  208. /* 定时器初始化*/
  209. void timer0()
  210. {
  211.         TMOD =0x01;
  212.         TH0 = (65536-1000)/256;
  213.         TL0 = (65536-1000)%256; //1ms
  214.         ET0 = 1;
  215.         EA = 1;
  216. }

  217. /* 倒计时显示 */
  218. void xianshi()
  219. {
  220.                 weixuan(0);
  221.                 P0 = duanxuan[i%10];                        
  222.                 delay(1);
  223.                 P0 = 0x00;
  224.    
  225.                 weixuan(1);
  226.                 P0 = duanxuan[i/10];                        
  227.                 delay(1);
  228.                 P0 = 0x00;

  229.                 weixuan(2);
  230.                 P0 = 0x40;                        
  231.                 delay(1);
  232.                 P0 = 0x00;
  233.                
  234.                 weixuan(3);
  235.                 P0 = duanxuan[j%10];                        
  236.                 delay(1);
  237.                 P0 = 0x00;
  238.                
  239.                 weixuan(4);
  240.                 P0 = duanxuan[j/10];                        
  241.                 delay(1);
  242.                 P0 = 0x00;               
  243. }

  244. /* 倒计时开始 */
  245. void int0()
  246. {
  247.         EA=1;
  248.         IT0=1;
  249.         EX0=1;
  250. }

  251. /*  数码管复位 */
  252. void int1()
  253. {
  254.         EX1=1;
  255.         IT1=1;
  256.         EA=1;
  257. }





复制代码

所有资料51hei提供下载:
四路抢答器(倒计时).zip (35.3 KB, 下载次数: 0)

评分

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

查看全部评分

回复

使用道具 举报

admin 发表于 2019-11-10 21:14 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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