標(biāo)題:
有倒計(jì)時功能的八路搶答器
[打印本頁]
作者:
dzdiy
時間:
2015-4-12 02:54
標(biāo)題:
有倒計(jì)時功能的八路搶答器
有倒計(jì)時功能的八路搶答器,適合單片機(jī)初學(xué)者進(jìn)行電子小制作練習(xí)用,顯示部分用LCD1602作顯示,四個控制按鍵,這個有倒計(jì)時功能的八路搶答器功能如下:
1 八個人參賽,編號分號為0,1,2,3,4,5,6,7
2 主持人按下開始鍵后,八人中搶先按下鍵者,液晶上顯示其對應(yīng)的編號,并鎖定顯示,后來按下者無效。
3 按下開始鍵后蜂鳴器響起0.5s作提示
4 主持人按下選擇鍵,可以選擇調(diào)整定時對象如分或秒,一次按鍵選中秒,二次按鍵選中分,三次按鍵恢復(fù)原狀
5 按下選擇鍵后可按設(shè)定時間鍵來設(shè)定時間,秒是5s遞增,分是1分遞增。
6 如果定時搶答時間到后卻沒有選手搶答,則本次搶答無效,系統(tǒng)短暫報(bào)警,并封鎖輸入電路禁止選手超時后搶答,時間在顯示器上顯示00:00
7 主持人按下復(fù)位鍵后可以重新開始搶答。
源程序如下:
//有倒訂時功能的八路搶答器C語言程序:
#include "AT89X52.h"
#define uint unsigned int
#define uchar unsigned char
#define LCDPORT P2 //LCD數(shù)據(jù)線
#define KEY P3 //八路搶答按鍵
#define NO_KEY 25 //八路搶答按鍵
sbit lcdrs=P1^0;
sbit lcden=P1^1;
sbit speaker=P1^2; //控制蜂鳴器
sbit select=P1^3; //選擇分或秒的調(diào)整位
sbit light=P1^4;
sbit begin=P1^5; //開始鍵
sbit rst=P1^6; //復(fù)位鍵
sbit set=P1^7; //設(shè)置時間鍵
uchar table[]="00:15"; //初始值的設(shè)定
void delay(uint z); //延時z毫秒
void write_com(uchar com); //寫指令
void write_data(uchar date); //寫數(shù)據(jù)
void lcd_init(); //液晶初始化
void timer_init(); //定時器初始化
void display(uchar miao); //顯示時間
void display1(uchar fen);
void restart();
void set_time(uchar temp);
uchar keyscan(); //鍵盤掃描程序
uint aa,bb,cc,dd; //用于計(jì)數(shù)
uchar start; //開始標(biāo)志
uchar stop; //結(jié)束標(biāo)志
uchar reset; //復(fù)位標(biāo)志
uchar miao=15;
uchar fen;
bit lockflag; //鎖定標(biāo)志,標(biāo)志著已經(jīng)有人搶答成功
bit spflag; //開始聲響標(biāo)示
bit ovflag;//超時聲響標(biāo)志
void main()
{
uchar a;
lcd_init();
timer_init();
while(1)
{
a= keyscan();
if(a!=NO_KEY)
{
set_time(a); //設(shè)定時間
if(a==10) //按下開始鍵
{
start=1; //第一次按下就要開始搶答
light=0; //燈亮表示開始
TR0=1; //啟動定時器
TR1=1;
spflag=1; //標(biāo)志開始的聲響
}
if(a==9) //按下復(fù)位鍵
{
restart(); //復(fù)原到初始狀態(tài)
}
if(start) //已經(jīng)按下開始鍵后才作下面處理
{
if(a>=0&&a<8&&lockflag==0)
{
write_com(0x80+0x40) ;
write_data(0x30+a);
TR0=0; //關(guān)閉定時器停止計(jì)時
lockflag=1; //鎖定
}
}
}
}
}
/******設(shè)定時間*******/
void set_time(uchar temp)
{
if(temp==8) //調(diào)整時間
{
if(cc==1) //調(diào)整秒
{
miao+=5;
if(miao==60)
miao=0;
display(miao); //更新顯示數(shù)據(jù)
write_com(0x80+4);
write_com(0x0f); //出現(xiàn)光標(biāo)并讓光標(biāo)閃爍
}
if(cc==2) //調(diào)整分
{
fen++;
if(fen==5)
{
fen=0;
}
display1(fen); //更新顯示數(shù)據(jù)
write_com(0x80+1); //起到固定光標(biāo)位置的作用
write_com(0x0f); //出現(xiàn)光標(biāo)并讓光標(biāo)閃爍
}
}
if(temp==11) //選擇調(diào)整分或秒位
{
TR0=0;
if(cc==1) //調(diào)整秒時間
{
write_com(0x80+4);
write_com(0x0f); //出現(xiàn)光標(biāo)并讓光標(biāo)閃爍
}
if(cc==2) //調(diào)整分時間
{
write_com(0x80+1);
write_com(0x0f); //出現(xiàn)光標(biāo)并讓光標(biāo)閃爍
}
if(cc==3)
{
write_com(0x0c); //讓光標(biāo)消失
}
}
}
void restart()
{
uchar num;
start=0;
TR0=0; //關(guān)閉定時器才能停止計(jì)時
TR1=0;
miao=0;
fen=0;
spflag=0;
ovflag=0;
lockflag=0; //各種標(biāo)志清零
write_com(0x80) ;
for(num=0;num<5;num++)
{
write_data(table[num]) ; //顯示清零
}
write_com(0x80+0x40) ;
write_data(' ');
}
/*****顯示秒*******/
void display(uchar miao)
{
uchar shi,ge;
shi=miao/10;
ge=miao%10;
write_com(0x80+3) ;
write_data(0x30+shi);
write_data(0x30+ge);
}
/*****顯示分*****/
void display1(uchar fen)
{
uchar shi,ge;
shi=fen/10;
ge=fen%10;
write_com(0x80) ;
write_data(0x30+shi);
write_data(0x30+ge);
}
/******定時器0的中斷服務(wù)程序******/
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
if(aa==20)
{
aa=0;
miao--;
if(miao==0)
{
if(fen==0)
{
stop=1; //時間到了,搶答超時
TR0=0; //關(guān)閉定時器
light=1; //把燈也關(guān)了
TR1=1; //開啟定時器1,響聲
ovflag=1; //超時標(biāo)志
}
else
{
miao=59;
fen--;
}
}
display(miao); //更新顯示數(shù)據(jù)
display1(fen);
}
}
/*******定時器1的中斷服務(wù)程序*******/
void timer1() interrupt 3
{
TH1=(65536-500)/256;
TL1=(65536-500)%256; //重裝初值
if(spflag) //開始時先響500ms
{
speaker=!speaker;
dd++;
if(dd>1000)
{
dd=0;
TR1=0; //停止定時器
}
}
if(ovflag) //超時聲響
{
dd++;
if(dd>3000)
{
dd=0;
TR1=0;
}
if(dd%2==0)
{
speaker=!speaker;
}
}
}
/******定時器初始化*******/
void timer_init()
{
TMOD=0x11; //工作方式的選擇
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //50ms
ET0=1;
TH1=(65536-500)/256;
TL1=(65536-500)%256; //0.5ms
ET1=1;
EA=1;
TR0=0;
TR1=0;
}
/*****鍵盤掃描程序********/
uchar keyscan()
{
uchar key=NO_KEY;
if(KEY!=0xff)
{
delay(5); //延時5m作消抖處理
if(KEY!=0xff) //確認(rèn)有按鍵按下
{
key=KEY;
switch(key)
{
case 0xfe: key=0;
break;
case 0xfd: key=1;
break;
case 0xfb: key=2;
break;
case 0xf7: key=3;
break;
case 0xef: key=4;
break;
case 0xdf: key=5;
break;
case 0xbf: key=6;
break;
case 0x7f: key=7;
break;
}
while(KEY!=0xff) ; //等待松手
}
}
if(set==0)
{
delay(5); //延時5m作消抖處理
if(set==0)
{
key=8;
while(!set) ;
}
}
if(rst==0)
{
delay(5); //延時5m作消抖處理
if(rst==0)
{
key=9;
while(!rst) ;
}
}
if(begin==0)
{
delay(5); //延時5m作消抖處理
if(begin==0)
{
key=10;
while(!begin) ;
}
}
if(select==0)
{
delay(5); //延時5m作消抖處理
if(select==0)
{
cc++;
if(cc==4)
{
cc=0;
}
key=11;
while(!select) ;
}
}
return(key) ;
}
/****延時z毫秒*******/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--) ;
}
/***液晶寫指令******/
void write_com(uchar com)
{
lcdrs=0;
P2=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
/****液晶寫數(shù)據(jù)******/
void write_data(uchar date)
{
lcdrs=1;
P2=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
/***液晶初始化********/
void lcd_init()
{
uchar num;
lcden=0;
write_com(0x38) ; //初始化
write_com(0x0c) ; //打開光標(biāo) 0x0c不顯示光標(biāo) 0x0e光標(biāo)不閃,0x0f光標(biāo)閃
write_com(0x01) ; //清顯示
write_com(0x80) ;
for(num=0;num<5;num++)
{
write_data(table[num]) ;
}
}
復(fù)制代碼
作者:
avalycoris
時間:
2015-12-22 15:14
過來看看~
作者:
MX安心
時間:
2016-6-20 11:38
過來看看~
作者:
houniao
時間:
2019-7-25 09:46
學(xué)習(xí)學(xué)習(xí)
作者:
鵬博士PBs
時間:
2019-7-25 11:01
51單片機(jī)的8路搶答器
作者:
whiteM3
時間:
2019-7-29 10:46
圖文不符
作者:
奔跑步
時間:
2020-5-4 17:12
謝謝分享
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1