|
(原創。┗51單片機的五路數顯搶答器設計
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei圖片_20220524183636.png (112.46 KB, 下載次數: 38)
下載附件
2022-5-24 18:36 上傳
要求如下:
51hei圖片_20220524194409.png (129.71 KB, 下載次數: 31)
下載附件
2022-5-24 19:44 上傳
程序難點分析:
1、搶答的判斷,處于開始搶答環節還是不處于搶答環節,標志位要控制好。
2、燈的閃爍問題,需要通過計數的形式解決,否則數碼管和LED一起閃爍。
附件有完整的程序(注釋詳細)+仿真原件+設計說明書+PCB圖+原理圖!在附件。!
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei圖片_20220524195525.png (80.11 KB, 下載次數: 33)
下載附件
2022-5-24 19:55 上傳
51hei圖片_20220524195521.png (65.54 KB, 下載次數: 33)
下載附件
2022-5-24 19:55 上傳
單片機源程序代碼:#include<reg51.h>
#include<intrins.h>
sbit smg1=P2^0; //定義數碼管第一位
sbit smg2=P2^1; //定義數碼管第二位
sbit deng1=P2^3; //燈1號
sbit deng2=P2^4; // 燈2號
sbit deng3=P2^5; // 燈3號
sbit deng4=P2^6; // 燈4號
sbit deng5=P2^7; // 燈5號
sbit keyksqd=P3^7; //定義開始按鍵
sbit spk=P3^6; //定義蜂鳴器
int dingshi;js; //初始倒計時時間
int keyhao; //矩陣鍵值
int buzzbiaozhi=1; //10S倒計時結束后蜂鳴器響一下的標志位
int biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0; //正確搶答唯一
int xxxx=0; //犯規搶答標志位
int flagD=0; // 控制是否顯示倒計時
int zqqd,fgqd; //zqqd正確搶答,fgqd犯規搶答
int jishu; //用來控制LED閃爍的快慢,防止數碼管閃爍
int table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0X71}; // 數碼管段碼0 1 2 3 4 5 6 7 8 9 f
//******延時子程序****//
void delayms(unsigned z) //定義毫秒
{
unsigned x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Timer0_init() //定時器0初始化
{
js=0;
TMOD=0x01; //設置定時器0為工作方式1(M1M0為01)
TH0=(65536-50000)/256; //裝初值12M晶振定時50ms數為50000,1US是1000初始值,所以50ms是5萬
TL0=(65536-50000)%256;
ET0=1; //開定時器0中斷
EA=1; //開總中斷
}
void timer0() interrupt 1 using 1 //定時器0中斷服務函數
{
TH0=(65536-50000)/256; //裝初值12M晶振定時50ms數為50000
TL0=(65536-50000)%256;
js++; //疊加20次
if(js==20)
{
js=0; //清空
dingshi--; //產生1s的倒計時
}
}
///矩陣按鍵//
unsigned char key_juzhen(void)
{
unsigned key_value=0;
P1=0xf7;//給第一列賦值0,其余全為1
if(P1!=0xf7)//判斷第一列按鍵是否按下
{
delayms(10);//消抖
switch(P1)//保存第一列按鍵按下后的鍵值
{
case 0x77: key_value=1;break; //記錄鍵值1
case 0xb7: key_value=5;break; //記錄鍵值5
case 0xd7: key_value=9;break; //記錄鍵值9
case 0xe7: key_value=13;break; //記錄鍵值13
}
}
while(P1!=0xf7);//等待按鍵松開
P1=0xfb;//給第二列賦值0,其余全為1
if(P1!=0xfb)//判斷第二列按鍵是否按下
{
delayms(10);//消抖
switch(P1)//保存第二列按鍵按下后的鍵值
{
case 0x7b: key_value=2;break; //記錄鍵值13
case 0xbb: key_value=6;break; //記錄鍵值13
case 0xdb: key_value=10;break; //記錄鍵值13
case 0xeb: key_value=14;break; //記錄鍵值13
}
}
while(P1!=0xfb);//等待按鍵松開
P1=0xfd;//給第三列賦值0,其余全為1
if(P1!=0xfd)//判斷第三列按鍵是否按下
{
delayms(10);//消抖
switch(P1)//保存第三列按鍵按下后的鍵值
{
case 0x7d: key_value=3;break; //記錄鍵值3
case 0xbd: key_value=7;break; //記錄鍵值7
case 0xdd: key_value=11;break; //記錄鍵值11
case 0xed: key_value=15;break; //記錄鍵值15
}
}
while(P1!=0xfd);//等待按鍵松開
P1=0xfe;//給第四列賦值0,其余全為1
if(P1!=0xfe)//判斷第四列按鍵是否按下
{
delayms(10);//消抖
switch(P1)//保存第四列按鍵按下后的鍵值
{
case 0x7e: key_value=4;break; //記錄鍵值4
case 0xbe: key_value=8;break; //記錄鍵值8
case 0xde: key_value=12;break; //記錄鍵值12
case 0xee: key_value=16;break; //記錄鍵值16
}
}
while(P1!=0xfe);//等待按鍵松開
return key_value;
}
///倒計時函數////
void djsxs() //第一位,第二位 顯示倒計時函數
{
int b1,b2;
b1=dingshi/10;
b2=dingshi%10; //將倒計時時間分成高低位
P0=table[b1];
smg1=0; //第1位顯示十位
delayms(3);
smg1=1; //顯示十位數字
P0=table[b2];
smg2=0; //第2位顯示各位
delayms(3); //顯示個位數字
smg2=1;
}
//**顯示F犯規**//
void djsxs10() //高位數碼管顯示F 表示搶答犯規
{
P0=0X71; //高位數碼管顯示F
smg1=0;
delayms(3);
smg1=1;
}
////*****顯示搶答選手號碼*********///////
void haoma1() //第二位數碼管顯示1
{
P0=table[1];
smg2=0;
delayms(3);
smg2=1; //第二位數碼管顯示1
}
void haoma2() //第二位數碼管顯示2
{
P0=table[2];
smg2=0;
delayms(3);
smg2=1; //第二位數碼管顯示2
}
void haoma3() //第二位數碼管顯示3
{
P0=table[3];
smg2=0;
delayms(3);
smg2=1; //第二位數碼管顯示3
}
void haoma4() //第二位數碼管顯示4
{
P0=table[4];
smg2=0;
delayms(3);
smg2=1; //第二位數碼管顯示4
}
void haoma5() //第二位數碼管顯示5
{
P0=table[5];
smg2=0;
delayms(3);
smg2=1; //第二位數碼管顯示5
}
void main()
{
jishu=0; //記錄多少毫秒累加
dingshi=10; //修改倒計時初始值
Timer0_init(); //初始化定時器中斷
while(1)
{
// smg2=0; //上電數碼管不亮,因為非門取反
// smg1=0; //上電數碼管不亮,因為非門取反
keyhao=key_juzhen();
switch(zqqd) //顯示搶答的號碼
{
case 1:haoma1(); break;
case 2:haoma2(); break;
case 3:haoma3(); break;
case 4:haoma4(); break;
case 5:haoma5(); break;
default: ;
}
if(xxxx==0) ///大前提條件是,開始搶答之前有效,否則按下開始搶答數碼管亂碼。!
{
switch(fgqd) //顯示犯規的號碼
{
case 1:djsxs10();haoma1(); break;
case 2:djsxs10();haoma2(); break;
case 3:djsxs10();haoma3(); break;
case 4:djsxs10();haoma4(); break;
case 5:djsxs10();haoma5(); break;
default: ;
}
}
///////選手正確搶答****/////////////////////
if((keyhao==1)&&(biaozhi1==1)) //在定時器運行狀態下則說明1號搶答選手按下按鍵
{
spk=0;delayms(200);spk=1;
biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
TR0=0; //啟動定時器 開始倒計時
flagD=0; //顯示倒計時函數
zqqd=1;
}
if((keyhao==2)&&(biaozhi2==1)) //在定時器運行狀態下,key1==0 則說明2號搶答選手按下按鍵
{
spk=0;delayms(200);spk=1;
biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
TR0=0; //啟動定時器 開始倒計時
flagD=0; //顯示倒計時函數
zqqd=2;
}
if((keyhao==3)&&(biaozhi3==1)) //在定時器運行狀態下 則說明3號搶答選手按下按鍵
{
spk=0;delayms(200);spk=1;
biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
TR0=0; //啟動定時器 開始倒計時
flagD=0; //顯示倒計時函數
zqqd=3;
}
if((keyhao==4)&&(biaozhi4==1)) //在定時器運行狀態下,則說明4號搶答選手按下按鍵
{
spk=0;delayms(200);spk=1;
biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
TR0=0; //啟動定時器 開始倒計時
flagD=0; //顯示倒計時函數
zqqd=4;
}
if((keyhao==5)&&(biaozhi5==1)) //在定時器運行狀態下,則說明5號搶答選手按下按鍵
{
spk=0;delayms(200);spk=1;
biaozhi1=0,biaozhi2=0,biaozhi3=0,biaozhi4=0,biaozhi5=0;
TR0=0; //啟動定時器 開始倒計時
flagD=0; //顯示倒計時函數
zqqd=5;
}
////////成功搶答指示燈//////
if(zqqd==1) ///1號
{
jishu++;
delayms(20);
if(jishu==50) //計數到50次燈亮
{
deng1=0;
}
if(jishu==100) //計數到100次燈滅
{
deng1=1;
jishu=0;
}
}
//************* //
if(zqqd==2) ///2號
{
jishu++;
delayms(20); //20*50=1秒
if(jishu==50)
{
deng2=0;
}
if(jishu==100) //計數到100次燈滅
{
deng2=1;
jishu=0;
}
}
////*************//
if(zqqd==3) //3號
{
jishu++;
delayms(20);
if(jishu==50) //計數到50次燈亮
{
deng3=0;
}
if(jishu==100) //計數到100次燈滅
{
deng3=1;
jishu=0;
}
}
////****//////
if(zqqd==4) //4號
{
jishu++;
delayms(20);
if(jishu==50) //計數到50次燈亮
{
deng4=0;
}
if(jishu==100) //計數到100次燈滅
{
deng4=1;
jishu=0;
}
}
//////**************////////
if(zqqd==5) //5號
{
jishu++;
delayms(20);
if(jishu==50) //計數到50次燈亮
{
deng5=0;
}
if(jishu==100) //計數到100次燈滅
{
deng5=1;
jishu=0;
}
}
///////////////// *************犯規搶答***************************///////////////
if((keyhao==1)&&(xxxx==0)) //說明1號搶答選手按下按鍵犯規
{
spk=0;delayms(200);spk=1; delayms(500); spk=0;delayms(200);spk=1;
fgqd=1;
}
if((keyhao==2)&&(xxxx==0))//說明2號搶答選手按下按鍵犯規
{
spk=0;delayms(200);spk=1; delayms(400); spk=0;delayms(200);spk=1;
fgqd=2;
}
if((keyhao==3)&&(xxxx==0))//說明3號搶答選手按下按鍵犯規
{
spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
fgqd=3;
}
if((keyhao==4)&&(xxxx==0)) //說明5號搶答選手按下按鍵犯規
{
spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
fgqd=4;
}
if((keyhao==5)&&(xxxx==0)) //說明4號搶答選手按下按鍵犯規
{
spk=0;delayms(200);spk=1; delayms(200); spk=0;delayms(200);spk=1;
fgqd=5;
}
////////犯規搶答指示燈//////
if(xxxx==0) ///大前提條件是,開始搶答之前有效
{
if(fgqd==1) ///1號 犯規閃爍的快
{
jishu++;
delayms(20);
if(jishu==10) //計數10次燈亮
{
deng1=0;
}
if(jishu==20) //計數到20次燈滅
{
deng1=1;
jishu=0;
}
}
//************* //
if(fgqd==2) ///2號
{
jishu++;
delayms(20);
if(jishu==10) //計數10次燈亮
{
deng2=0;
}
if(jishu==20) //計數到20次燈滅
{
deng2=1;
jishu=0;
}
//////////******剩余程序請移步附件區域***///////////////// |
-
-
搶答器電路-原理圖 PCB.rar
2022-5-24 18:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
2.51 MB, 下載次數: 19, 下載積分: 黑幣 -5
原理圖+PCB
-
-
搶答器-程序 詳細注釋.rar
2022-5-24 18:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
38.29 KB, 下載次數: 14, 下載積分: 黑幣 -5
程序
-
-
搶答器仿真.rar
2022-5-24 18:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
240.76 KB, 下載次數: 16, 下載積分: 黑幣 -5
仿真
-
-
五路數顯搶答器設計說明書.doc
2022-5-24 18:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
1.36 MB, 下載次數: 15, 下載積分: 黑幣 -5
說明書
評分
-
查看全部評分
|