2.2按鍵輸入模塊設(shè)計(jì)
鍵盤在單片機(jī)應(yīng)用系統(tǒng)中能實(shí)現(xiàn)向單片機(jī)輸入數(shù)據(jù)、傳送命令功能,是人工干預(yù)單片機(jī)的主要手段。鍵盤實(shí)質(zhì)上是一組按鍵開關(guān)集合。通常鍵盤所用開關(guān)為機(jī)械彈性開關(guān),均利用了機(jī)械觸點(diǎn)的合、斷作用。鍵的閉合與否,反映在輸出電壓是呈現(xiàn)高電平或低電平,如果高電平表示斷開的話,那么低電平則表示鍵閉合,所以通過對電平高低狀態(tài)的檢測,便可確認(rèn)按鍵按下與否。為了確保CPU對一次按鍵動作只確認(rèn)一次按鍵,必須消除抖動的影響,這樣才能使鍵盤在單片機(jī)系統(tǒng)中的使用得更加穩(wěn)定。
搶答器的輸入按鈕使用常開開關(guān)。這些常開開關(guān)組成了搶答按鍵,硬件電路簡單,在程序設(shè)計(jì)上也不復(fù)雜,只要在程序中消除在按鍵過程中產(chǎn)生的“毛刺”現(xiàn)象就可以了。這里采用最常用的方法即延時(shí)法,其的原理為:因?yàn)椤懊獭泵}沖一般持續(xù)時(shí)間短,約為幾ms,而按鍵的時(shí)間一般遠(yuǎn)遠(yuǎn)大于這個(gè)時(shí)間,所以當(dāng)單片機(jī)檢測到有按鍵動靜后再延時(shí)一段時(shí)間(這里取10ms)后再判斷此電平是否保持原狀態(tài),如果是則為有效按鍵,否則無效。
AT89C51單片機(jī)P2.0-P2.7端口分別與S0-S7按鈕相連對應(yīng)8個(gè)不同的選手的搶答按鍵。選手通過搶答按鍵進(jìn)行搶答,單片機(jī)接收信號后內(nèi)部進(jìn)行處理并在顯示屏上顯示選手編號。內(nèi)部進(jìn)行鎖存。如圖2.2所示。
圖2.2
2.3顯示模塊設(shè)計(jì)
在單片機(jī)的應(yīng)用系統(tǒng)中,顯示器是最常見的輸出設(shè)備,也是人機(jī)對話必不可少的部分。顯示電路運(yùn)用的是LCD顯示器,如圖2.3.1所示
圖2.3.1
引腳圖如圖2.3.2所示
圖2.3.2
端口定義:RS為寄存器選擇,高電平1時(shí)選擇數(shù)據(jù)寄存器、低電平0時(shí)選擇指令寄存器。RW為讀寫信號線,高電平(1)時(shí)進(jìn)行讀操作,低電平(0)時(shí)進(jìn)行寫操作。E(或EN)端為使能(enable)端,高電平(1)時(shí)讀取信息,負(fù)跳變時(shí)執(zhí)行指令。D0~D7為8位雙向數(shù)據(jù)端。VEE為液晶對比度調(diào)整端,接正電源時(shí)對比度最弱,接地電源時(shí)對比度最高,對比度過高時(shí)會產(chǎn)生“鬼影”,使用時(shí)通過接一個(gè)10K的電位器調(diào)整對比度。
2.4時(shí)鐘電路
單片機(jī)必須在時(shí)鐘的驅(qū)動下才能工作。AT89C51單片機(jī)的時(shí)鐘產(chǎn)生方法有兩種:內(nèi)部時(shí)鐘方式和外部時(shí)鐘方式。無論何種形式,都需要外部附加電路,產(chǎn)生時(shí)鐘脈沖。
外部時(shí)鐘方式就是直接將外部的振蕩脈沖通過XTALl或XTAL2接入單片機(jī),外部時(shí)鐘方式多用于多機(jī)系統(tǒng),以便各個(gè)單片機(jī)能夠同時(shí)工作。對外部震蕩信號無特殊要求,但需保證脈沖寬度不小于20ns,且頻率應(yīng)低于單片機(jī)所支持的最高頻率。
內(nèi)部時(shí)鐘方式就是利用單片機(jī)芯片內(nèi)部的振蕩器,通過在引腳XTALl和XTAL2兩端跨接晶體振蕩器,構(gòu)成穩(wěn)定的自激振蕩器的方法,再由獲得的自激振蕩器發(fā)出穩(wěn)定的脈沖,直接送入芯片內(nèi)部的時(shí)鐘電路的方式。跨接的晶體振蕩器如果已經(jīng)起振,則會向XTAL2引腳上輸出一定幅值的正弦波。自激振蕩器的頻率取決于晶體振蕩器的頻率,常見的晶體振蕩器頻率有6MHz和12MHz。
本系統(tǒng)中采用的是內(nèi)部時(shí)鐘方式。時(shí)鐘電路如圖2.4所示。
圖2.4
從時(shí)鐘電路的示意圖中可以看到,單片機(jī)所跨接的晶體振蕩器旁邊還有兩個(gè)電容器C2和C3。C2和C3被稱為諧振電容,主要作用有兩點(diǎn):一是可以促使單片機(jī)系統(tǒng)快速起振;二是C2、C3具有對頻率進(jìn)行微調(diào)作用,有利于單片機(jī)系統(tǒng)振蕩頻率的穩(wěn)定,維持單片機(jī)的正常運(yùn)行。諧振電容的容值選擇,與所用的晶體振蕩器的頻率值有關(guān)。晶體振蕩器的振蕩頻率越高,相應(yīng)的諧振電容的容值也要提高。二者如果配合的好,可以發(fā)揮諧振電容的積極作用。反之,自激振蕩器頻率的穩(wěn)定性將受到影響。經(jīng)過大量的實(shí)際應(yīng)用,晶體振蕩器的頻率與諧振電容的容值之間形成了一定的固定搭配。例如:當(dāng)晶體振蕩器的頻率為12MHz時(shí),諧振電容的容值一般為30pF左右。
單片機(jī)在工作時(shí),由內(nèi)部振蕩器產(chǎn)生或由外直接輸入的送至內(nèi)部控制邏輯單元的時(shí)鐘信號的周期稱為時(shí)鐘周期。其大小是時(shí)鐘信號頻率的倒數(shù),常用T=1/fosc表示。圖中時(shí)鐘頻率為12MHz,即fosc=12MHz,則時(shí)鐘周期為1/12μs。此電路在加電大約延遲10ms后振蕩器起振,在XTAL2引腳產(chǎn)生幅度為3V左右的正弦波時(shí)鐘信號。
為了減小寄生電容,更好地保證振蕩器穩(wěn)定、可靠地工作。在設(shè)計(jì)電路板時(shí),晶體振蕩器和諧振電容的位置應(yīng)盡可能地靠近單片機(jī)的XTALl和XTAL2引腳 。
2.5復(fù)位電路
使CPU進(jìn)入初始狀態(tài),從0000H地址開始執(zhí)行程序的過程叫系統(tǒng)復(fù)位。單片機(jī)本身不能自動進(jìn)行復(fù)位,必須配合相應(yīng)的外部復(fù)位電路才能實(shí)現(xiàn)。從實(shí)現(xiàn)系統(tǒng)復(fù)位的方法來看,系統(tǒng)復(fù)位可分為硬件復(fù)位和軟件復(fù)位。
硬件復(fù)位必須通過CPU外部的硬件電路給CPU的RESET端加上足夠時(shí)間的高電位才能實(shí)現(xiàn)。上電復(fù)位,人工按鈕復(fù)位和硬件看門狗復(fù)位均為硬件復(fù)位。硬件復(fù)位后,各專用寄存器的狀態(tài)均被初始化,且對片內(nèi)通用寄存器的內(nèi)容沒有影響。
軟件復(fù)位就是用一系列指令來模擬硬件復(fù)位功能,最后通過轉(zhuǎn)移指令使程序從0000H地址開始執(zhí)行。對各專用寄存器的復(fù)位操作是容易的,也沒有必要完全模擬,可根據(jù)實(shí)際需要去主程序初始化過程中完成。而對中斷激活標(biāo)志的清除工作常被遺忘,因?yàn)樗鼪]有明確的位地址可供編程。有的編程人員用020000(LJMP 0000H)作為軟件陷阱,認(rèn)為直接轉(zhuǎn)向0000H地址就完成了軟件復(fù)位,就是這類錯(cuò)誤的典型代表。軟件復(fù)位是使用軟件陷阱和軟件看門狗后必須進(jìn)行的工作,這時(shí)程序出錯(cuò)完全有可能發(fā)生在中斷子程序中,中斷激活標(biāo)志已置位,它將阻止同級中斷響應(yīng)。由于軟件看門是高級中斷,它將阻止說要中斷響應(yīng),由此可見清除中斷激活標(biāo)志的重要性。
單片機(jī)的第9腳RST為硬件復(fù)位端,只要將該端持續(xù)4個(gè)機(jī)器周期的高電平即可實(shí)現(xiàn)復(fù)位,復(fù)位后單片機(jī)的各狀態(tài)都恢復(fù)到初始化狀態(tài),其電路圖如圖2.5所示。
圖2.5
復(fù)位電路的原理是單片機(jī)RST引腳接收到2uS以上的電平信號,只要保證電容的充放電時(shí)間大于2uS,即可實(shí)現(xiàn)復(fù)位,所以電路中的電容值是可以改變的。值得注意的是,在設(shè)計(jì)當(dāng)中使用到了硬件復(fù)位和軟件復(fù)位兩種功能,軟復(fù)位實(shí)際上就是當(dāng)程序執(zhí)行完畢之后,將程序指針通過一條跳轉(zhuǎn)指令讓它跳轉(zhuǎn)到程序執(zhí)行的起始地址。
2.6報(bào)警模塊設(shè)計(jì)
報(bào)警模塊的功能是在無人搶答和闡述超時(shí)的情況下報(bào)警。具體電路如圖2.6。
圖2.6
端口定義:三極管是NPN型小功率三極管,基極連接單片機(jī),發(fā)射極連接喇叭并進(jìn)行驅(qū)動。
2.7總體設(shè)計(jì)圖
三、系統(tǒng)軟件設(shè)計(jì)
實(shí)驗(yàn)的軟件設(shè)計(jì)可以分為主程序和外部中斷程序部分。
主流程圖:
外部中斷操作流程:

