找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的六路抢答器程序

[复制链接]
跳转到指定楼层
楼主
ID:678490 发表于 2020-1-2 12:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
                #include<reg51.h>
                #include<intrins.h>
                #define uint unsigned int
                #define uchar unsigned char
                sbit P37=P3^7;
                sbit P07=P0^7;
                sbit P06=P0^6;
                uchar m,a,b,c,i,k,s,r=0;
                uint j,sum,d1=0,d2=0,d3=0,d4=0,d5=0,d6=0;
                uchar code tab1[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   //倒计时字符表
                uchar code tab[6]={0x06,0x5b,0x4f,0x66,0x6d,0x7d};        //编号字符表
                                                                               //头文件及参数定义
                main()              //主函数
                 {
//中断服务程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   EA=1;            //开中断总开关
                   EX0=1;           //开外部中断INT0
                   IT0=1;           //选择下降沿触发方式
                   TMOD=0x01;       //定时器T0选择方式一
                   while(1)         //等待中断
//跑马程序~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    {  for(k=0;k<6;k++)
                        {
                          P1=0x40;           //P1口位选
                          for(i=0;i<6;i++)
                           {
                             if(P0==0xff)    //无违规操作
                              {
                                P2=tab[k];  //P2对应输出字符
                                for(j=0;j<=25000;j++);    //延时
                                P1=_cror_(P1,1);    //左移一位
                                for(j=0;j<=25000;j++);
                              }
                             else          //有违规操作
                              {
                                P1=0x02;    //对应位数码管被选中
                                P2=0x6d;
                                for(j=0;j<=1000;j++);
                                P1=0x04;
                                P2=0x78;
                                for(j=0;j<=1000;j++);
                                P1=0x08;
                                P2=0x3f;
                                for(j=0;j<=1000;j++);
                                P1=0x10;
                                P2=0x73;
                                for(j=0;j<=1000;j++);
                              }
                             while(r==3)   //3轮答题结束后显示对应位得分结果
                              {
                                P1=0x01;P2=tab1[d1];for(j=0;j<50;j++);
                                P1=0x02;P2=tab1[d2];for(j=0;j<50;j++);
                                P1=0x04;P2=tab1[d3];for(j=0;j<50;j++);
                                P1=0x08;P2=tab1[d4];for(j=0;j<50;j++);
                                P1=0x10;P2=tab1[d5];for(j=0;j<50;j++);
                                P1=0x20;P2=tab1[d6];for(j=0;j<50;j++);
                              }
                           }
                       }
                   }
               }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

           int0() interrupt 0       //进入中断(开始抢答)
             {
              P0=0xff;             //初始化P0口开关无人拨开

              for(m=9;m>=0;m--)
               {
                P1=0xff;
                P2=0x00;
                TR0=1; TMOD=0x01;
                for(s=1;s<=20;)       //定时器定时一秒
                 {
                  if(P0!=0xff)
                 {
                  switch(P0)          //判开关
                   {
                     case 0xfe:{P2=0x06;sum=1;}break;
                     case 0xfd:{P2=0x5b;sum=2;}break;
                     case 0xfb:{P2=0x4f;sum=3;}break;
                     case 0xf7:{P2=0x66;sum=4;}break;
                     case 0xef:{P2=0x6d;sum=5;}break;
                     case 0xdf:{P2=0x7d;sum=6;}break;
                   }
                  if(P0!=0xff) goto ap1;
                }
                  TH0=15536/256;
                  TL0=15536%256;
                  do{}while(!TF0);
                  s++;
                  TF0=0;
                 }
               if(m==0) goto ap2;
              }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             ap1:
             P1=~P0;
             b=P2;           //把P2口字符赋值给参数b
             if(P0!=0xff)
              { r++;        //抢答次数
//鸣笛程序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                for(a=0;a<sum;a++)
                 {
                   for(i=1;i<200;i++)
                    {
                      P37=~P37;         //P37为喇叭开关控制
                      for(j=0;j<=100;j++);
                    }
                   for(i=1;i<200;i++)
                   for(j=0;j<=100;j++);
                 }
//对应位亮闪编号5次 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                for(c=0;c<6;c++)
                 { for(j=0;j<=25000;j++);
                   P1=0x01;
                   for(j=0;j<=25000;j++);
                   P1=0x00;
                 }
                P1=~P0;
//答题倒计时 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                for(m=9;m>=0;m--)
                 {
                   P2=tab1[m];
                   TR0=1; TMOD=0x01;
                   for(s=1;s<=20;  s++)
                    {
                      while(P07==0)          //拨P07答题正确 显示PASS
                       { P1=0x01;P2=0x73;for(j=0;j<50;j++);
                         P1=0x02;P2=0x77;for(j=0;j<50;j++);
                         P1=0x04;P2=0x6d;for(j=0;j<50;j++);
                         P1=0x08;P2=0x6d;for(j=0;j<50;j++);
                         if(P07==1)          //答题正确对应位加一分
                          { if(sum==1) d1=d1+1;
                            if(sum==2) d2=d2+1;
                            if(sum==3) d3=d3+1;
                            if(sum==4) d4=d4+1;
                            if(sum==5) d5=d5+1;
                            if(sum==6) d6=d6+1;
                            goto ap2;
                          }
                        }
                      while(P06==0)          //拨P06答题错误 显示ff
                       {  P1=0xff;P2=0x71;for(j=0;j<50;j++);
                           if(P06==1) goto ap2;
                       }
                      TH0=15536/256;
                      TL0=15536%256;         //定时器初值
                      do{}while(!TF0);       //查询等待定时

                      TF0=0;
                   }
                if(P0==0xff) goto ap2;       //开关拨回跳到判复位程序



            }
//判开关复位程序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ap2:
           while(P0!=0xff)
            { P1=~P0;                     //位选对应选手数码管
              P2=b;                       //P2口输出显示对应编号
              if(P0==0xff) goto ap2;       //开关复位 返回主程序中断点
            }
         }}
~~//
这个抢答器有跑马,鸣笛,判违规,倒计时等功能,
需要的芯片有AT89c51/52,和一个74ls573(可选择别的代替)
仅供大家参考,也欢迎各位指出程序中的不足,我也好改正。


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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