找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机八路抢答器设计(keil+Proteus仿真+PCB原理图)

[复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


单片机源程序如下:
  1. /*************************************************************
  2.                       八路抢答器系统

  3. 补充说明:
  4. ***************************************************************/
  5. #include<reg52.h>                   //头文件
  6. #include<SMG.h>
  7. #include<EEPROM.h>
  8. #include<INTERRUPT.h>

  9. #define uchar unsigned char//宏定义
  10. #define uint unsigned int

  11. /**********************引脚定义************************/
  12. sbit key_zhu=P2^2;           //主持人键
  13. sbit key_jia=P2^1;           //加键
  14. sbit key_jian=P2^0;           //减键

  15. sbit key_1=P1^1;           //八位选手按键定义
  16. sbit key_2=P1^3;
  17. sbit key_3=P1^5;
  18. sbit key_4=P1^7;
  19. sbit key_5=P3^1;
  20. sbit key_6=P3^3;
  21. sbit key_7=P3^5;
  22. sbit key_8=P3^7;

  23. sbit led_1=P1^0;           //八位LED灯按键定义
  24. sbit led_2=P1^2;
  25. sbit led_3=P1^4;
  26. sbit led_4=P1^6;
  27. sbit led_5=P3^0;
  28. sbit led_6=P3^2;
  29. sbit led_7=P3^4;
  30. sbit led_8=P3^6;
  31. /**********************变量定义************************/
  32. uchar zhu_f=0;                   //比赛进行阶段标记位,=0表示没有按。=1表示在设置倒计时的时间。=2表示开始抢答
  33. uchar qiang_f=0;           //抢答犯规标记,=0没有犯规。=1表示有人犯规
  34. uchar wan_f=0;                   //抢答完成标记,=0抢答没完成后还没有开始。=1表示抢答完成
  35. uchar time=30;                   //倒计时时间
  36. uchar T0_num;                   //定时器0计数
  37. uchar number;                   //抢答成功选手的编号,或犯规选手的编号。=0的时候表示没有

  38. /********************************************************
  39. 函数名称:void delayms(uint ms)
  40. 函数作用:毫秒延时函数
  41. 参数说明:
  42. ********************************************************/
  43. void delayms(uint ms)
  44. {
  45.         unsigned char i=100,j;
  46.         for(;ms;ms--)
  47.         {
  48.                 while(--i)
  49.                 {
  50.                         j=10;
  51.                         while(--j);
  52.                 }
  53.         }
  54. }
  55. /********************************************************
  56. 函数名称:void bajing()
  57. 函数作用:抢答犯规报警提示
  58. 参数说明:
  59. ********************************************************/
  60. void bajing()
  61. {
  62.         buzz=0;                   //开蜂鸣器
  63.         delayms(10);
  64.         buzz=1;                   //关蜂鸣器
  65.         delayms(10);
  66. }
  67. /********************************************************
  68. 函数名称:uchar qianda()
  69. 函数作用:抢答按键检测,返回抢答编号
  70. 参数说明:
  71. ********************************************************/
  72. uchar qianda()
  73. {
  74.         uchar temp=0;
  75.         if(key_1==0)                                  //一号犯规,下同
  76.                 temp=1;                          //记录1号
  77.         else
  78.                 if(key_2==0)
  79.                         temp=2;
  80.                 else
  81.                         if(key_3==0)
  82.                                 temp=3;
  83.                         else
  84.                                 if(key_4==0)
  85.                                         temp=4;
  86.                                 else
  87.                                         if(key_5==0)
  88.                                                 temp=5;
  89.                                         else
  90.                                                 if(key_6==0)
  91.                                                         temp=6;
  92.                                                 else
  93.                                                         if(key_7==0)
  94.                                                                 temp=7;
  95.                                                         else
  96.                                                                 if(key_8==0)
  97.                                                                         temp=8;       
  98.         return temp;       
  99. }
  100. /********************************************************
  101. 函数名称:void led_kongzhi(uchar num,bit mode)
  102. 函数作用:LED灯控制
  103. 参数说明:num控制哪一个灯,k=1,点亮,=0关闭。mode=0全灭后在控制这个灯,=1单独控制这个灯
  104. ********************************************************/
  105. void led_kongzhi(uchar num,bit k,bit mode)
  106. {
  107.         if(mode==0)
  108.         {
  109.                 led_1=1;           //八位LED灯全灭
  110.                 led_2=1;
  111.                 led_3=1;
  112.                 led_4=1;
  113.                 led_5=1;
  114.                 led_6=1;
  115.                 led_7=1;
  116.                 led_8=1;       
  117.         }       
  118.         if(k==1)
  119.         {
  120.                 switch (num)          //控制对应LED灯亮
  121.                 {
  122.                         case 1:led_1=0;
  123.                                 break;
  124.                         case 2:led_2=0;
  125.                                 break;
  126.                         case 3:led_3=0;
  127.                                 break;
  128.                         case 4:led_4=0;
  129.                                 break;
  130.                         case 5:led_5=0;
  131.                                 break;
  132.                         case 6:led_6=0;
  133.                                 break;
  134.                         case 7:led_7=0;
  135.                                 break;
  136.                         case 8:led_8=0;
  137.                                 break;
  138.                 }
  139.         }
  140.         else
  141.         {
  142.                 switch (num)          //控制对应LED灯灭
  143.                 {
  144.                         case 1:led_1=1;
  145.                                 break;
  146.                         case 2:led_2=1;
  147.                                 break;
  148.                         case 3:led_3=1;
  149.                                 break;
  150.                         case 4:led_4=1;
  151.                                 break;
  152.                         case 5:led_5=1;
  153.                                 break;
  154.                         case 6:led_6=1;
  155.                                 break;
  156.                         case 7:led_7=1;
  157.                                 break;
  158.                         case 8:led_8=1;
  159.                                 break;
  160.                 }       
  161.         }
  162. }
  163. /********************************************************
  164. 函数名称:void scan(void)
  165. 函数作用:按键检测函数
  166. 参数说明:
  167. ********************************************************/
  168. void scan(void)
  169. {       
  170.         uchar qiangda_num=0;
  171.         //主持人键
  172.         if(key_zhu==0)                   //按键按下
  173.         {
  174.                 delayms(7);                   //显示消抖
  175.                 if(key_zhu==0&&zhu_f!=2&&qiang_f==0&&wan_f==0)//判断是否有人犯规或者抢答是否开始或者抢答是否完成
  176.                 {
  177.                         zhu_f++;           //比赛阶段标记+1
  178.                         if(zhu_f==2)   //比赛正式开始
  179.                         {
  180.                                 TR0=1;           //比赛开始,开启定时
  181.                                 wan_f=0;   //清除比赛完成标志
  182.                                 bajing();  //提示比赛开始
  183.                         }                       
  184.                 }
  185.                 else
  186.                         if(key_zhu==0&&qiang_f==1)   //判断是否有人犯规
  187.                         {
  188.                                 buzz=1;                                         //清除报警
  189.                                 qiang_f=0;                                 //清除抢答标志
  190.                                 number=0;                                 //清除选手编号
  191.                                 time=EEPROM_read(0x2000);//重新读取存储的抢答总时长
  192.                                 led_kongzhi(0,0,0);
  193.                         }
  194.                         else                                                 
  195.                                 if(key_zhu==0&&wan_f==1) //判断是否有人完成
  196.                                 {
  197.                                         buzz=1;                                 //清除报警
  198.                                         wan_f=0;                         //清除完成标志
  199.                                         number=0;                         //清除选手编号
  200.                                         time=EEPROM_read(0x2000);//重新读取存储的抢答总时长
  201.                                         led_kongzhi(0,0,0);
  202.                                 }
  203.                                 else
  204.                                         if(key_zhu==0&&zhu_f==2) //暂停比赛
  205.                                         {
  206.                                                 TR0=0;                                 //关闭定时
  207.                                                 zhu_f=1;                         //重新回到设置比赛时间阶段
  208.                                                 bajing();                         //提示暂停比赛
  209.                                         }
  210.                 while(!key_zhu);//检测按键松开
  211.         }

  212.         //加值键,支持连按
  213.         if(key_jia==0&&zhu_f==1&&qiang_f==0)         //判断是否在设置倒计时时间
  214.         {
  215.                 delayms(7);                                                         //延时消抖
  216.                 if(key_jia==0)                                                 //再次判断按键按下
  217.                 {
  218.                         if(time<99)                             //比赛时间最大值99S
  219.                                 time++;                                                  //比赛时间+1S
  220.                         EEPROM_delete(0x2000);                         //擦除EEPROM煽区
  221.                         EEPROM_write(0x2000,time);                 //写入【比赛时间】数据保存
  222.                         display(time/10,time%10,10,0);         //显示设置比赛时间
  223.                 }
  224.         }

  225.         //减值键,支持连按
  226.         if(key_jian==0&&zhu_f==1&&qiang_f==0)         //判断是否在设置倒计时时间
  227.         {
  228.                 delayms(7);                                                         //延时消抖
  229.                 if(key_jian==0)                                                 //再次判断按键按下
  230.                 {
  231.                         if(time!=0)                                                   //比赛时间最小值0S
  232.                                 time--;                                 //比赛时间-1S
  233.                         EEPROM_delete(0x2000);                         //擦除EEPROM煽区
  234.                         EEPROM_write(0x2000,time);                 //写入【比赛时间】数据保存
  235.                         display(time/10,time%10,10,0);         //显示设置比赛时间
  236.                 }
  237.         }
  238.         //选手按键
  239.         qiangda_num=qianda();
  240.         if(qiangda_num!=0)                              //判断是否有选手按下按键
  241.         {
  242.                 if(zhu_f!=2&&qiang_f==0&&wan_f==0)//如果还没有开始抢答时按下
  243.                 {
  244.                         zhu_f=1;
  245.                         buzz=0;                                                  //蜂鸣器报警
  246.                         qiang_f=1;                                          //抢答犯规标记
  247.                         number=qiangda_num;
  248.                         led_kongzhi(number,1,0);
  249.                 }
  250.                 else
  251.                         if(zhu_f==2&&wan_f==0)                         //在开始抢答时按下
  252.                         {
  253.                                 wan_f=1;                                         //标记抢答完成
  254.                                 zhu_f=0;                                         //主持人标记复位
  255.                                 TR0=0;                                                 //关闭倒计时定时器
  256.                                 number=qiangda_num;
  257.                                 led_kongzhi(number,1,0);
  258.                                 bajing();                                         //提示有人抢答完成
  259.                         }
  260.         }  
  261. }

  262. /*********************************************************
  263. 函数名称:void main()
  264. 函数作用:主函数函数
  265. 参数说明:
  266. *********************************************************/
  267. void main()
  268. {
  269.         uchar i=0;
  270.         T0_init();                                                 //定时器初始化
  271.         if(key_jian==0)          
  272.         {
  273.                 delayms(100);
  274.                 if(key_jian==0)
  275.                 {
  276.                         EEPROM_delete(0x2000);         //擦除EEPROM煽区
  277.                         EEPROM_write(0x2000,30); //写入【比赛时间】数据保存
  278.                 }
  279.         }
  280.         time=EEPROM_read(0x2000);                 //读取存储的【比赛时间】数据

  281.         for(i=0;i<9;i++)
  282.         {
  283.                 led_kongzhi(i,1,1);
  284.                 delayms(10);       
  285.         }

  286.         for(i=9;i>0;i--)
  287.         {
  288.                 led_kongzhi(i-1,0,1);
  289.                 delayms(10);       
  290.         }
  291.         led_kongzhi(0,0,0);
  292.         while(1)                                                 //死循环
  293.         {
  294.                 scan();                                                 //按键检测处理
  295.                 if(zhu_f==0&&wan_f==0)                 //判断是否还没进入比赛阶段
  296.                         display(10,10,10,10);         //未进入,显示"----"
  297.                 else
  298.                         if(zhu_f==0&&wan_f==1)         //进入比赛阶段,并且处于设置比赛时间
  299.                                 display(time/10,time%10,10,number);//显示设置比赛时间
  300.                         else
  301.                                 if(zhu_f!=0)                 
  302.                                 {               
  303.                                         if(qiang_f==1)   //设有人犯规
  304.                                                 display(11,11,10,number);                   //显示FF-犯规编号
  305.                                         else
  306.                                                 display(time/10,time%10,10,number);//显示比赛剩余时间和抢答者编号,未抢答显示0
  307.                                 }               
  308.         }
  309. }
复制代码

所有资料51hei提供下载(仿真PCB与代码):
八人抢答器51hei设计.zip (1.14 MB, 下载次数: 190)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1071489 发表于 2023-4-13 16:23 | 只看该作者
可以说一下主要的功能吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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