源程序:
#include<reg51.h>
#include<lcd1602.h>
sbit sjjia=P1^0; //定義時(shí)間加按鈕
sbit sjjian=P1^1; //定義時(shí)間減按鈕
sbit kaishi=P1^2; //定義開始按鈕
sbit fuwei=P1^3; //定義復(fù)位按鈕
sbit soud=P1^4; //報(bào)警按鈕
sbit led_r=P1^5; //定義搶答成功指示
sbit led_y=P1^6; //定義闡述時(shí)間到指示
unsigned char num[]={'0','1','2','3','4','5','6','7','8','9'},num2;
unsigned char model,time,temp;
void init() //初始化函數(shù)
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=0;
EA=1;
P1=0x0f;
model=0;
time=30;
}
void delay(unsigned char i) //延時(shí)函數(shù)
{
unsigned char j,k;
while(i--)
for(j=100;j>0;j--)
for(k=100;k>0;k--);
}
void star() //啟動
{
lcd_xml(0x80);lcd_xsj(" welcome ");
delay(100);
lcd_xml(0xc0);lcd_xsj(" 8 Way Responder");
delay(80);
}
void led_num() //刷新倒計(jì)時(shí)
{
lcd_xml(0x80);lcd_xsj(" Countdown : ");
lcd_xml(0x8d);lcd_xsj2(num[time/10]);
lcd_xml(0x8e);lcd_xsj2(num[time%10]);
}
void reset() //復(fù)位
{
TR0=0;
P1=0x0f;
led_r=0;
led_y=0;
P2=0xff;
model=0;
time=10;
led_num();
lcd_xml(0xc0);lcd_xsj(" Not started ");
}
void Not_started()
{
if(sjjia==0)
{
delay(10);
if(sjjia==0)
{
time++;
if(time==100) time=0;
led_num();
}
}
if(sjjian==0)
{
delay(10);
if(sjjian==0)
{
time--;
if(time==0) time=99;
led_num();
}
}
if(kaishi==0)
{
delay(10);
if(kaishi==0)
{
model=1;
TR0=1;
lcd_xml(0xc0);lcd_xsj(" Start Responder");
soud=1;delay(10);soud=0;
}
}
}
void anjian()
完整的Word格式文檔51黑下載地址:
http://www.zg4o1577.cn/bbs/dpj-180994-1.html