单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机8路抢答器Proteus仿真+代码设计(可设置抢答和答题时间)

[复制链接]
MrHuan991 发表于 2019-1-11 19:53 | 显示全部楼层 |阅读模式
时间有限,用数码管显示8路抢答
用定时器进行8路扫描,间隔可以调十分小
此外,具有设置时间的功能(抢答和答题时间)

8路抢答器仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png 0.png

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. void Setsecond();//抢答器答题和抢答时间的设置函数声明
  4. void delay(int k); //延时函数声明

  5. //数码管选管位
  6. sbit Sel1=P2^0;
  7. sbit Sel2=P2^1;
  8. sbit Sel3=P2^2;
  9. sbit Sel4=P2^3;
  10. sbit Sel5=P2^4;
  11. sbit Sel6=P2^5;

  12. //抢答器的状态指示灯
  13. sbit led=P2^6;   //显示复位和设置时间的状态
  14. sbit Led1=P3^1;  //抢答失败时,该灯会一直闪烁
  15. sbit Led2=P3^2;  //答题完毕时,该灯会一直闪烁

  16. //抢答器初始化抢答和答题时间按键
  17. sbit Set1=P3^3;  //设置抢答时间,+
  18. sbit Set2=P3^4;  //设置抢答时间,-
  19. sbit Set3=P3^5;  //设置答题时间,+
  20. sbit Set4=P3^6;  //设置答题时间,-
  21. sbit RST=P2^7;   //抢答器的复位按键
  22. sbit EN=P3^0;    //抢答器使能和设置抢答和答题时间按键

  23. unsigned char Tshu1=11,Tshu2=31,shu1=11,shu2=31,shu;//抢答器抢答时间和答题时间的相关变量
  24. unsigned char count0=0,count1=0,roberflag=0,scond1=0,second2=0,robernum=0;//抢答者的相关变量
  25. unsigned char Shuma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段码值
  26. bit Enflag=0; //抢答器使能的工作标志变量,0表示正常工作,1表示设置时间(抢答和答题)


  27. void main()  //主函数
  28. {
  29.         unsigned char n=0;
  30.         TMOD=0x11;Led1=0;Led2=0;
  31.         TH0=(2^16-50000)/2^8;TL0=(2^16-50000)%2^8;
  32.         TH1=(2^16-50000)/2^8;TL1=(2^16-50000)%2^8;
  33.         TR0=1;ET0=1;TR1=1;ET1=1;EA=1;
  34.         while(1)
  35.         {
  36.                 for(n=0;n<6;n++) //这个循环,实现数码管的动态显示
  37.                 {
  38.                 switch(n)
  39.                 {
  40.                         case 0:Sel1=1,Sel2=0,Sel3=0,Sel4=0,Sel5=0,Sel6=0;
  41.                         if(Enflag == 0)
  42.                         P0=~Shuma[shu/10];
  43.                         else
  44.                         P0=~Shuma[shu1/10];break;
  45.                         case 1:Sel1=0,Sel2=1,Sel3=0,Sel4=0,Sel5=0,Sel6=0;
  46.                         if(Enflag == 0)
  47.                         P0=~Shuma[shu%10];
  48.                         else
  49.                         P0=~Shuma[shu1%10];break;
  50.                         case 2:Sel1=0,Sel2=0,Sel3=1,Sel4=0,Sel5=0,Sel6=0;P0=0xBF;break;
  51.                         case 3:Sel1=0,Sel2=0,Sel3=0,Sel4=1,Sel5=0,Sel6=0;P0=0xBF;break;
  52.                         case 4:Sel1=0,Sel2=0,Sel3=0,Sel4=0,Sel5=1,Sel6=0;
  53.                         if(Enflag == 0)
  54.                         P0=~Shuma[robernum/10];
  55.                         else
  56.                         P0=~Shuma[shu2/10];break;
  57.                         case 5:Sel1=0,Sel2=0,Sel3=0,Sel4=0,Sel5=0,Sel6=1;
  58.                         if(Enflag == 0)
  59.                         P0=~Shuma[robernum%10];
  60.                         else
  61.                         P0=~Shuma[shu2%10];break;
  62.                         }
  63.                   delay(20);
  64.                         P0=0xff;
  65.          }
  66. }
  67. }

  68. void delay(int k)   //延时函数,主要是为了数码管的动态显示
  69. {
  70.    while(k--);
  71. }

  72. void Timer0() interrupt 1  //定时器0,主要用于各种按键的扫描,每200ms一次
  73. {  
  74.   TH0=(2^16-50000)/2^8;TL0=(2^16-50000)%2^8;
  75.         count0++;
  76.         P1=0x00;
  77.         if(count0 == 5)
  78.         {
  79.                 count0=0;
  80.                 Setsecond();  //调用设置时间函数,检测是否有设置时间的动作
  81.                 if(RST == 0) //检测是否有复位动作,有动作,则实现部分变量初始化值
  82.                 {
  83.                         roberflag=0;
  84.                         robernum=0;shu=0;
  85.                         led=~led;Led1=0;Led2=0;
  86.                         shu1=Tshu1;shu2=Tshu2;
  87.                 }
  88.                 if(EN == 0)
  89.                 {
  90.                         Enflag=~Enflag;
  91.                         led=~led;Led1=0;Led2=0;
  92.                 }
  93.                 if(Enflag == 0) //正常工作时候的,抢答人号码的识别和显示(同时判断8口,不准次扫描,无优先级)
  94.                 {
  95.                 if(P1 != 0x00)
  96.                 {
  97.                         if(roberflag == 0) //只有在抢答时间才能抢答,roberflag=0表示抢答,1答题,2抢答失败,3答题完毕
  98.                         {
  99.                         roberflag++;  
  100.                         switch(P1)
  101.                         {
  102.                                 case 0x01:robernum=1;break;
  103.                                 case 0x02:robernum=2;break;
  104.                                 case 0x04:robernum=3;break;
  105.                                 case 0x08:robernum=4;break;
  106.                                 case 0x10:robernum=5;break;
  107.                                 case 0x20:robernum=6;break;
  108.                                 case 0x40:robernum=7;break;
  109.                                 case 0x80:robernum=8;break;
  110.                                 default:break;
  111.                         }
  112.                 }
  113.         }
  114. }
  115. }
  116.         }

  117. void Timer1() interrupt 3    //定时器1主要是用于工作时的数码显示,跑表,1一秒刷新一次
  118. {
  119.         TH1=(2^16-50000)/2^8;TL1=(2^16-50000)%2^8;
  120.         if(roberflag == 2)
  121.                 Led1=~Led1;
  122.         if(roberflag == 3)
  123.                 Led2=~Led2;
  124.         count1++;
  125.         if(count1 == 20) //正常工作时候的跑表
  126.         {
  127.                 if(Enflag == 0)
  128.                 {
  129.                 if(roberflag == 0)  //抢答时间的跑表  
  130.                 {
  131.                         shu1--;
  132.                         shu = shu1;
  133.                 }
  134.                 if(roberflag == 1)  //答题时间的跑表
  135.                 {
  136.                         shu2--;
  137.                         shu = shu2;
  138.                 }
  139.                 if(shu1 == 0)
  140.                         roberflag=2;
  141.                 if(shu2 == 0)
  142.                         roberflag=3;
  143.           }
  144.                   count1=0;
  145.         }
  146. }

  147. void Setsecond()   //抢答时间和答题时间设置函数,也是被T0调用,实现设置时间功效。
  148. {
  149.         if(Enflag == 1)
  150.         {
  151.                
  152.         if( Set1 == 0)
  153.         {
  154.           Tshu1++;
  155.         }
  156.         if(Set2 == 0)
  157.         {
  158.           Tshu1--;
  159.         }
  160.         if(Set3 == 0)
  161.         {
  162.                 Tshu2++;
  163.         }
  164.         if(Set4 == 0)
  165.         {
  166.                 Tshu2--;
  167.         }
  168.         shu1=Tshu1;  //Tshu1,Tshu2的出现是为了实现设置的抢答和答题时间具有存储功能,不随跑表而发生变化
  169.         shu2=Tshu2;
  170.   }
  171. }
复制代码

所有资料51hei提供下载:
RoberAck.rar (18.17 KB, 下载次数: 20)

评分

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

查看全部评分

回复

使用道具 举报

sisijiling 发表于 2019-1-12 10:23 | 显示全部楼层
有汇编程序吗??
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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