题目:抢答器设计

1系统设计

1.1设计要求

1.1.1设计任务

基于单片机的抢答器的设计,实现抢答器的基本功能。

1.1.2性能指标要求

1.需要自己设计电路并焊接电路板。

2.有一个主持人控制开关和6路抢答按扭,当主持人允许抢答时才能进行抢答操作,并用一个数码管显示抢答选手的号码,同时其他选手不能再抢答。

3.当主持人允许抢答后倒计时5秒时间,在这5秒内抢答有效,过后就不能进行抢答了。

4.电路上要加个蜂鸣器的电路,当有选手抢答时蜂鸣器响一下。

5.当有选手抢答后,进行倒计时20秒作为选手回答问题时间,用两个数码管显示,倒计时时间到时有声光提示。

6.画电路板时要增加下载接口,方便调试程序。

7.扩展功能(选做)

用按键可设置倒计时的时间,范围在5秒到30秒之间。

1.2设计思路及设计框图

1.2.1设计思路

本次实训是基于单片机STC89C52芯片来扩展的抢答器。

首先先设置支持人开始抢答按键,在芯片的P1^6脚处接入按键,按键按下,蜂鸣器响来实现这个抢答开始信号。在主持人开始允许抢答时,六位选手连接的单片机从P1^0—P1^5口的任意一位选手进行抢答,抢答时间为5s,抢答后设定回答问题时间为5s—30s,倒计时5s时LED灯亮,并且蜂鸣器响。所抢答的选手号码、抢答时间与回答时间均将字节送入数码管中显示。用两个按键来掌控回答问题的时间,时间加计数与时间减计数。当需要重新进行抢答时则按下与芯片的RST段(即9脚)连接的按键则可以实现。所抢答的选手号码、抢答时间与回答时间均将字节送入数码管中显示。P0口接的是一个四位一体共阴数码管,P2.4、P2.2、P2.1、P2.0作为数码管的位选。由于单片机自身IO口的驱动能力不能让蜂鸣器发出声音,因此要通过三极管NPN来放大电流,这样才能使蜂鸣器发出声音。

1.2.2总体设计款图

2各个模块设计

2.1单片机STC89C52模块

P0-P3:占32个引脚,其中P0是低8位地址线/数据线端口,P1是数据线端口,P2是高8位地址线/数据线端口,P3是数据线/第二功能线端口。

EA~/VPP:片外程序ROM有效编程电源,作EA~用时为输出信号,EA~=0片外程序ROM有效,EA~=1片内ROM有效,作VPP用时为电源输入。

XTAL1和XTAL2:外部时钟震荡输入端

VCC:+5V电源。

VSS:地

RST/VPD:复位/备用电源接入。正常工作时作复位信号引入,当VCC失电时,此脚接入备用电源,使片内RAM中的数据处于底功能保护。

2.2选手按键电路

该电路是由6个按键开关组成,实现6位选手抢答的终端,每一个开关连接一个I/O(P1.0-P1.5),注意按键的公共端接地,当单片机的脚悬空时为高电平,按下时为低电平。

2.3时钟频率振荡电路

单片机必须在时钟的驱动下才能工作.在单片机内部有一个时钟振荡电路,只需要外接一个振荡源就能产生一定的时钟信号送到单片机内部的各个单元,决定单片机的工作速度。此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为5V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。电路中两个电容C2、C3的作用有两个:一是帮助振荡器起振;二是对振荡器的频率进行微调。C2、C3的典型值为22pF。

2.4复位电路

给单片机一个复位信号使程序重头开始执行,一般有两种复位方式:上电复位和手动复位。在此作品中的复位采用手动复位方式,复位电路是单片机初始化,使单片机重新开始执行程序,当复位键按下,RST由低电平变为高电平,则程序从头开始执行。

2.5数码管显示电路

该电路是为了更好地显示出各时段的情况也是让我们能直观的看到各个状态,该电路由8位排阻和4位数码管组成,8为排阻的每一管脚接着数码管的段码a、b、c、d、e、f、g、dp有助于提高数码管的亮度,s1、s2、s3、s4是数码管的位选,连接着单片机的I/O(P2.0、P2.1、P2.2、P2.3)数码管由单片机程序控制位选和段选,按我们的要求显示.

