【课设】基于单片机技术的电子抢答器的设计和实现课设(附源码)

摘 要本文介绍用单片机技术设计的电子抢答器,除能完成基本的抢答功能外,还可进行加分、减分、存贮显示各组分数、答题限时抢答限时等功能.主要有选手抢答部分、主持人控制部分和数码管显示部分。优点是利用单片机来设计抢答器,使以上问题得以解决,即使两组的抢答时间相差几微秒,也可分辨出哪组优先答题硬件电路简单,功能齐全,操作方便,是一款即先进又实用的电子抢答器.

关键词单片机、抢答、显示、控制

使用说明:首先由主持按下开始键,单片机开始倒计时,选手们才可以开始抢答,单片机从30秒开始倒计时,如果在30秒内无人抢答,则自动放弃,进入下一题,若有人抢答,则单片机会自动检测是几号首先抢答,做出判断,之后数码管会显示,然后单片机重新倒计时,从90秒开始,若在90秒内回答完并回答正确,主持人可以按加分键,则所的分数会显示在选手的数码管上,若回答错误,则主持人可以通过减分键进行减分,然后进入下一题。

方案论证:

方案一:利用集成芯片设计,优点是造价低,但缺点很多,功能单一,操作不便。

方案利用单片机设计,充分利用单片机的资源:定时器和IO口,利用定时器实现倒计时功能,抢答部分采用独立式键盘,显示部分采用数码管扫描实现,其外围部分简单,主要是由单片机控制,把程序编写成攻即可。

综合考虑以上两个方案,决定采用第二个方案,利用单片机实现。

三、方案设计

四、程序

本作品的核心部分是单片的控制部分,所以便一个合适的程序是极其重要的,程序如下:

#include<reg52.h>

Static unsigned char dm[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

static unsigned char px2[11]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff};

static unsigned char px3[11]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xbf,0x7f};

static unsigned char xs[11]={0xc0,0xa4,0xc0,0xa4,0xc0,0xa4,0xc0,0xa4,0xc0,0xb0,0xc0};

static unsigned char dj[4]={0};

static unsigned char n,r;

static unsigned char t=30;            //t:时间,k:溢出

static unsigned char k,k2=0;

static unsigned char kk,p;

static unsigned char fen1=20,fen2=20,fen3=20,fen4=20;

///

void djxs1(unsigned char t)             //倒计时函数1

{

unsigned char i;

if(t>23)           dj[3]=~((~dj[3])>>1);

if((t>16)&&(t<24)) dj[2]=~((~dj[2])>>1);

if((t>8)&&(t<17))  dj[1]=~((~dj[1])>>1);

if((t>0)&&(t<9))   dj[0]=~((~dj[0])>>1);

for(i=0;i<4;i++)

{

    SBUF=dj[i];

while(!TI){}

TI=0;

 }

}

/

void djxs2(unsigned char t)             //倒计时函数2

{

unsigned char i;

if(t>69)           dj[3]=~((~dj[3])>>1);

if((t>48)&&(t<70)) dj[2]=~((~dj[2])>>1);

if((t>24)&&(t<49))  dj[1]=~((~dj[1])>>1);

if((t>0)&&(t<25))   dj[0]=~((~dj[0])>>1);

for(i=0;i<4;i++)

{

    SBUF=dj[i];

while(!TI){}

TI=0;

 }

}

//

void t1(void)interrupt 3              //定时器1中断

{

 TH1=0X15;

 TL1=0XA0;

 k++;

 if(k>20)

 {

 k=0;

 k2++;

// if(t==90)

// for(r=0;r<4;r++)dj[r]=0;

 if(kk)djxs1(t);

 if(p&&(k2==3)){k2=0;djxs2(t);}     //3秒

                     //1秒                        //灯倒计时

  t--;

  xs[9]=dm[t/10];

  xs[10]=dm[t%10];

  if(t==0){for(r=0;r<4;r++)

            dj[r]=0;

           TR1=0;

           xs[9]=dm[3];

           xs[8]=dm[0];}

 }

}





void t0(void)interrupt 1         //定时器2中断

{

P0=xs[n];

P2=px2[n];

P3=px3[n];

n++;

if(n>10)n=0;

TH0=0Xfe;

TL0=0X00;

}



char jianpan()                    //键盘函数

