您的位置:   首页>>设计与制作>>电脑抢答器设计与制作
  一个抢答器程序
  • 来源:
  • 作者:qdq
  • 时间:2006-09-22 07:36:36
  • 网友评论:0
  • 点击数:8556
推荐阅读   加入收藏      


    其实程序大部分都是从实验程序中拿来的,很多注释都没改,呵呵 。我c语言学得还可以,把这些程序组合一下就做出这个抢答器了。有什么问题大家交流一下。

4号键 设定抢答时限 
5号键 增加抢答时限
6号键 减少抢答时限
8号键 抢答开始
9号键 复位
C-F号键 抢答组别

#include <reg51.h>
#include <intrins.h>
                 
#define uchar unsigned char
#define uint  unsigned int

uchar table<17>={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82, //0,1,2,3,4,5,6
  0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF} ;//7,8,9,A,B,C,D,E,F,-

unsigned char data dis_digit ;
unsigned char data dis_buf<8> ;
unsigned char data dis_index ;
unsigned char hour ;
unsigned char sec100 ; 
unsigned char kaishi ;
unsigned char shour ;
unsigned char daoshi ;
unsigned char shezhi ;
unsigned char qiangda ;
sbit BEEP = P3^7 ;         //蜂鸣器驱动线
//uchar dis_buf ;            //显示缓存
uchar  temp ;
uchar  key ;               //键顺序吗

void beep1() ;              //蜂鸣器-开始声音
void beep2() ;              //蜂鸣器-发生抢答声音
void beep3() ;              //蜂鸣器-时间到结束声音
void delay0(uchar x) ;      //x*0.14MS
void inc_sec() ;
void delayms(unsigned char ms) ;
//--------------------------------------------------
/* 延时子程序*/

void  delay(uchar x)
{ uchar j ;
    while((x--)!=0)
    { for(j=0 ;j<125 ;j++)
         { ;}
    }
}
//--------------------------------------------------
 /*键扫描子程序*/
 void  keyscan(void)
 { 
    P1=0x0F ;         //低四位输入  
    delay(1) ;
 temp=P1 ;         //读P1口 
    temp=temp&0x0F ;
    temp=~(temp|0xF0) ;
    if(temp==1)
        key=0 ;
    else if(temp==2)
        key=1 ;
    else if(temp==4)
        key=2 ;
    else if(temp==8)
        key=3 ;
    else
        key=16 ;
        
    P1=0xF0 ;        //高四位输入
    delay(1) ;
 temp=P1 ;          //读P1口       
    temp=temp&0xF0 ;
    temp=~((temp>>4)|0xF0) ;
    if(temp==1)
        key=key+0 ;
    else if(temp==2)
        key=key+4 ;
    else if(temp==4)
        key=key+8 ;
    else if(temp==8)
        key=key+12 ;
    else
        key=16 ;

    if(key>=12&&key<=16&&kaishi==1&&daoshi==1)
 {
     dis_buf<7>=table ; //查表得键值
  kaishi=0 ;
  TR1 = 0 ;
  beep1() ;
  qiangda=0 ;
 }
 else if(key == 8 && qiangda==1)  // 抢答开始
 { 
  TR1 = 1 ;
  kaishi=1 ;
  beep2() ;
  shezhi=0 ;
 }
 else if(key == 9) // 复位
 {
  TR1 = 0 ;
  hour = shour ;
  kaishi=0 ;
  daoshi=1 ;
  shezhi=0 ;
  qiangda=1 ;
  if(shour > 9)
   dis_buf<0> = table ;  
  else
   dis_buf<0> = 0xff ;     
  dis_buf<1> = table ; 
  dis_buf<7> = table<0> ;
 }
 else if(key == 4 && kaishi==0) // 设置限时
 {
  shezhi=1 ;
 }
 else if(key == 5&& shezhi==1) // 增加时间
 {
 shour++ ;
  if(shour > 99)
  {
   shour = 0 ;
  }
  if(shour > 9)
   dis_buf<0> = table ;  
  else
   dis_buf<0> = 0xff ;     
  dis_buf<1> = table ;  
  hour=shour ;                         //开始使用新限时
  delay(250) ;       //延时 
 }
 else if(key == 6&& shezhi==1) // 减少时间
 {
 if(shour == 0)
  {
   shour = 100 ;
  }
  shour-- ;
  if(shour > 9)
   dis_buf<0> = table ;  // 十位
  else
   dis_buf<0> = 0xff ;     // 当十位为0时不显示
  dis_buf<1> = table ;  // 个位 
  hour=shour ;                         //开始使用新限时
     delay(250) ;       //延时 
 }
 }
