找回密码
 立即注册

QQ登录

只需一步,快速开始

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

8位竞赛抢答器 单片机程序

[复制链接]
跳转到指定楼层
楼主
以单片机为核心,设计一个8位竞赛抢答器:同时供8名选手或8个代表队比赛,分别8个按钮S0~S7表示。设置一个系统清除和抢答控制开关S,开关由主持人控制。抢答器具有锁存与显示功能。即选手按按钮,锁存相应的编号,并在优先抢答选手的编号一直保持到主持人将系统清除为止。抢答器具有定时抢答功能,且一次抢答的时间由主持人设定(如30秒)。当主持人启动“开始”键后,定时器进行减计时,同时扬声器发出短暂的声响,声响持续的时间为0.5s左右。参赛选手在设定的时间抢答,抢答有效,定时器停止工作,显示器上显示选手的编号和抢答时间,并保持到主持人将系统清除为止。如果定时时间已到,无人抢答,本次抢答无效,系统报警并禁止抢答,定时显示器上显示00



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

  2. sbit DIN=P3^0;//与max7219接口定义
  3. sbit LOAD=P3^1;
  4. sbit CLK=P3^2;

  5. sbit key0=P1^0;//8路抢答器按键
  6. sbit key1=P1^1;
  7. sbit key2=P1^2;
  8. sbit key3=P1^3;
  9. sbit key4=P1^4;
  10. sbit key5=P1^5;
  11. sbit key6=P1^6;
  12. sbit key7=P1^7;

  13. sbit key_clear=P2^0;//主持人时间设置、清除
  14. sbit begin=P2^1;//主持人开始按键

  15. sbit sounder=P3^7;//蜂鸣器

  16. unsigned char second=30;//秒表计数值
  17. unsigned char counter=0;//counter每100,minite加1
  18. unsigned char people=0;//抢答结果

  19. unsigned char num_add[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};//max7219读写地址、内容
  20. unsigned char num_dat[]={0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89};

  21. unsigned char keyscan()//键盘扫描函数
  22. {
  23.   unsigned char keyvalue,temp;
  24.   
  25.   keyvalue=0;
  26.   P1=0xff;
  27.   temp=P1;
  28.   if(~(P1&temp))
  29.   {
  30.     switch(temp)
  31.         {
  32.           case 0xfe:
  33.             keyvalue=1;
  34.             break;
  35.           case 0xfd:
  36.             keyvalue=2;
  37.             break;
  38.           case 0xfb:
  39.             keyvalue=3;
  40.             break;
  41.           case 0xf7:
  42.             keyvalue=4;
  43.             break;
  44.           case 0xef:
  45.             keyvalue=5;
  46.             break;
  47.           case 0xdf:
  48.             keyvalue=6;
  49.             break;
  50.           case 0xbf:
  51.             keyvalue=7;
  52.             break;
  53.       case 0x7f:
  54.             keyvalue=8;
  55.             break;
  56.           default:
  57.             keyvalue=0;
  58.             break;
  59.         }
  60.   }

  61.   return keyvalue;
  62. }

  63. void max7219_send(unsigned char add,unsigned char dat)//向max7219写指令函数
  64. {
  65.   unsigned char        ADS,i,j;

  66.   LOAD=0;
  67.   i=0;
  68.   while(i<16)
  69.   {
  70.     if(i<8)
  71.         {
  72.           ADS=add;
  73.         }
  74.         else
  75.         {
  76.           ADS=dat;
  77.         }
  78.         for(j=8;j>=1;j--)
  79.         {
  80.           DIN=ADS&0x80;
  81.           ADS=ADS<<1;
  82.           CLK=1;
  83.           CLK=0;
  84.         }
  85.         i=i+8;
  86.   }
  87.   LOAD=1;
  88. }

  89. void max7219_init()//max7219初始化函数
  90. {
  91.   max7219_send(0x0c,0x01);
  92.   max7219_send(0x0b,0x07);
  93.   max7219_send(0x0a,0xf5);
  94.   max7219_send(0x09,0xff);
  95. }

  96. void time_display(unsigned char x)//时间显示
  97. {
  98.   unsigned char i,j;
  99.   i=x/10;
  100.   j=x%10;
  101.   max7219_send(num_add[1],num_dat[j]);
  102.   max7219_send(num_add[0],num_dat[i]);
  103. }

  104. void scare_display(unsigned char x)//抢答结果显示
  105. {
  106.   unsigned char i,j;
  107.   i=x/10;
  108.   j=x%10;
  109.   max7219_send(num_add[3],num_dat[j]);
  110.   max7219_send(num_add[2],num_dat[i]);
  111. }

  112. void holderscan()//抢答时间设置,0-60s
  113. {
  114.   time_display(second);
  115.   scare_display(people);
  116.   if(~key_clear)//如果有键按下,改变抢答时间
  117.   {
  118.     while(~key_clear);
  119.         if(people)//如果抢答结果没有清空,抢答器重置
  120.         {
  121.           second=30;
  122.           people=0;
  123.         }
  124.         if(second<60)
  125.         {
  126.           second++;
  127.         }
  128.         else
  129.         {
  130.           second=0;
  131.         }
  132.   }
  133. }

  134. void timer_init()
  135. {
  136.   EA=1;
  137.   ET0=1;
  138.   TMOD=0x01;
  139.   TH0=0xd8;//设定10ms中断一次
  140.   TL0=0xef;
  141. }

  142. void main()
  143. {
  144.   while(1)
  145.   {
  146.   do{
  147.     holderscan();
  148.   }while(begin);//开始前进行设置,若未按下开始键
  149.   while(~begin);//防抖
  150.   max7219_init(); //芯片初始化
  151.   timer_init();          //中断初始化
  152.   TR0=1;                  //开始中断
  153.   do{
  154.     time_display(second);
  155.         scare_display(people);
  156.         people=keyscan();
  157.   }while((!people)&&(second));//运行直到抢答结束或者时间结束
  158.   TR0=0;
  159.   }
  160. }

  161. void timer0() interrupt 1
  162. {
  163.   if(counter<100)
  164.   {
  165.     counter++;
  166.         if(counter==50)
  167.         {
  168.           sounder=0;
  169.         }
  170.   }
  171.   else
  172.   {
  173.     sounder=1;
  174.     counter=0;
  175.         second=second-1;
  176.   }
  177.   TH0=0xd8;//重新装载
  178.   TL0=0xef;
  179.   TR0=1;
  180. }
复制代码

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

使用道具 举报

沙发
ID:779164 发表于 2020-6-14 22:18 | 只看该作者
很有用,谢谢
回复

使用道具 举报

板凳
ID:779647 发表于 2020-6-16 21:44 | 只看该作者
真的不错谢谢
回复

使用道具 举报

地板
ID:781699 发表于 2020-6-17 09:41 | 只看该作者

真的不错谢谢楼主
回复

使用道具 举报

5#
ID:962259 发表于 2021-8-25 12:26 | 只看该作者
为什么我的数码管不亮呢,接的共阴极数码管,换成共阳极后数码管又全亮了,求大神教教我
回复

使用道具 举报

6#
ID:399179 发表于 2022-1-7 11:51 来自手机 | 只看该作者
怎么显示第一第二第三名次?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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