其实程序大部分都是从实验程序中拿来的,很多注释都没改,呵呵 。我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
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++) ;
}
电脑抢答器网 抢答器设计与制作的专业网站 大学生课程设计的园地 |