2.6电源电路

该电源电路是为了更好的显示电路中电源导通状态。

2.7蜂鸣器控制电路

蜂鸣器VCC端接着VCC,GND端连接着NPN三极管的集电极,当三极管的基极送来高电平时NPN三极管导通即蜂鸣器导通,发出声音,三极管基极获得的高电平由程序控制,程序判断抢答开关按下后就给三极管基极送出高电平,三级管基极需要接上拉电阻一个,才能得到足够的电压开启三极管。

2.8下载口模块

为了实现我们编好的程序可以正常下载到单片机,就需要在电路中添加单片机下载口,电路的设计,下载口的2、3端分别连接单片机的RXD、TXD,4管脚接GND,1管脚接+5V。

3调试过程

3.1焊接过程

本次实训用的是洞洞板焊接,与以往的打板子不同,洞洞板没有明确的元器件摆放位置和相应的焊点,所以需要自己规划好每个元件的摆放位置以及每条线路的连接方式,是使用跳线还是直接通过一条焊锡拉过去,并且焊接的过程需要很仔细很小心,少接一条线,都有可能会导致整个电路都不连通,由于是 次使用洞洞板,所以我的线路布局有些杂乱,使用了很多跳线让板子看起来很杂乱,而且花费了较多的时间才完成本次实训的焊接过程。

3.2调试过程

焊接好电路后,通上电蜂鸣器不响并且数码管也不会亮,并且程序也不能下载进单片机,在检查后发现少连接了一条线导致单片机与数码管都没有通上电源,并且由于焊接的时候没有正确的了解到按键同一侧是相连的导致按键也没有作用,在都完善了以后,蜂鸣器却怎么都不会响,但用单片机相应管脚直接连上vcc蜂鸣器却会一直响,证明了电路连接没有问题, 在查阅了资料后,发现可以把蜂鸣器放在三极管的发射极,在更改了电路后蜂鸣器能正常运行。

4功能测试

4.1测试仪器与设备

万用表,下载线

4.2性能指标测试

1、接通电源,电源灯亮,抢答指示灯亮,数码管亮。

2、按下主持人按键,数码管上显示5秒倒计时,5秒计时结束后LED亮、蜂鸣器响。

3、在5秒抢答时间内按下选手按键,数码管上显示选手号码,同时显示20秒倒计时。

倒计时结束后,LED亮、蜂鸣器响。

4、复位键,数码管归零。

5、设置键可调节抢答时间与回答时间,加到三十秒自动回到五秒钟。

实物图:

5、电路原理图

程序:

#includereg52.h

sbitBEEP=P2^0;  

sbitLED1=P2^3;  

sbitLED2=P2^2;  

sbitLED3=P2^1;  

#defineduanPore  P0    //数码管段控制端口,高电平有效

sbitDIG1=P2^4;      

sbitDIG2=P2^5;      

sbitDIG3=P2^6;      

sbitDIG4=P2^7;      

sbitKEY1=P1^0;    

sbitKEY2=P1^1;    

sbitKEY3=P1^2;    

sbitKEY4=P1^3;    

sbitKEY5=P1^4;    

sbitKEY6=P1^5;    

sbitKEY7=P3^2;    

sbitKEY8=P3^3;    

unsignedcharcodetab_duan[19]=

{

  0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,  

  0x77,0x7c,0x39,0x5e,0x79,0x71,    

  0x40,0x00,0x48            

};

unsignedchardat_buf[4]={17,17,0,5};  

inttime=5,time1=5,time2=20;  

unsignedchari=0;

unsignedintcount=0;    

bitflag_lock=1;      

voidDelayMs(unsignedintms);    //延时函数

voiddig_scan(unsignedchar*dat);//数码管显示扫描

unsignedcharKeyScan(void);  //独立按键扫描

voidInitTimer0(void);      //定时器0初始化

voidalarm(void);    //报警函数

voidAnswerTask(void);  //抢答任务

voidSetTime(void);//设置倒计时时间