//--------------------------------------------------
/*判断键是否按下*/
 void  keydown(void)
 {  
   P1=0xF0 ;
 if(P1!=0xF0)
 {
   keyscan() ;
   //beep1() ;
     // while(P1!=0xF0) ;  //等待键释放
 }
 } 
//--------------------------------------------------
void beep1()
{
  unsigned char i ;
  for (i=0 ;i<100 ;i++)
   {
   delay0(4) ;
   BEEP=!BEEP ;       //BEEP取反
   } 
   BEEP=1 ;           //关闭蜂鸣器
   delay(100) ;       //延时    
  for (i=0 ;i<100 ;i++)
   {
   delay0(4) ;
   BEEP=!BEEP ;       //BEEP取反
   } 
   BEEP=1 ;           //关闭蜂鸣器
   delay(100) ;       //延时 
  for (i=0 ;i<100 ;i++)
   {
   delay0(4) ;
   BEEP=!BEEP ;       //BEEP取反
   } 
   BEEP=1 ;           //关闭蜂鸣器
   delay(250) ;       //延时  
}
//--------------------------------------------------
void beep2()
{
  unsigned char i ;
  for (i=0 ;i<100 ;i++)
   {
   delay0(5) ;
   BEEP=!BEEP ;       //BEEP取反
   } 
   BEEP=1 ;           //关闭蜂鸣器
   delay(250) ;       //延时     
}
//--------------------------------------------------
void beep3()
{
  unsigned char i ;
  for (i=0 ;i<100 ;i++)
   {
   delay0(10) ;
   BEEP=!BEEP ;       //BEEP取反
   } 
   BEEP=1 ;           //关闭蜂鸣器
   delay(400) ;       //延时  
  for (i=0 ;i<100 ;i++)
   {
   delay0(10) ;
   BEEP=!BEEP ;       //BEEP取反
   } 
   BEEP=1 ;           //关闭蜂鸣器
   delay(250) ;       //延时    
}
//--------------------------------------------------
void delay0(uchar x)    //x*0.14MS
{
 unsigned char i ;
  while(x--)
 {
  for (i = 0 ; i<13 ; i++) {}
 }
}
//-------------------------------------------------- 
    main()
 {
    P0=0xFF ;        //置P0口
    P2=0xFF ;        //置P2口  
    //dis_buf=0xBF ;
 kaishi=0 ;
 daoshi=1 ;
 shezhi=0 ;
 qiangda=1 ;
 
 TMOD = 0x11 ;
 TH0 = 0xFC ;
 TL0 = 0x17 ;
 TH1 = 0xdc ;
 TL1 = 0 ;

 shour = 10 ;
 hour=shour ;
 sec100 = 0 ;
 
 dis_buf<0> = table ;  // 时十位
 dis_buf<1> = table ;  // 时个位 
 dis_buf<2> = 0xFF ;
 dis_buf<3> = 0xFF ;
 dis_buf<4> = 0xFF ;
 dis_buf<5> = 0xFF ;
 dis_buf<6> = 0xFF ;
 dis_buf<7> = table<0> ;

 dis_digit = 0xfe ;
 dis_index = 0 ;

 TCON = 0x01 ;
 IE = 0x8a ;
 
 TR0 = 1 ;
    
    while(1)
    { 
       keydown() ;
    //P0 = dis_buf<0> ;   //键值送显示
       delay(2) ;
       //P2 = 0x7F ;
    }
  }   
//--------------------------------------------------   
void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
//    选通P2.0口数码管
// dis_buf   --- 显于缓冲区基地址 
{
 TH0 = 0xFC ;
 TL0 = 0x17 ;
 
 P2 = 0xff ;       // 先关闭所有数码管
 P0 = dis_buf ;   // 显示代码传送到P0口
 P2 = dis_digit ;      // 

 dis_digit = _crol_(dis_digit,1) ; // 位选通值左移, 下次中断时选通下一位数码管
 dis_index++ ;      // 
     
 dis_index &= 0x07 ;   // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描

void timer1() interrupt 3
{
 TH1 = 0xdc ;
 
 sec100++ ;
 
 if(sec100 >= 100)
 {
  sec100 = 0 ;
  inc_sec() ;
 }
}

void inc_sec()
{
 hour-- ; 
 if(hour > 9)
  dis_buf<0> = table ;  // 时十位
 else
  dis_buf<0> = 0xff ;     // 当小时的十位为0时不显示
 dis_buf<1> = table ;  // 时个位
 if(hour==0)
 {
 TR1 = 0 ;
 daoshi=0 ;
 beep3() ;
 }
}


void delayms(unsigned char ms) 
// 延时子程序
{      
 unsigned char i ;
 while(ms--)
 {
  for(i = 0 ; i < 120 ; i++) ;
 }

 

 

上一条:16路抢答器软件        下一条:抢答器程序使用说明
相关文章