{

 unsigned char x,d=500;

 P1=0xff;

 while(P1==0xff);

 x=P1;

 while(d--);

 d=500;

 while(P1!=0xff);

 return x;

}



main()

{unsigned char x,y,m;

// unsigned char k;

 IE=0X8a;

 //TMOD=0X01;

 TMOD=0X11;

 TH0=0Xfe;

 TL0=0Xb8;

 TR0=1;                                             //数码管显示

 TH1=0X15;

 TL1=0XA0;

loop: TR1=0;

      t=30;

      xs[8]=dm[0];

      xs[9]=dm[3];

      xs[10]=dm[0];

      for(m=0;m<4;m++)

      {dj[m]=0;

      }

 for(m=0;m<4;m++)

     {

         SBUF=dj[m];

         while(!TI){}

         TI=0;

     }                                               //灯全亮

    while(1)

   {

     x=jianpan();                                 //扫描键盘

     switch(x)

    {

        case 0xef:                                //开始键按下

          { kk=1;

            p=0;

            t=30;                                      //音乐

            TR1=1;                                  //灯逐个灭,数码管减一

            while(t)                                //30秒内

           { y=jianpan();

               //if(y&&0x0f!=0x0f)

                for(m=0;m<4;m++)

{

                  dj[m]=0;}

  k2=0;

                  t=90;

                  p=1;

              switch(y)

             {

               case 0xfe:{xs[8]=dm[1];                       //一键按下

                           kk=0;t=90;k2=0;                                        

                           while(1)

          {                                  //重新倒计时

                            if(P1==0xdf){fen1+=5;

                                       xs[0]=dm[fen1%10];            //加分

                                       xs[1]=dm[fen1/10];goto loop;}

                          if(P1==0xbf){fen1-=5;

                                       xs[0]=dm[fen1%10];            //减分

                                       xs[1]=dm[fen1/10];goto loop;}

                           }

                         break;}           //显示一

                case 0xfd:{xs[8]=dm[2];                              //二键按下

                kk=0;t=90;k2=0;

                           while(1)

                          {

                          if(P1==0xdf){fen2+=5;

                                       xs[2]=dm[fen2%10];

                                       xs[3]=dm[fen2/10];goto loop;}

                          if(P1==0xbf){fen2-=5;

                                       xs[2]=dm[fen2%10];

                                       xs[3]=dm[fen2/10];goto loop;}

                           }

                          break;}   //显示二

                case 0xfb:{xs[8]=dm[3];                            //三键按下

                           kk=0;t=90;k2=0;

                           while(1)

              {                                //重新倒计时

                          if(P1==0xdf){fen3+=5;

                                       xs[4]=dm[fen3%10];

                                       xs[5]=dm[fen3/10];goto loop;}

                          if(P1==0xbf){fen3-=5;

                                       xs[4]=dm[fen3%10];

                                       xs[5]=dm[fen3/10];goto loop;}

                           }

                           break;}   //显示三

                case 0xf7:{xs[8]=dm[4];                             //四键按下

                           kk=0;t=90;k2=0;                          //重新倒计时

                           while(1)

                          {

                          if(P1==0xdf){fen4+=5;

                                       xs[6]=dm[fen4%10];

                                       xs[7]=dm[fen4/10];goto loop;}

                          if(P1==0xbf){fen4-=5;

                                       xs[6]=dm[fen4%10];

                                       xs[7]=dm[fen4/10];goto loop;}

                           }

                           break;}   //显示四

                default:break;

              }

              }

      goto loop;}         //无人抢答

      default:break;}    //开始switch

    }                    //总while

 }

五、作品调试

作品调试的过程中主要是程序条是比较繁琐,硬件的制作工作量挺大的,主要是因为几个键盘是独立的,数码管是采用扫描显示的,每块小板上都有许多排针,程序主要在两个倒计时之间的转换上有点难调,定时器用了两个,调试往往顾此失彼,后来就实行模块式调试,最终实现了。

六、感想心得

通过这次制作中不断的纠错和调试,我学到了很多包括焊接中要注意的何布板设计的事情,更进一步的了解了单片机的内部资源和应用。理论和实际是存在一定的差距的,只有不断的实践,才能将理论和实践结合起来。

七、参考书目

《单片机应用系统设计技术》           张  齐 编著

《8051单片机实用教程》              徐爱韵  编著

《单片机原理及应用》                 孙育才  编著

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值