voidmain(void)

  BEEP=0;      

  LED1=1;

  InitTimer0();    

  time=time1;    

  while(1)

  {

    if(KeyScan()==7)  

    {

      alarm();    

      AnswerTask();  

    }

    if(KeyScan()==8)  

      SetTime();    

    dat_buf[0]=17;

    dat_buf[1]=17;

    dat_buf[2]=time/10;  

    dat_buf[3]=time%10;  

    dig_scan(dat_buf);    

  }

}

voidDelayMs(unsignedintms)//延时函数

  unsignedchara,b,c;

  while(--ms)

  for(c=1;c0;c--)

  for(b=;b0;b--)

  for(a=2;a0;a--);  

voiddig_scan(unsignedchar*dat)//数码管显示扫描

  switch(i)

    case0:

      duanPore=tab_duan[dat[0]];  

      DIG1=0;

      break;

    case1:

      duanPore=tab_duan[dat[1]];  

      DIG2=0;            

    case2:

      duanPore=tab_duan[dat[2]];  

      DIG3=0;            

    case3:

      duanPore=tab_duan[dat[3]];  

      DIG4=0;            

    default:break;  

  DelayMs(5);    

  DIG1=1;    

  DIG2=1;

  DIG3=1;

  DIG4=1;

  ++i;        

  if(i3)

    i=0;  

unsignedcharKeyScan(void)//独立按键扫描

  if(KEY1==0)    

  {

  LED2=0;

  LED3=1;

    DelayMs(10);  

    if(KEY1==0)  

      return1;

  if(KEY2==0)    

    if(KEY2==0)  

      return2;  

  if(KEY3==0)    

    DelayMs(10);    

    if(KEY3==0)  

      return3;  

  if(KEY4==0)    

  {  

    if(KEY4==0)  

      return4;  

  if(KEY5==0)    

    if(KEY5==0)  

      return5;

  if(KEY6==0)    

    if(KEY6==0)  

      return6;  

  if(KEY7==0)    

  LED3=0;

    if(KEY7==0)  

      return7;  

  if(KEY8==0)    

    if(KEY8==0)

      return8;

  return0;      

voidTimer0Interrupt(void)interrupt1//定时器

TH0=(-)/;

TL0=(-)%;

  ++count;

  if(count)        

    count=0;          

    --time;            

    if(time=0)        

      TR0=0;      

      BEEP=1;        

      LED1=0;

      LED2=1;

      LED3=1;

      flag_lock=0;          

    }        

voidInitTimer0(void)

TMOD=0x01;  

TH0=(-)/;  

EA=1;      

ET0=1;    

TR0=0;    

voidalarm(void)//报警

  BEEP=1;    

  DelayMs();    

  BEEP=0;

voidAnswerTask(void)//抢答

  unsignedcharkey_val;    

  TR0=1;          

    if(flag_lock==1)

    {

      key_val=KeyScan();    

      switch(key_val)

      {

        case1:

        {

          dat_buf[0]=key_val;  

          dat_buf[1]=16;    

          time=time2;      

          alarm();        

          flag_lock=0;      

          break;

        }

        case2:

          flag_lock=0;

        case3:

          time=time2;

        case4:

        case5:

        case6:

          dat_buf[0]=key_val;  

        default:break;

      }

    dat_buf[2]=time/10;    

    dat_buf[3]=time%10;    

    dig_scan(dat_buf);      

voidSetTime(void)//调时

{

  unsignedcharmode=0;      

    if(KeyScan()==8)    

      alarm();      

      ++mode;

      if(mode=2)

        break;      

    if(KeyScan()==7)    

      if(mode==0)    

        ++time1;    

        if(time)  

          time1=1;  

      if(mode==1)    

        ++time2;    

        if(time)  

          time2=1;  

    if(mode==0)

      dat_buf[0]=16;      

      dat_buf[1]=time1/10;  

      dat_buf[2]=time1%10;  

      dat_buf[3]=16;    

    if(mode==1)

      dat_buf[0]=18;      

      dat_buf[1]=time2/10;  

      dat_buf[2]=time2%10;  

      dat_buf[3]=18;      

    dig_scan(dat_buf);        

  time=time1;  



转载请注明地址:http://www.abmjc.com/zcmbhl/2598.html