找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6951|回复: 8
收起左侧

四路竞赛抢答器论文+Proteus仿真+单片机程序

  [复制链接]
ID:206068 发表于 2017-5-30 15:31 | 显示全部楼层 |阅读模式
这是我做了两个星期的毕业设计,四路竞赛抢答器,
附件里面包含了仿真图可直接下载打开
还有程序哦,请各位大神进行指教吧

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载):
四路抢答器Proteus仿真图2.jpg 四路抢答器Proteus仿真图.jpg 四路抢答器的程序截图.jpg 0.png

抢答器的设计论文:
0.png

单片机源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. char s;
  5. uchar num=0;
  6. char time=20;        //抢答时间
  7. char datitime=30;        //答题限时时间
  8. uint tt,t1;        //T0,T1定时器定一秒时
  9. bit flag,s_flag=1,b_flag,fall_flag;        //标志位
  10. bit K_startcountflag,K_timecountflag;        //时间调整标志位
  11. sbit K0=P3^0;
  12. sbit beep=P3^7;         //蜂鸣器输出口
  13. sbit rled=P3^1;                //指示灯输出口
  14. sbit K1=P1^0;               
  15. sbit K2=P1^1;
  16. sbit K3=P1^2;
  17. sbit K4=P1^3;
  18. sbit K_Time=P3^2;        //答题计时键
  19. sbit K_startcount=P3^3;        //开始抢答时间调整键
  20. sbit K_timecount=P3^4;        //答题计时时间调整键
  21. void delay(uchar ms)
  22. {
  23.         uchar y;
  24.         for(;ms>0;ms--)
  25.                 for(y=120;y>0;y--);
  26. }
  27. uchar code tabledu[]={0x3f,0x06,0x5b,0x4f,
  28. 0x66,0x6d,0x7d,0x07,
  29. 0x7f,0x6f,0x77,0x7c,
  30. 0x39,0x5e,0x79,0x71
  31. };
  32. uchar code tablewe[]={0XFE,0XFD,0XFB,0XF7};
  33. void T0_Init(void)
  34. {
  35.         TMOD=0X01;
  36.         TH0=(65536-2000)/256;
  37.         TL0=(65536-2000)%256;
  38.         TH1=(65536-2000)/256;
  39.         TL1=(65536-2000)%256;
  40.         ET0=1;
  41.         ET1=1;
  42.         EA=1;
  43.         P0=0;
  44. }
  45. void Key_Scan(void)                //开始键扫描
  46. {
  47.         if(K0==0)
  48.         {
  49.                 delay(10);
  50.                 if(K0==0)
  51.                 {
  52.                         while(!K0);
  53.                         TR0=1;
  54.                         s=time;
  55.                         tt=0;
  56.                         flag=1;
  57.                         s_flag=1;
  58.                         b_flag=1;
  59.                         num=0;
  60.                         beep=1;
  61.                         rled=1;
  62.                         fall_flag=0;        //清除违规标志位
  63.                         K_startcountflag=0;
  64.                         K_timecountflag=0;
  65.                 }
  66.         }
  67. }
  68. void Scan(void)                //四路热键扫描(哪个键先按下,哪个优先级最高)
  69. {
  70.         if(K1==0)
  71.         {
  72.                 delay(10);
  73.                 if(K1==0)
  74.                 {
  75.                         while(!K1);
  76.                         num=1;                //数码管显示1号"1"
  77.                         TR0=0;                //关闭定时器0,时间停止
  78.                         TR1=1;                //打开定时器1,使扬声器响一声
  79.                         s_flag=0;        //关闭开始键标志位,使再按其他三个键不会响应
  80.                 }
  81.         }
  82.         if(K2==0)                        //下面三个键的处理同上
  83.         {
  84.                 delay(10);
  85.                 if(K2==0)
  86.                 {
  87.                         while(!K2);
  88.                         num=2;               
  89.                         TR0=0;
  90.                         TR1=1;
  91.                         s_flag=0;        //重要
  92.                 }
  93.         }
  94.         if(K3==0)
  95.         {
  96.                 delay(10);
  97.                 if(K3==0)
  98.                 {
  99.                         while(!K3);
  100.                         num=3;
  101.                         TR0=0;
  102.                         TR1=1;
  103.                         s_flag=0;
  104.                 }
  105.         }
  106.         if(K4==0)
  107.         {
  108.                 delay(10);
  109.                 if(K4==0)
  110.                 {
  111.                         while(!K4);
  112.                         num=4;
  113.                         TR0=0;
  114.                         TR1=1;
  115.                         s_flag=0;
  116.                 }
  117.         }
  118. }
  119. void display(void)
  120. {
  121.         if(flag==1)                //开始键按下,开始计时抢答
  122.         {
  123.                 if(num!=0)        //如果有人抢答,则显示相应的几号
  124.                 {
  125.                         P0=tabledu[num];        //显示几号抢到了
  126.                         P2=tablewe[0];
  127.                         delay(2);
  128.                         P0=0;
  129.                         P2=0XFF;
  130.                 }
  131.                 else                //否则没人抢答,则前面不显示几号
  132.                 {
  133.                         P0=0;               
  134.                         P2=0XFF;
  135.                 }
  136.                 P0=tabledu[s/10];                //下面为显示抢答倒计时
  137.                 P2=tablewe[2];
  138.                 delay(2);
  139.                 P0=0;
  140.                 P2=0XFF;
  141.                 P0=tabledu[s%10];
  142.                 P2=tablewe[3];
  143.                 delay(2);
  144.                 P2=0XFF;
  145.                 P0=0;
  146.         }
  147.         else        //如果开始键没有按下,则显示F FF(若有违规者,则显示违规号码及 FF)或时间调整
  148.         {
  149.                 if(fall_flag==1)        //违规显示
  150.                 {
  151.                         if(num!=0)
  152.                         {
  153.                                 P0=tabledu[num];        //显示几号违规了
  154.                                 P2=tablewe[0];
  155.                                 delay(2);
  156.                                 P0=0;
  157.                                 P2=0XFF;
  158.                                 P0=tabledu[15];                //下面显示 FF,表示违规了
  159.                                 P2=tablewe[2];
  160.                                 delay(2);
  161.                                 P0=0;                //消隐
  162.                                 P2=0XFF;
  163.                                 P0=tabledu[15];
  164.                                 P2=tablewe[3];
  165.                                 delay(2);
  166.                                 P0=0;
  167.                                 P2=0XFF;
  168.                         }
  169.                         else               
  170.                         {
  171.                                 P0=0;               
  172.                                 P2=0XFF;
  173.                         }
  174.                 }
  175.                 else        //没有人违规才显示调整时间
  176.                 {
  177.                         if(K_startcountflag==1)
  178.                         {
  179.                                 P0=0X6D;                //第一位数码管显示"5(S)"(表示抢答时间调整)
  180.                                 P2=tablewe[0];
  181.                                 delay(2);
  182.                                 P0=0;
  183.                                 P2=0XFF;
  184.                                 P0=tabledu[time/10];        //下面显示调整的抢答时间
  185.                                 P2=tablewe[2];
  186.                                 delay(2);
  187.                                 P0=0;
  188.                                 P2=0XFF;
  189.                                 P0=tabledu[time%10];
  190.                                 P2=tablewe[3];
  191.                                 delay(2);
  192.                                 P0=0;
  193.                                 P2=0XFF;
  194.                         }
  195.                         else if(K_timecountflag==1)
  196.                         {
  197.                                 P0=0X07;        //第一位与第二位数码管合起来显示"T",表示答题时间调整
  198.                                 P2=tablewe[0];
  199.                                 delay(2);
  200.                                 P0=0;
  201.                                 P2=0XFF;
  202.                                 P0=0X31;
  203.                                 P2=tablewe[1];
  204.                                 delay(2);
  205.                                 P0=0;
  206.                                 P2=0XFF;
  207.                                 P0=tabledu[datitime/10];
  208.                                 P2=tablewe[2];
  209.                                 delay(2);
  210.                                 P0=0;
  211.                                 P2=0XFF;
  212.                                 P0=tabledu[datitime%10];
  213.                                 P2=tablewe[3];
  214.                                 delay(2);
  215.                                 P0=0;
  216.                                 P2=0XFF;
  217.                         }
  218.                         else                //否则显示F FF
  219.                         {
  220.                                 P0=tabledu[15];
  221.                                 P2=tablewe[0];
  222.                                 delay(2);
  223.                                 P0=0;
  224.                                 P0=tabledu[15];
  225.                                 P2=tablewe[2];
  226.                                 delay(2);
  227.                                 P0=0;                //消隐
  228.                                 P2=0XFF;
  229.                                 P0=tabledu[15];
  230.                                 P2=tablewe[3];
  231.                                 delay(2);
  232.                                 P0=0;
  233.                                 P2=0XFF;
  234.                         }        
  235.                 }        
  236.         }
  237. }
  238. void Time_Scan(void)                //调整时间键扫描
  239. {
  240.         if(K_startcount==0)                //抢答时间调整
  241.         {
  242.                 delay(10);
  243.                 if(K_startcount==0)        
  244.                 {
  245.                         while(!K_startcount);
  246.                         time++;                        
  247.                         if(time==50)
  248.                         {
  249.                                 time=20;
  250.                         }
  251.                         K_startcountflag=1;        //将抢答时间标志位置1
  252.                         K_timecountflag=0;        //同时关闭答题时间标志位
  253.                 }
  254.         }
  255.         if(K_timecount==0)                //答题时间调整
  256.         {
  257.                 delay(10);
  258.                 if(K_timecount==0)
  259.                 {
  260.                         while(!K_timecount);
  261.                         datitime++;
  262.                         if(datitime==60)
  263.                         {
  264.                                 datitime=30;
  265.                         }
  266.                         K_timecountflag=1;
  267.                         K_startcountflag=0;
  268.                 }
  269.         }
  270. }
  271. void main(void)
  272. {
  273.         T0_Init();
  274.         while(1)
  275.         {
  276.                 Key_Scan();                //开始键扫描
  277.                 if((flag==0)&(s_flag==1))        //当开始键没按下及没有人违规时才可进行时间调整
  278.                 {
  279.                         Time_Scan();
  280.                 }
  281.                 if((flag==1)&(s_flag==0))//当开始键按下及有人抢答才进行开始回答计时倒计时
  282.                 {
  283.                         if(K_Time==0)
  284.                         {
  285.                                 delay(10);
  286.                                 if(K_Time==0)
  287.                                 {
  288.                                         while(!K_Time);
  289.                                         s=datitime;
  290.                                         TR0=1;
  291.                                         tt=0;
  292.                                         TR1=1;
  293.                                 }
  294.                         }
  295.                 }        
  296.                 if((flag==0)&(s_flag==1))        //违规
  297.                 {
  298.                         Scan();
  299.                         if(num!=0)                //开始键没有按下时,有人按下了抢答器,则置违规标志位
  300.                         {
  301.                                 fall_flag=1;
  302.                                 rled=0;
  303.                         }
  304.                 }
  305.                 if((flag==1)&(s_flag==1))        //如果开始键按下且抢答键没有人按下,则进行八路抢答键扫描
  306.                 {
  307.                         Scan();
  308.                 }        
  309.                 display();                //显示到数码管上
  310.         }
  311. }
  312. void timer0(void) interrupt 1
  313. {
  314.         TH0=(65536-2000)/256;        //2ms
  315.         TL0=(65536-2000)%256;
  316.         if(b_flag)        //开始(START)键按下,嘟一声(长1秒),表示开始抢答
  317.         {
  318.                 beep=~beep;
  319.         }
  320.         else
  321.         beep=1;
  322.         if(s<5)        //抢答时间快到报警,隔1秒响一声且红灯闪烁,响三声
  323.         {
  324.                 if(s%2==0)
  325.                 {
  326.                         b_flag=1;
  327. ……………………

  328. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
四路竞赛抢答器编程程序.zip (168.37 KB, 下载次数: 281)

评分

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

查看全部评分

回复

使用道具 举报

ID:207455 发表于 2017-6-3 19:00 来自手机 | 显示全部楼层
棒,真好!!!!
回复

使用道具 举报

ID:89286 发表于 2017-6-4 04:56 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

ID:207897 发表于 2017-6-7 15:53 来自手机 | 显示全部楼层
很好…感谢分享
回复

使用道具 举报

ID:198404 发表于 2017-12-3 18:31 | 显示全部楼层
非常感谢 分享
回复

使用道具 举报

ID:420224 发表于 2018-11-5 09:21 | 显示全部楼层
要花多少币才能下载完???
回复

使用道具 举报

ID:868377 发表于 2020-12-28 14:30 | 显示全部楼层
10,12,13,14这几个引脚得开关是干嘛得?
回复

使用道具 举报

ID:865245 发表于 2021-5-11 20:09 | 显示全部楼层
求大佬指教一下怎么把时间改成计分数
回复

使用道具 举报

ID:1025285 发表于 2022-5-10 09:47 | 显示全部楼层
怎么把里面的串口改成at89c52的型号啊 有大佬知道吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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