《單片機應用技術》課件第2章_第1頁
《單片機應用技術》課件第2章_第2頁
《單片機應用技術》課件第2章_第3頁
《單片機應用技術》課件第2章_第4頁
《單片機應用技術》課件第2章_第5頁
已閱讀5頁,還剩217頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

項目2可調(diào)式電子鬧鐘系統(tǒng)設計2.1項目要求

2.2理論知識

2.3項目分析及實施

2.4項目拓展

2.5項目總結習題

2.1項目要求

本項目要求設計一個可調(diào)式電子鐘,此電子鐘具有隨意設置起始時間和鬧鈴時間的功能,系統(tǒng)開始時通過按下“啟動/停止”鍵啟動時鐘運行,默認起始時間為0時0分0秒,可以通過按下“時”、“分”、“秒”鍵分別設置時鐘起始時間,當按下“鬧鈴”鍵時,可以設置鬧鈴時間,鬧鈴時間到時,蜂鳴器響起,進行鬧鈴提醒。每次修改時間之后,按“確認”鍵完成修改。

項目重難點:

(1)51單片機定時/計數(shù)器工作原理及控制方式;

(2)51單片機的中斷系統(tǒng);

(3)51單片機與LED數(shù)碼管的接口原理;

(4)數(shù)碼管動態(tài)顯示原理及程序控制;

(5)51單片機與鍵盤的接口原理;

(6)按鍵的識別方法。

技能培養(yǎng):

(1)掌握51單片機定時/計數(shù)器工作原理及編程控制方法;

(2)掌握編寫中斷服務程序的方法;

(3)掌握51單片機與LED數(shù)碼管接口電路的設計方法,并能熟練編寫顯示程序;

(4)掌握鍵盤與單片機的接口電路設計方法;

(5)能夠熟練編寫矩陣鍵盤掃描程序。 2.2理論知識

2.2.1

51單片機的中斷系統(tǒng)

1.中斷的概念

CPU在處理某一事件A時,發(fā)生了另一事件B請求CPU迅速去處理(中斷發(fā)生);CPU暫停當前的工作,轉(zhuǎn)去處理事件B(中斷響應和中斷服務);待CPU將事件B處理完畢后,再回到原來事件A被中斷的地方繼續(xù)處理事件A(中斷返回),這一過程稱為中斷。

CPU處理中斷事件的過程如圖2-1所示。圖2-1

CPU處理中斷事件過程

2.中斷源

引起CPU中斷的根源稱為中斷源。51單片機中每個中斷源對應一個中斷標志位,當某個中斷源有申請時,相應的中斷標志位置1。

MCS-51有3類中斷:外部中斷、定時中斷、串行中斷。

由外部信號引起的中斷稱為外部中斷。51單片機有兩個外部中斷,分別從P3.2引腳和P3.3引腳引入,稱為外部中斷0(INT0)和外部中斷1(INT1)。

外部信號向CPU請求中斷的方式有兩種:電平方式、脈沖方式。

電平方式:低電平有效。單片機硬件電路在P3.2或P3.3引腳采樣到有效的低電平時,即為有效中斷請求。脈沖方式:下降沿觸發(fā)有效。硬件電路在相鄰的兩個機器周期對P3.2和P3.3采樣,如前一次為高電平,后一次為低電平,即為有效中斷請求。

除了外部中斷之外,51單片機還有兩類內(nèi)部中斷(定時中斷、串行中斷)。51單片機內(nèi)部有兩個定時/計數(shù)器(T0、T1),當定時時間到或計數(shù)值滿時,就以計數(shù)溢出信號作為中斷請求,去置位溢出標志位,向CPU請求中斷,即為定時中斷。當單片機與其他外設進行串行通信時,每當串行接收或發(fā)送完一組串行數(shù)據(jù)時,就產(chǎn)生一個中斷請求,即為串行中斷。

3.51單片機中斷系統(tǒng)結構

51單片機中,中斷源有6個,分別為INT0、INT1、T0、T1、RX、TX。每個中斷源都有一個唯一的入口地址,相應的中斷服務程序從中斷入口地址開始存放。其中,RX、TX屬于串行口中斷,它們共用一個入口地址,所以入口地址為5個,51單片機的入口地址如表2-1所示。圖2-2所示為51單片機中斷系統(tǒng)結構,主要通過TCON、SCON、IE、IP寄存器實現(xiàn)對中斷的控制。表2-1各中斷源入口地址及中斷號圖2-2

51單片機中斷系統(tǒng)結構

4.中斷控制

TCON寄存器和SCON寄存器主要是對中斷系統(tǒng)中中斷源的控制。TCON寄存器為定時/計數(shù)器控制寄存器,字節(jié)地址為88H,可以進行位尋址。每一位的定義如表2-2所示。表2-2

TCON寄存器各位定義并不是只要中斷源向CPU請求中斷,CPU都會響應該中斷,而是通過中斷允許寄存器來決定CPU是否會響應該中斷請求。51單片機中的中斷允許寄存器(IE)的字節(jié)地址為A8H,可進行位尋址,每一位的定義如表2-3所示。表2-3

IE寄存器各位定義

IE寄存器中,每一個中斷允許控制位都可由軟件編程控制。比如,若需要CPU響應來自定時器T0的中斷請求,則需要打開T0中斷允許以及總中斷允許,方法是在程序中添加指令:EA=1;ET0=1??梢姰斠驝PU響應某個請求時,不但要打開分中斷允許,還要打開總中斷允許。當總中斷允許關閉時,不管分中斷允許狀態(tài)如何,CPU都不響應中斷請求。

當幾個中斷源同時向CPU請求中斷時,就存在CPU優(yōu)先響應哪一個中斷源請求的問題(優(yōu)先級問題),一般根據(jù)中斷源的輕重緩急排隊,優(yōu)先處理最緊急事件的中斷請求。于是便規(guī)定每一個中斷源都有一個中斷優(yōu)先級別,并且CPU總是響應級別最高的中斷請求。但是當CPU正在處理一個中斷源請求的時候,另一個中斷源又提出了新中斷請求,CPU是否響應新的中斷請求,在于新中斷請求的優(yōu)先級是否高于目前正在處理的中斷請求。如果新中斷請求的優(yōu)先級高于正在處理的中斷請求,則CPU暫時中止對目前中斷處理程序的執(zhí)行,轉(zhuǎn)而去處理新中斷請求,待處理完以后,再繼續(xù)執(zhí)行原來的低級中斷處理程序,這樣的過程稱為中斷嵌套,中斷嵌套示意圖如圖2-3所示。如果新中斷請求的優(yōu)先級低于正在處理的中斷請求,則CPU將繼續(xù)執(zhí)行正在處理的中斷程序。圖2-3中斷嵌套示意圖

51系列單片機具有兩個中斷優(yōu)先級。對于所有的中斷源,均可由軟件設置為高優(yōu)先級中斷或低優(yōu)先級中斷,并可實現(xiàn)兩級中斷嵌套。一個正在執(zhí)行的低優(yōu)先級中斷服務程序,能被高優(yōu)先級中斷源所中斷。同級或低優(yōu)先級中斷源不能中斷正在執(zhí)行的中斷服務程序。

所以CPU對中斷的處理遵循以下三條原則:

(1)同時收到幾個中斷源的請求時,響應優(yōu)先級別最高的;

(2)中斷服務過程不能被同級、低優(yōu)先級的中斷源所中斷;

(3)低優(yōu)先級的中斷服務,能被高優(yōu)先級的中斷源所中斷。每個中斷源的中斷優(yōu)先級都可以由軟件指令來設定,對中斷優(yōu)先級的控制通過優(yōu)先級寄存器(IP)來實現(xiàn)。IP寄存器的字節(jié)地址為B8H,可進行位尋址,每一位的定義如表2-4所示。表2-4

IP寄存器各位定義

5.中斷處理過程

中斷的處理過程主要有四步:

(1)中斷請求,當中斷源需要中斷服務時,置位自己的中斷請求標志位。

(2)中斷響應,CPU在每個機器周期的最后一個狀態(tài)(S6狀態(tài))按優(yōu)先級或硬件查詢次序查詢各中斷請求標志位,當查詢到有效的中斷請求時,若總中斷允許打開(EA=1),對應中斷源的中斷允許打開,CPU就會響應這個中斷請求。在進行中斷服務之前,CPU要先執(zhí)行完正在執(zhí)行的那條指令,并將這條指令的地址保存到程序計數(shù)器(PC)中。

(3)中斷服務,CPU響應中斷后,去完成中斷源請求的事情,即轉(zhuǎn)去執(zhí)行中斷服務程序。

(4)中斷返回,在執(zhí)行完中斷服務程序之后,CPU返回到剛才被中斷的位置(程序計數(shù)器中保存的位置)繼續(xù)執(zhí)行程序。

6.中斷標志的清除

單片機系統(tǒng)中的中斷源只有外部中斷、定時/計數(shù)器中斷、串行口中斷,當CPU響應中斷之后,要及時清除中斷標志,否則CPU會不斷的響應中斷。

中斷標志的清除有四種情況:

(1)INT0、INT1中斷標志(IE0、IE1)。外中斷標志的清除不僅與中斷標志位有關還與中斷請求信號有關。中斷標志位在中斷響應后自動清零。對于脈沖方式的中斷請求,由于脈沖信號過后就自動消失,也就是說中斷請求信號也自動消失。對于電平方式的中斷請求,若中斷請求的低電平信號保持時間過長,又會重新置位IE0或IE1,導致CPU重復響應中斷,所以在硬件電路設計上需考慮這個低電平的持續(xù)時間,確保CPU響應中斷后,清除低電平。

(2)定時/計數(shù)器中斷標志(TF0、TF1)。CPU響應中斷后,硬件自動清除了相應的中斷請求標志TF0、TF1。

(3)串行口中斷標志(TI、RI)。CPU響應中斷后,必須在中斷服務程序中,通過軟件指令清除。2.2.2

51單片機的定時/計數(shù)器

1.定時/計數(shù)器的結構和工作原理

51單片機的兩個定時/計時器都是16位的,由高8位和低8位兩個寄存器組成,而且都為加1計數(shù)器,其內(nèi)部結構如圖2-4所示。從圖2-4中可以看出定時/計數(shù)器主要由TCON、TMOD、TH0、TL0、TH1、TL1寄存器組成。TMOD寄存器主要決定定時/計數(shù)器的功能和工作模式。TCON寄存中的TR0、TR1控制定時/計數(shù)器的啟動和停止。TH0、TL0、TH1、TL1分別存放T1和T0的計數(shù)初始值。圖2-4定時/計數(shù)器結構

2.定時/計數(shù)器的控制

51單片機中定時/計數(shù)器的工作主要由TCON和TMOD寄存器控制。TCON寄存器已經(jīng)在表2-2中介紹。TMOD寄存器用于設定定時/計數(shù)器的工作方式,其字節(jié)地址為89H,不能進行位尋址,高四位用于T1,低四位用于T0,每一位的定義如表2-5所示。表2-5

TMOD寄存器各位定義

GATE——門控位。GATE=0時,只要用軟件使TCON中的TR0或TR1為1,就可以啟動定時/計數(shù)器工作;GATA=1時,不僅要用軟件使TR0或TR1為1,同時還要使外部中斷引腳(INT0或INT1)也為高電平時,才能啟動定時/計數(shù)器工作。即此時定時器的啟動條件,加上了引腳為高電平這一條件。

C/T——定時/計數(shù)模式選擇位。C/T=0為定時模式,C/T=1為計數(shù)模式。

M1M0——工作方式設置位。定時/計數(shù)器有四種工作方式,由M1M0進行設置,如表2-6所示。表2-6定時/計數(shù)器工作方式設置

3.定時/計數(shù)器工作方式

定時/計數(shù)器的四種工作方式由TMOD寄存器中的M1M0設定,下面以T0為例,具體介紹每種工作方式。

1)工作方式0、1

工作方式0為13位定時/計數(shù)器,由TL0的低5位(高3位未用)和TH0的8位組成。TL0的低5位溢出時向TH0進位,TH0溢出時,置位TCON中的溢出標志位TF0,向CPU發(fā)出中斷請求。此方式最大記錄脈沖個數(shù)為213(8192),工作方式0的邏輯圖如圖2-5所示。圖2-5工作方式0邏輯圖

2)工作方式2

工作方式2為8位自動重裝定時/計數(shù)器。當M1M0=10時,定時/計數(shù)器工作在此方式,此時低8位TL0計數(shù),高8位TH0存放計數(shù)初始值,當TL0溢出時,不僅由硬件電路置位TF0,向CPU申請中斷,同時硬件電路會自動將存放在TH0中的計數(shù)初值置入TL0中,TL0從此初值開始重新計數(shù),此方式最大記錄脈沖個數(shù)為28(256),其邏輯圖如圖2-6所示。圖2-6工作方式2邏輯圖

3)工作方式3

只有T0有工作方式3,此時T0分成兩個獨立的8位計數(shù)器TL0和TH0,T1無此工作方式。工作方式3邏輯圖如圖2-7所示。TL0使用T0原來的控制位,既可以用作定時器也可以用作計數(shù)器,TL0的工作方式與工作方式0、1相似,但是最大計數(shù)脈沖為256個。TH0占用T1的啟動控制位(TR1)和溢出標志位(TF1),只能用作簡單的定時器。若將T1設置為工作方式3,則T1不工作。當T0工作在工作方式3時,T1可以工作在工作方式0、1、2,作為串行口的波特率發(fā)生器。圖2-7工作方式3邏輯圖 2.3項目分析及實施

2.3.1任務1——設計周期為2s的方波信號發(fā)生器

1.任務要求和分析

1)任務要求

利用單片機內(nèi)部定時/計數(shù)器產(chǎn)生周期為2s的方波信號定時信號。并將這個信號從某個I/O引腳輸出。

2)任務分析

當定時器1s時間到時,讓I/O引腳交替輸出高低電平,這相當于一個周期為2s的方波信號。

在硬件設計方面,完成本任務不需要太多外圍器件,只需要直接在方波信號的輸出引腳測試高、低電平的持續(xù)時間就可以了。在軟件程序方面,需要通過對TMOD寄存器的設置,選擇好利用哪個定時/計數(shù)器及其工作方式,并對定時計數(shù)器初始化。

2.器件及設備選擇

對于方波信號而言,關鍵的問題是定時,這里直接使用單片機內(nèi)部的定時器即可,只需要讓定時器工作在某種方式下,當1s時間到時,從某個I/O引腳交替輸出高低電平。但是如何準確判斷定時是否達到1s呢?在目前掌握的知識基礎上,最簡單的方法就是在I/O引腳接示波器去觀察,本任務中選用P2.0口進行觀察。

3.任務實施

1)周期為2s的方波信號發(fā)生器硬件原理圖設計

系統(tǒng)的硬件原理圖就是在單片機最小系統(tǒng)的基礎上加觀察設備(示波器),如圖2-8所示。在Proteus軟件中,為了方便用戶調(diào)試,已經(jīng)開發(fā)了一些虛擬儀器,如圖2-9所示,點擊

圖標,會看到有示波器、邏輯分析儀、計數(shù)器等虛擬儀器。選中示波器之后,選擇一個通道跟P2.0口相接,如圖2-8中所示。當程序運行起來之后,會自動彈出示波器窗口,如圖2-10所示。圖2-8方波信號發(fā)生器硬件原理圖圖2-9

Proteus中的虛擬儀器圖2-10周期為2s的方波信號

2)周期為2s的方波信號發(fā)生器軟件程序設計

軟件程序的編寫主要是對定時器的控制。

寫單片機定時器程序時,首先需要對定時器初始化,需要包含以下幾項:

(1)設置TMOD寄存器,確定使用哪個定時器及其工作模式;

(2)設置TH0、TL0或TH1、TL1,確定定時器的初始值;

(3)使TR0=1或TR1=1,啟動定時器,開始計時。

當定時/計數(shù)器工作在定時模式時,通過對內(nèi)部機器周期的計數(shù)達到定時的效果,所以定時器計數(shù)初始值和機器周期決定了定時器每記滿一次產(chǎn)生的定時時間。當定時器計數(shù)滿之后,會置位溢出標志位TF0(TF1),在定時器中斷打開的情況下,CPU查詢到TF0(TF1)=1時,自動轉(zhuǎn)入相應中斷服務程序。若未打開定時器中斷,可以通過軟件程序不斷查詢溢出標志位TF0(TF1)的方法,處理計數(shù)滿之后的情況。

如果使用中斷方式,還需要對IE寄存器進行設置,打開定時器中斷和系統(tǒng)總中斷。本任務中只使用了一個定時器中斷,故無需設置中斷優(yōu)先級。

使用中斷方式的定時器程序如下:程序分析:

(1)程序通過TMOD=0x01設定讓T0工作在工作方式1。主函數(shù)中有“TH0=(65536-50000)/256;TL0=(65536-50000)%256;”這兩條語句為計數(shù)初始值的設定,計數(shù)器如果不設定初始值,則將從0開始計數(shù)到最大值溢出,再開始下一個循環(huán)。本任務中要實現(xiàn)1s定時,如果從0開始計數(shù),在系統(tǒng)晶振頻率為12MHz時,機器周期為1μs,計數(shù)器在工作方式1時,最大計數(shù)值為65536,也就是說從0到65536的最長定時時間為65536μs。此時可以考慮讓計數(shù)器多中斷幾次,達到1s的時間,可是1s不是65536μs的整數(shù)倍(65536×15.2≈1s),如果讓定時器從0到65536計數(shù)中斷15次,則定時時間約為983ms,在第16次從0計數(shù)到17000時,1s時間到產(chǎn)生中斷,但是定時器只有在計數(shù)滿時才會由硬件產(chǎn)生中斷,這樣考慮顯然很復雜。如果讓定時器從某個確定的值開始計數(shù),當計數(shù)到最大時,記錄脈沖的個數(shù)N可以整除1s,這樣就簡單的多了。本程序正是這樣考慮的。讓定時器從15536開始計數(shù),當計到65536時,計數(shù)脈沖個數(shù)N=50000,則定時器產(chǎn)生一次中斷的時間為50ms,這樣只要定時器每次從15536計數(shù)到65536,中斷20次,就完成了1s的定時。本程序中采用了取商和取余的方法,直接給TH0和TL0裝入初始值,不需程序員自己計算。由于工作方式1時,定時器每計滿256個脈沖,低8位就會向高8位進1,則計數(shù)初始值Nstart除以256得到的商即是TH0的初值,余數(shù)則是TL0的初值,但是這種方法會降低程序的運行速度。定時器工作在工作方式0時,則TH0=Nstart/32;TL0=Nstart%32;因為工作方式0是低5位和高8位計數(shù),當?shù)?位計滿時就會向高8位進位。

定時器工作在工作方式2、3時,只要直接將計數(shù)初始值Nstart裝入TH0和TL0就可以了。因為工作方式2為8位定時/計數(shù)器,Nstart不可超過256。

(2)在中斷服務程序中,再次出現(xiàn)“TH0=(65536-50000)/256;TL0=(65536-50000)%256”;語句,其功能是再次裝入初始值。

(3)程序中定義的變量“num”是用來記錄進入中斷的次數(shù),定時器每50ms進入一次中斷服務程序,num就加1,在中斷服務程序中判斷“num==20”,實質(zhì)是判斷時間是否到了1s。若時間到則給P2.0口取反,同時“num”歸零,開始下一個1s的定時。

采用查詢方式的1s定時程序如下:程序分析:

(1)本程序通過不斷查詢TF0狀態(tài)的方法實現(xiàn)定時,這種方式下,需要關閉定時器中斷。語句“while(!TF0);”就是不斷查詢TF0位的狀態(tài)。當定時器未溢出時,TF0=0,那么(!TF)=1,“while(!TF0)”相當于“while(1)”,程序就會不斷的執(zhí)行“while(!TF0)”語句,當記數(shù)滿之后,硬件置位TF0=1,則(!TF)=0,此時“while(!TF0)”語句的條件為假,退出循環(huán)。這就是采用查詢方式對定時器的控制。注意:此時TF0需軟件清零。

(2)不論是中斷方式還是查詢方式,當定時器溢出之后(方式2除外),都必須重新裝入初始值。

3)軟硬件聯(lián)合調(diào)試

程序編譯通過之后,生成hex文件,加入到圖2-9所示的Proteus文件中,仿真運行效果如圖2-10所示。若觀察到方波信號周期不是兩秒,則重點檢查定時器初始值是否設置正確。注意機器周期與定時器初始值之間的關系。2.3.2任務2——設計帶時間顯示的電子秒表

1.任務要求和分析

1)任務要求

利用單片機內(nèi)部定時/計數(shù)器產(chǎn)生1s定時信號,并通過顯示器件顯示計時時間,當計時到59s時,從0開始重新計時。

2)任務分析

在硬件電路設計方面主要是如何將計時時間顯示出來。在軟件程序設計方面主要是如何將計時結果送到顯示器件上顯示?

2.器件及設備選擇

目前單片機系統(tǒng)中使用的主要顯示器件有LED數(shù)碼管、LCD液晶顯示屏和LED顯示屏。

(1)LED數(shù)碼管適合顯示數(shù)字信息,不能顯示較復雜的字符,而且需要顯示的數(shù)字較多時,需要采用動態(tài)掃描,分時輪流顯示。

(2)LCD液晶屏,顯示字符的種類較多,并且根據(jù)控制器的不同,有些液晶屏可以直接顯示漢字,而且其與單片機的接口電路簡單。

(3)LED顯示屏具有亮度高、故障低、能耗少、使用壽命長、顯示內(nèi)容多樣、顯示方式豐富等優(yōu)點。本任務選用共陽極數(shù)碼管作為顯示器件。為了防止流過數(shù)碼管的電路過大,燒毀數(shù)碼管,還需要采用電阻進行限流。

常用的LED數(shù)碼管有七段數(shù)碼管和八段數(shù)碼管。其中八段數(shù)碼管的結構如圖2-11所示。圖2-11(a)為數(shù)碼管的封裝,圖2-11(b)為內(nèi)部結構圖。圖2-11八段LED數(shù)碼管表2-7數(shù)碼管的字形碼表單片機對于LED數(shù)碼管的控制主要有兩種方式:靜態(tài)顯示和動態(tài)顯示。

靜態(tài)顯示時各LED數(shù)碼管的共陰或共陽極連接在一起接地或接+5V,每位的段選線(a~dp)分別與一個8位并行I/O口相連。靜態(tài)顯示的特點是各LED數(shù)碼管能穩(wěn)定地同時顯示各自字形。靜態(tài)顯示典型連接電路如圖2-12所示。缺點是使用元器件較多,接線復雜,而且當數(shù)碼管較多時,占用I/O口較多。圖2-12靜態(tài)顯示典型連接電路圖動態(tài)顯示是各LED數(shù)碼管的段選線(a~dp)連接在一起,由一個8位I/O口控制,公共端(稱為位選線)分別用一根I/O線單獨控制。動態(tài)顯示時,段選線上送來的字形碼由位選線控制是哪一位數(shù)碼管顯示,各LED輪流地一遍一遍顯示各自字符,因為數(shù)碼管有余輝時間,加上人眼的視覺暫留時間,所以人看到的似乎是所有LED在同時顯示不同字符。為穩(wěn)定地顯示,每位LED顯示的時間為1~5ms。8位LED動態(tài)顯示電路如圖2-13所示。圖2-13

8位LED動態(tài)顯示電路圖

3.任務實施

1)帶時間顯示的電子秒表硬件原理圖設計

采用共陽極數(shù)碼管,靜態(tài)顯示接口方式的秒表硬件原理圖如圖2-14所示。

數(shù)碼管和發(fā)光二極管一樣,如果陽極接+5V電源,電流是流入單片機引腳內(nèi)部的,沒有限流電阻的話,電流過大容易燒壞數(shù)碼管和單片機I/O口。限流電阻大小的選擇和發(fā)光二極管限流電阻選擇是同樣的原理。如果采用共陰極的數(shù)碼管,則數(shù)碼管公共端接地,單片機I/O口需要高電平才能點亮數(shù)碼管,但是由于單片機I/O口的拉電流非常小,所以要加上拉電阻,提供大的輸出電流。圖2-14數(shù)碼管靜態(tài)顯示的秒表硬件原理圖采用共陽級數(shù)碼管,動態(tài)顯示接口方式的秒表硬件原理圖如圖2-15所示。由于51單片機I/O口的拉電流非常小,不能直接驅(qū)動數(shù)碼管,所以這里使用三極管Q1和Q2為數(shù)碼管提供大的驅(qū)動電流,Q1和Q2工作在開關管狀態(tài),當給P2.0引腳低電平時,三極管Q1導通,數(shù)碼管1的公共端變?yōu)楦唠娖?,選通數(shù)碼管1。只要交替地使P2.0和P2.1引腳為低電平,就可以交替選通兩個數(shù)碼管。圖2-15數(shù)碼管動態(tài)顯示的秒表硬件原理圖

2)帶時間顯示的電子秒表軟件程序設計

在這個任務的程序設計上,與任務1的區(qū)別就是多了顯示部分的程序,程序如下:

靜態(tài)顯示方式時,秒表的程序如下:程序分析:

(1)程序中定義的數(shù)組table[]用來存放數(shù)碼管顯示0~9數(shù)字對應的字形碼。

(2)本程序中使用定時器1的工作方式2來完成定時。由于工作方式2是8位自動重裝的工作方式,最大計數(shù)值只有256,所以設計數(shù)初始值為56,也就是定時器每中斷一次的時間為200μs(晶振12MHz),那么中斷5000次就可以達到

1s。注意定時器工作方式2的特點——自動重裝初始值,所以在中斷服務程序中,不需要像任務1中一樣再裝一次初始值。這里在中斷服務程序中用“num++”,來記錄進入中斷服務程序的次數(shù)。

(3)主函數(shù)中在while循環(huán)里不斷的判斷num是否等于5000,若num==5000,則對num清零,同時記錄秒時間的變量second加1,當second等于59時,對second清零,重新記錄下一個一分鐘。

(4)P0=table[second/10];P2=table[second%10];”這兩句指令是將秒十位和秒個位送到數(shù)碼管上顯示,在數(shù)碼管靜態(tài)顯示中,只需要向與數(shù)碼管連接的I/O口送需要顯示的字形碼,數(shù)碼管就可以顯示相應數(shù)字了。

當采用動態(tài)顯示方式時,秒表的程序如下:程序分析:

(1)在數(shù)碼管的動態(tài)顯示程序中,關鍵是要不斷給數(shù)碼管送字形碼和位碼,所以顯示部分的程序放在while(1)循環(huán)中。

(2)“delayms(5);”延時是為了讓數(shù)碼管穩(wěn)定顯示,如果沒有延時,由于動態(tài)顯示的特點(分時輪流顯示),快速改變段選端和位選端的數(shù)據(jù),會使得數(shù)碼管顯示亮度不夠甚至出現(xiàn)亂碼。但是延時時間不可過長,否則會出現(xiàn)閃爍。所以動態(tài)顯示的延時很重要,延時太短,數(shù)碼管點亮時間過短,亮度不夠;延時太長,回掃間隔過大(超過11ms),肉眼就會感覺到閃爍。這個可以根據(jù)數(shù)碼管的多少及硬件電路自行調(diào)整。

(3)“P0=0xff;”在這里的作用為“消影”,如果去掉這一句,當延時時間到時,P2口送出秒“個”位的位碼,那么秒“十”位的字形碼就會顯示到“個”位數(shù)碼上,雖然緊接著送出了“個”位字形碼,但這有可能引起數(shù)碼管顯示亂碼。加上“P0=0xff;”后,在送位碼之前,P0口段碼端的數(shù)據(jù)全是高電平,哪個數(shù)碼管都不會亮,接著送秒“個”位的位碼和字形碼,這樣可以避免亂碼的現(xiàn)象。

3)軟硬件聯(lián)合調(diào)試

在調(diào)試中,若發(fā)現(xiàn)數(shù)碼管顯示亂碼的現(xiàn)象,如果采用靜態(tài)顯示接口電路,則需在硬件上檢查數(shù)碼管是否是共陽級的,并保證接口正確,在軟件上需檢查字形碼是否正確。如果采用動態(tài)顯示接口電路,則需注意延時時間和消影。

2.3.3任務3——可調(diào)式電子鬧鐘的系統(tǒng)設計

1.任務要求和分析

1)任務要求

在任務2中,實現(xiàn)了“秒”的計時和顯示,但是沒有“分”和“時”的顯示,同時任務2中的系統(tǒng)不能實現(xiàn)停止/啟動等功能。在這個任務中,要求可以顯示“分”和“時”,以“**—**—**”的方式顯示,并且使電子鐘具備能夠隨意設置起始時間、停止計時、定時鬧鈴提醒的功能。

2)任務分析

電子鐘需要顯示的內(nèi)容增多了,那么顯示器件也要改變,根據(jù)顯示要求需要八只數(shù)碼管。如此多的數(shù)碼管如果使用靜態(tài)顯示接口電路,顯然I/O接口不夠用,所以采用動態(tài)顯示的方式,八只數(shù)碼管只需要兩個I/O口就夠了。

要實現(xiàn)電子鐘的時間設置、鬧鈴設置等功能,就需要人機接口器件,通過這個器件,用戶可以控制電子鐘的運行。

2.器件及設備選擇

關于電子鐘時間的顯示采用8位一體共陽級數(shù)碼管,對電子鐘的控制則通過按鍵來完成。

在單片機系統(tǒng)中,鍵盤是十分重要的人機對話的組成部分,是人向機器發(fā)出指令、輸入信息的必需設備。一個按鍵實際上就是一個開關元件,如圖2-16所示為單片機系統(tǒng)中常用的按鍵。根據(jù)單片機與按鍵的接口方式,鍵盤可以分為獨立式鍵盤、矩陣式鍵盤、編碼式鍵盤等。圖2-16開關式按鍵所謂獨立式鍵盤,就是每一個按鍵的電路是獨立的,占用一條數(shù)據(jù)線,一個鍵是否按下不會影響其他按鍵的狀態(tài)。這種鍵盤占用硬件資源多,適合少量按鍵的情況。如圖2-17所示,圖中S1~S4是四個獨立的按鍵,系統(tǒng)工作時,通過檢測與按鍵相接的I/O口的電平狀態(tài)判斷是否有鍵按下。對于圖2-17,當無鍵按下時,P1.0~P1.3引腳由于上拉電阻的作用,處于高電平,如果有鍵按下,I/O口的電平就會被拉向低電平。圖2-17獨立按鍵接口原理圖當系統(tǒng)中按鍵較多時,采用獨立式鍵盤顯然不可取,因為占用太多的I/O口,這時可將鍵盤排成行列式,如圖2-18所示,鍵盤的行線一端經(jīng)電阻接+5V電源,另一端接單片機的輸入口。各列線的一端接單片機的輸出口,另一端懸空。行線與列線在交叉處不相通,而是通過一個按鍵來連通。這種結構如果有m條行線,n條列線,則可以構成具有m×n個按鍵的鍵盤。可見當需要的按鍵較多時,采用矩陣式鍵盤可以大大地節(jié)省I/O口。圖2-18矩陣鍵盤結構在矩陣鍵盤中最關鍵的是如何知道是哪個鍵被按下,也就是按鍵的識別問題。在矩陣鍵盤中,對按鍵的識別主要有兩種方法:行掃描法和線翻轉(zhuǎn)法。

線翻轉(zhuǎn)法掃描的原理是:

(1)將所有行線置為低電平,列線置為高電平,讀取列線狀態(tài),并記錄下來(若有鍵按下,則有一根列線為低電平);

(2)將所有行線置為高電平,列線置為低電平,讀取行線狀態(tài),并記錄(若有鍵按下,則有一根行線為低電平);行和列都為低電平的那個交叉點上的鍵就是閉合的鍵。將兩次記錄結果按位“或”運算,就是該鍵的鍵碼。比如圖2-18中,假設鍵盤與P1口相接,首先往P1口送0x0f(行低列高),再去讀取P1口電平,若讀回的值為0x0d,說明第二列有鍵按下,但是不能確定是在哪一行;接著往P1口送0xf0(行高列低),再去讀取P1口電平,若讀回的值為0x70,說明是第四行有鍵按下,兩次讀回的值相“或”,其值為0x7d,此時可以確定剛剛被按下的鍵是“S14”鍵,也就是說“S14”鍵的鍵碼(鍵值)是0x7d。由此可以確定圖2-18中每個鍵的鍵碼如表2-8所示。表2-8矩陣鍵盤的鍵碼行掃描法的原理是:

(1)先判斷鍵盤中有無鍵按下。將全部行線置成低電平,列線置高電平,然后檢測列線,只要有一條列線為低電平,則表示有鍵按下,而且閉合的鍵位于低電平列線與行線的交叉處。

(2)判斷閉合鍵所在的位置。在確認有鍵按下后,依次將行線置為低電平,即只有一根行線為低電平,其余為高電平。再確定某根行線為低電平后,依次檢測各列線的電平狀態(tài),當檢測到某根列線也為低電平后,則該列線與置為低電平的行線交叉處的按鍵就是閉合的按鍵。除了矩陣鍵盤,還可以使用編碼式鍵盤解決按鍵較多的問題。編碼式鍵盤是利用編碼器將按鍵進行二進制編碼之后,送入I/O口,利用74LS148編碼器,將8個按鍵進行編碼,如圖2-19所示。比如,當單片機P2.2~P2.0引腳讀到011時,就可以確定是第三個鍵按下。圖2-19編碼式鍵盤結構由于鍵盤是由操作人員去控制的,很難預測什么時候會有按鍵,所以如何及時準確地獲取按鍵信息極為重要。因為按鍵有隨機性,所以在程序控制上就要不斷讀取跟鍵盤相接的I/O口狀態(tài),可是這樣做就會占用CPU大量的時間,使得CPU無暇做其他的事情?;谝陨显颍瑔纹瑱C對鍵盤的控制方式主要有定時掃描和中斷掃描。

定時掃描就是每隔一段時間讀取一次與鍵盤相接的單片機I/O口狀態(tài),可以利用單片機內(nèi)部的定時器來控制鍵掃描的間隔,當定時時間到時,在中斷服務程序中進行掃描,若有鍵按下,進行鍵識別之后,再對按鍵進行處理。定時掃描鍵盤不管是否有鍵按下,只要時間到就會去掃描鍵盤,很多時候沒有按鍵,那就是空掃,為了提高CPU的效率,可以利用中斷方式掃描鍵盤。在這種方式下,鍵盤的接口電路也會有所改變,如圖2-20所示。鍵盤的四條行線經(jīng)過與門連接到外中斷上,系統(tǒng)工作時,讓所有的列線都處于低電平,行線處于高電平,當有鍵按下時,就會有一根行線被拉為低電平,經(jīng)過與門之后就會觸發(fā)一次外中斷,在中斷服務程序中再進行鍵識別,判斷具體是哪個按鍵。這種方式避免了對鍵盤的空掃描,提高了CPU的效率。圖2-20中斷掃描鍵盤方式接口電路根據(jù)任務要求,設計的電子鐘可以進行鬧鈴提醒,那么當鬧鈴時間到時,如何提醒用戶呢?單片機系統(tǒng)中,大部分都是使用蜂鳴器來做提示或報警。蜂鳴器種類很多,一般按結構性能分為電磁式蜂鳴器和電子式蜂鳴器兩大類。按是否自帶震蕩源分為有源式蜂鳴器和無源式蜂鳴器,這里的“源”不是指電源,而是指震蕩源。也就是說,有源蜂鳴器內(nèi)部帶震蕩源,所以只要一通電就會叫。無源式蜂鳴器內(nèi)部不帶震蕩源,所以如果用直流信號無法令其鳴叫,必須用2KHz

~5KHz的方波去驅(qū)動它,圖2-21是有源蜂鳴器的形狀。由于蜂鳴器的工作電流一般比較大,以致于單片機的I/O口是無法直接驅(qū)動的,所以要利用放大電路來驅(qū)動,一般使用三極管來放大電流就可以了。蜂鳴器的驅(qū)動電路如圖2-22所示。圖2-21有源蜂鳴器形狀圖2-22蜂鳴器驅(qū)動電路

3.任務實施

1)可調(diào)式電子鬧鐘硬件原理圖設計

在這個任務中,鍵盤的功能主要是設置鬧鐘的啟動、停止、起始時間、鬧鈴設置等,需要的按鍵較多,所以采用了矩陣鍵盤。而且鬧鐘顯示的時間信息有“時”、“分”、“秒”,所需數(shù)碼管較多,故顯示部分采用數(shù)碼管動態(tài)顯示。本書所用實驗板上數(shù)碼管及鍵盤部分的接口原理圖如圖2-23所示。圖2-23鍵盤、數(shù)碼管與單片機連接圖

2)可調(diào)式電子鬧鐘軟件程序設計

在進行程序設計之前,首先要明確對時鐘的操作步驟,然后進行程序編寫。這個任務中,對時鐘的操作步驟為:開機默認顯示“00-00-00”,當按下“S15”鍵后時鐘開始工作,默認鬧鈴時間為“06-00-00”,若需要修改當前時間,需按下相應的“時”、“分”、“秒”按鍵,然后按數(shù)字鍵修改,修改的時間會在數(shù)碼管上顯示,修改完成后需要按“確認”鍵以保存修改數(shù)據(jù)。當需要修改鬧鈴時間時,先按下“鬧鈴”鍵,再分別按“時”、“分”鍵修改鬧鈴時間,修改后的鬧鈴時間也會在當前數(shù)碼管上顯示,但是當按下“確認”鍵之后,數(shù)碼管上的鬧鈴時間會消失并顯示當前時間,當鬧鈴時間到時,連接在P2.4引腳上的蜂鳴器會響起,進行提醒一分鐘。這個任務的程序設計中,主要有三大部分:

(1)計時部分程序;

(2)數(shù)碼管的動態(tài)顯示程序;

(3)鍵盤掃描及鍵處理程序。

計時部分,依然采用內(nèi)部定時器完成計時功能。其流程圖如圖2-24所示。圖2-24計時程序流程圖鍵掃描部分的流程圖如圖2-25所示,可以看到通過鍵掃描來判斷是否有鍵按下,鍵掃描的實質(zhì)就是讀取跟鍵盤相接的I/O口的電平狀態(tài),如果讀到低電平,就說明有鍵按下。鍵盤其實就是機械彈性開關,平時是和觸點斷開的,只有當按下時才和觸點閉合。由于觸點的彈性作用,一次按鍵從開始到穩(wěn)定閉合要經(jīng)過多次彈跳,會連續(xù)產(chǎn)生多個脈沖,按鍵斷開時,也有同樣的問題,這種現(xiàn)象稱為鍵盤抖動,抖動波形如圖2-26所示。圖2-25鍵掃描流程圖圖2-26鍵盤抖動波形圖鍵盤抖動時間的長短跟鍵盤的機械特性有關,一般為5ms~10ms,按鍵穩(wěn)定閉合時間的長短由操作人員決定。由于鍵盤有抖動特性,會出現(xiàn)一次按鍵被CPU讀取多次的現(xiàn)象,因此為了確保一次按鍵只被CPU讀取一次,必須消除鍵盤抖動的影響。

鍵盤消抖動通常有硬件消抖動和軟件消抖動兩種方法。

常用的硬件消抖動的電路如圖2-27所示。圖2-27(a)利用RS鎖存器消抖,這種電路只適用于單刀雙擲開關;圖2-27(b)利用電容消抖動,適合輕觸式按鍵。圖2-27鍵盤消抖動硬件電路

軟件消抖動具體程序如下:程序分析:

(1)在主程序中,“TMOD=0x12;”是設置T1工作在方式1,T0工作在方式2,接下來對T1和T0設置初始值,T1每50ms中斷一次,T0每250μs中斷一次。在這個程序中,T1是來完成時鐘計時的,在T1中斷服務程序中判斷進入中斷的次數(shù)是否達到20次,若是,則說明1s時間到,調(diào)用time()函數(shù)。T0定時器是用來完成定時鍵掃描的,每5ms調(diào)用一次鍵掃描。定義的全局數(shù)組dis_buf[]將要顯示的字形碼放在一個表格中,然后每次從這個表格里面取數(shù),送到P0口即可。語句“dis_buf[0]=dis_table[hour/10];”是對顯示緩沖區(qū)的初始化,比如起始時間是0時0分0秒,那么將“0”對應的字形碼從dis_table[]數(shù)組中取出,放入dis_buf[]數(shù)組中相應的位置?!皃os_scan”用于數(shù)碼管的位選擇,初始值為0xfe,即首先選擇左邊第一個數(shù)碼管。變量“dsy_num”是顯示緩沖區(qū)數(shù)組dis_buf[]的索引號。在while(1)大循環(huán)中,不斷調(diào)用顯示函數(shù)和鬧鈴函數(shù)。

(2)在顯示函數(shù)display()中,主要是輪流地從P0口送出位碼和字形碼,程序中:

wei_LE=1;

P0=pos_scan;//鎖存位碼

wei_LE=0;這三句的功能是,先打開控制位碼的鎖存器的鎖存使能,然后從P0口送出位碼,接著關閉鎖存使能,這樣位碼就會鎖存在鎖存器的Q端,之后P0口送出的數(shù)據(jù)就不會影響到剛剛送出的位碼信息。接下來用同樣的方法打開段選鎖存使能,送出段碼并鎖存?!皃os_scan=_crol_(pos_scan,1);”語句是將位碼循環(huán)左移一位,以便選擇下一個數(shù)碼管?!癲sy_num=(dsy_num+1)%8;”是將顯示緩沖區(qū)索引循環(huán)移位,八個數(shù)碼管要顯示的字形碼從左到右依次是放在dis_buf[]數(shù)組中的,緩沖區(qū)有八個元素,通過這個語句可以讓dsy_num的值在0~7之間循環(huán)?!癙0=0xff;”在這里的作用稱為“消影”,因為我們系統(tǒng)的段選和位選是共用P0口的。在下一次送位碼之前,段碼數(shù)據(jù)是留在P0口的,當位碼鎖存使能一打開,段碼數(shù)據(jù)就會立刻送到位選端,這個時間雖然很短暫,但是由于硬件電路速度較快以及由于動態(tài)顯示需要不斷掃描的原因,也會造成亂碼的出現(xiàn)。所以在下一次送位碼之前,先通過送0xff,關閉所有位選。這樣,只要在主函數(shù)中不斷的調(diào)用顯示函數(shù),就可以實現(xiàn)數(shù)碼管的動態(tài)顯示。

(3)在key_scan()鍵掃描函數(shù)中,主要是獲取按鍵的鍵碼(鍵值),第一句“P3=0x0f;”的作用是將行線置為低電平,列線置為高電平;“key_state=P3;”語句是讀取P3口的狀態(tài),存放在變量key_state中,若key_state不等于0x0f,說明有鍵按下,經(jīng)過“delayms(5);”延時消抖動之后,再讀一次P3口的狀態(tài),若依然不等于0x0f,說明確實有鍵按下。接著給P3口送0xf0,讓列線為低電平,行線為高電平,“key_state=key_state^P3;”是將P3口的狀態(tài)讀回來再與剛才存放在key_

state中的值相“異或”(相“或”也可以)之后再賦給key_state,此時key_state的值就是相應按鍵的鍵碼。swich結構中,根據(jù)key_state的值給變量key_num賦值,本系統(tǒng)中給每個鍵編了一個鍵號,分別是0~15。“while(P3!=0xf0);”語句是等待按鍵釋放,如果鍵一直被按下,那么P3口的狀態(tài)就不是等于0xf0,程序就會一直在這里循環(huán)等待,這樣做的目的是避免在沒有鍵釋放的情況下,進入鍵處理。在單片機的按鍵檢測中,要等待鍵釋放之后再進入相應按鍵的處理任務。若不加等待按鍵釋放,由于硬件執(zhí)行代碼的速度很快,而且鍵盤是不斷檢測的,那么一次按鍵會被檢測很多次,造成錯誤。

“if(key_num!=16)key_manage();”是為了避免沒有按鍵時調(diào)用鍵處理程序,當沒有按鍵時讓key_num等于16,若有按鍵時,key_num就等于0~15之間的一個值,此時就會調(diào)用鍵處理程序。

(4)key_manage()函數(shù)是鍵處理函數(shù),根據(jù)key_num的值進入不同的case分支,當按下0~9的數(shù)字鍵時,會將鍵號存入預先定義的time_buffer[]數(shù)組中,這個數(shù)組是用來暫時存放修改的時間數(shù)據(jù)的,“dis_buf[time_i]=dis_table[key_num];”是將鍵號對應的字形碼送到顯示緩沖區(qū)顯示,變量“time_flag”記錄“時”、“分”、“秒”鍵被按下的標志,當需要改變時鐘時間或者鬧鈴時間時,需要先按下相應的“時”、“分”、“秒”鍵,再按0~9數(shù)字鍵,最后按“確認”鍵才能使新設置的時間或鬧鈴生效。在“確認”分支中,根據(jù)“alarm_flag”的狀態(tài)決定新設置的時間是鬧鈴時間還是時鐘起始時間,因為如果之前按下過“鬧鈴”鍵,則“alarm_flag”就會等于1,否則為0。若“alarm_flag”等于0,就會根據(jù)time_flag的值,從time_buffer[]數(shù)組中取出數(shù)據(jù)修改當前的時間信息,time_buffer[]數(shù)組中前兩個元素存放“時”,第二和第三個元素存放“分”,最后兩個元素存放“秒”。若“alarm_flag”等于1,則會從time_buffer[]數(shù)組中取出前兩個元素經(jīng)過計算后之后賦給“hour_alarm”,取出第二和第三個元素經(jīng)過計算后賦給“minute_alarm”,記錄新的鬧鈴時間。

(5)alarm_manage()鬧鈴管理函數(shù)中,將鬧鈴時間和當前時間進行比較,若相等則蜂鳴器響起,進行鬧鈴提醒。對于蜂鳴器的控制,只要給P2.4口低電平,三極管就會導通,此時蜂鳴器中有電流流過,就會發(fā)聲。

3)軟硬件聯(lián)合調(diào)試

本任務程序較大,建議在程序編寫時,分模塊調(diào)試。檢查鍵掃描的程序中,讀回的鍵值是否正確;定時器的中斷號是否正確;蜂鳴器的極性是否接正確;驅(qū)動電路是否正常。

僅僅在keil的調(diào)試狀態(tài)下,檢查本程序的功能,難度較大。可以通過單片機仿真器幫助調(diào)試。在較大程序的調(diào)試中,利用仿真器幫助調(diào)試,可以大大節(jié)省程序的開發(fā)時間。利用仿真器進行調(diào)試可以單步運行,指定斷點、停止等,極為方便。

也可以利用軟件仿真調(diào)試,由于本任務具有人機交互接口(鍵盤),所以不能像前面一樣,直接在Proteus軟件下仿真運行,而需要Keil和Proteus軟件的聯(lián)合調(diào)試。在進行Keil和Proteus兩個軟件的聯(lián)合調(diào)試之前,需進行如下設置:

(1)把proteus安裝目錄下的VDM51.dll(\Proteus7Professional\MODELS)文件復制到Keil安裝目錄的\C51\BIN目錄中。

(2)編輯C51里的tools.ini文件,加入:TDRV1=BIN\VDM51.DLL("PROTEUSVSMMONITOR51DRIVER");注:“TDRV1”后面的“1”不要與tools.ini文件原有的數(shù)字重復。

(3)在keil里設置:Project-->Optionsforproject窗口選擇“Debug”標簽頁,如圖2-28所示,選中“ProteusVSMMonitor-51Driver”,再進入seting,如果同一臺機同時運行Keil和Proteus,則IP名為127.0.0.1,如不是同一臺機則填另一臺機的IP地址。端口號一定為8000。圖2-28設置“Debug”標簽頁

(4)Proteus軟件里打開需要調(diào)試的文件,在“Debug”菜單下,勾選“useremotedebugmonitor”。

(5)打開Keil,按F5開始聯(lián)合調(diào)試。

2.4項目拓展

2.4.1電子音樂盒設計

1.樂理知識介紹

在進行音樂盒設計之前,首先要明白樂曲演奏的原理,我們平時唱的哆、、咪、法、嗦、啦、唏,每個音符具有固定的頻率值,這個稱為音調(diào),頻率越大音調(diào)越高,每個音符的持續(xù)時間就是音長。當演奏樂曲時,只要按照每個音符的頻率和時長送出激勵信號到揚聲器,揚聲器就可以發(fā)出樂曲的聲音。音符中的7個音名稱為C、D、E、F、G、A、B,對應于簡譜中的1、2、3、4、5、6、7。由音樂的12平均率可知:每兩個八度音之間的頻率相差一倍,即中音1的頻率是低音1頻率的兩倍。而且在兩個八度音之間又分為12個半音,相鄰兩個半音之間的頻率比為。音名E與F之間為半音,B與C之間為半音(即低音B到中音C),其余都是全音。在國際上,規(guī)定a1這個音的頻率為440Hz,稱為第一國際高度。其余音的頻率可以根據(jù)十二平均率依次算得,如表2-9所示。表2-9音名與頻率關系表在一首樂譜中,除了音調(diào)的高低之外,還有這個音調(diào)要持續(xù)多長時間,也就是我們通常所說的節(jié)拍(也稱為音長),這樣樂曲才會婉轉(zhuǎn)動聽。音調(diào)的節(jié)拍通常有4分音符、8分音符、16分音符、2分音符、全音符等。假設4分音符的音長為T,則8分音符的音長為T/2,依次類推,以簡譜中“3”為例,音長與節(jié)拍數(shù)的關系如表2-10所示。表2-10音長與節(jié)拍數(shù)的關系

2.LCD1602介紹

在這個音樂盒設計中,我們通過液晶顯示器顯示所播放音樂的名稱。目前,市場上液晶顯示器件種類繁多,根據(jù)顯示的內(nèi)容可分為字段式、字符點陣式、圖形點陣式三種,圖形點陣式者可以顯示漢字。由于液晶顯示器顯示內(nèi)容豐富、外形美觀、無需定制、使用方便等特點,逐漸成為LED顯示器的替代品。將LCD(LiquidCrystalDisplay)和顯示控制器、驅(qū)動器、字符存儲器做到一塊板子上,就成為顯示模塊,稱為LCM。單片機系統(tǒng)中常用的液晶顯示器有LCD1602、LCD12864、LCD12232等。液晶顯示器的型號通常是按照顯示字符的行數(shù)或液晶點陣的行列數(shù)來命名的。比如1602的意思是可以顯示兩行,每行顯示16個字符;12864的意思是內(nèi)部有128*64個點陣。液晶顯示器是否能夠直接顯示漢字跟控制器有關系,因為漢字屬于圖形顯示。比如12864液晶顯示模塊,若控制器的型號是ST7920則可以直接顯示漢字,若控制器型號是KS0108則不帶中文字庫,只能通過打點的方法顯示漢字。

考慮到本項目設計中只顯示歌曲的名字,所以使用了LCD1602字符型液晶顯示模塊顯示歌曲的英文名稱。對于液晶模塊的控制,首先要確定與單片機的接口電路,其次是軟件程序的控制。液晶與單片機的接口主要有串行和并行兩種方式,這里我們采用并行接口方式。并行LCD1602模塊的引腳功能如表2-11所示。表2-11

LCD1602液晶模塊接口說明

1602控制器內(nèi)部有80B的RAM緩沖區(qū),其映射關系如表2-12所示。當向00~0F、40~4F地址中寫入數(shù)據(jù)時,可以立刻顯示在顯示屏上,當數(shù)據(jù)寫入到10~27、50~67地址時,需要通過移屏指令將數(shù)據(jù)移入到顯示區(qū)。表2-12

1602內(nèi)部RAM映射關系表

LCD1602的軟件控制主要是通過指令來進行的。指令如表2-13所示。表2-13

LCD1602指令表指令1:清屏。光標復位到地址00H位置。

指令2:光標返回。光標返回到地址00H。

指令3:光標和顯示模式設置。I/D:光標移動方向,高電平右移,低電平左移;S:屏幕上所有文字是否左移或者右移,高電平表示有效,低電平則無效。

指令4:顯示控制。D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示;C:控制光標的開與關,高電平表示有光標,低電平表示無光標;B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。

指令5:光標/字符移位。S/C:高電平時移動顯示的文字,低電平時移動光標;R/L:高向左,低向右。指令6:功能設置命令。DL:高電平時為4位總線,低電平時為8位總線;N:低電平時為單行顯示,高電平時雙行顯示;F:低電平時顯示5×7的點陣字符,高電平時顯示5×10的點陣字符。(有些模塊是DL:高電平時為8位總線,低電平時為4位總線。)

指令7:字符發(fā)生器RAM地址設置。地址:字符地址×8+字符行數(shù)。(將一個字符分成5×8的點陣,一次寫入一行,8行就組成一個字符。)

指令8:置數(shù)據(jù)存儲器地址,第一行為:00H——0FH,第二行為:40H——4FH。指令9:讀忙標志和光標地址。BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數(shù)據(jù),如果為低電平表示不忙。

指令10:寫數(shù)據(jù)。

指令11:讀數(shù)據(jù)。

當向1602寫數(shù)據(jù)、指令或讀數(shù)據(jù)、狀態(tài)時的基本操作時序如表2-14所示。表2-14

1602操作時序表

3.電子音樂盒硬件電路設計

音樂盒硬件電路的設計要依據(jù)所實現(xiàn)的功能確定,本項目中設計的音樂盒,可以通過按鍵切換播放的音樂,同時所播放音樂的曲名會在LCD1602液晶屏上顯示,音樂盒整體硬件原理圖如圖2-29所示,本原理圖是在proteus中繪制的,1602模塊沒有列出15、16腳。系統(tǒng)中通過接在P3.2引腳上的獨立按鍵切換播放的曲目。圖2-29電子音樂盒硬件原理圖

4.電子音樂盒軟件程序設計

本項目中設計的音樂盒可以播放“HappyBirthday!”和“JingleBells”兩首歌曲,兩首歌的曲子如下:前面已經(jīng)介紹了樂理知識,每個音調(diào)都對應不同的頻率,那么要根據(jù)音調(diào)產(chǎn)生相應的頻率信號,必須不斷的改變定時器的初始值,為了優(yōu)化程序結構,先將音調(diào)頻率與定時器初始值關系寫成頭文件,以后也可以在其他的程序中使用。

頭文件內(nèi)容如下:本項目的程序中主要有三個模塊,分別是樂曲播放模塊、曲目名稱顯示模塊、按鍵切換模塊。樂曲播放模塊中利用定時器0產(chǎn)生不同頻率的信號,即音調(diào);利用定時器1產(chǎn)生延時,即節(jié)拍;按鍵切換模塊利用按鍵觸發(fā)外中斷,從而進行播放樂曲的切換。

液晶顯示模塊的程序如下:程序分析:

(1)程序中包含了兩個自己創(chuàng)建的頭文件“musicTab.h”和“l(fā)cd.h”,“musicTab.h”頭文件的內(nèi)容在前面已經(jīng)列出,是與音調(diào)頻率與計數(shù)初始值對應的宏定義?!發(fā)cd.h”是對“l(fā)cd.c”文件中各函數(shù)的聲明,其內(nèi)容如下:

voiddelayms(unsignedchar);

voidLCD_write_commuter(unsignedchar);

voidLCD_write_data(unsignedchar);

voidinit_lcd();

voidlcd_str(unsignedchar*,unsignedchar);這樣做體現(xiàn)的是一種模塊化的設計思想,以后在其他工程中用到LCD1602顯示屏時,可以直接將“l(fā)cd.c”文件添加到工程中,并在主函數(shù)文件中包含“l(fā)cd.h”頭文件。當一個工程下包含多個“*.c”文件時,工程窗口如圖2-30所示。圖2-30

Keil中包含多個*.c文件的工程窗口

(2)在程序開始定義了數(shù)組birthday_freq[]、birthday_length[]來存放樂曲的音調(diào)和節(jié)拍,根據(jù)樂曲簡譜找到相應音調(diào)的頻率存入birthday_freq[]中,再將每個音調(diào)的節(jié)拍數(shù)存入birthday_length[]中,在“HappyBirthday!”樂曲中,一個節(jié)拍的時長為500ms。在主函數(shù)的while(1)循環(huán)中,根據(jù)song_ID的值,使指針變量song_freq、song_length、name指向?qū)⒁シ艠非囊粽{(diào)數(shù)組、節(jié)拍數(shù)組、名稱數(shù)組。

(3)play()函數(shù)中,對定時器0裝入音調(diào)頻率的初始值,再調(diào)用Delay()函數(shù)產(chǎn)生節(jié)拍,本程序中用到了兩個定時器,對T0使用中斷方式處理,而對于T1則使用查詢方式處理,Delay()函數(shù)中,對T1首先賦初值,“while(!TF1);”語句是不斷的查詢T1的溢出標志位,當T1計數(shù)滿溢出時,TF1會由硬件置“1”,所以程序中通過查詢TF1的方法判斷定時時間是否達到。

(4)對于獨立按鍵的處理是通過外中斷來做的,考慮到任何時候只要有按鍵,播放的樂曲就會換向另外一首,如果不使用中斷,則只有當前樂曲播放完之后,如果正好有按鍵,才會進行切換。所以每按一次鍵就會觸發(fā)一次外中斷,在外中斷0服務程序中,改變了song_ID的值,而且置button_flag的值為“1”,在主程序中當查到button_flag的值為“1”時,就會立刻停止當前播放的樂曲,根據(jù)song_freq、song_length的新值來進行播放。

(5)程序中定義的指針變量“unsignedint*song_freq,*song_length;”,“unsignedchar*name;”是指向數(shù)組元素的指針變量,“song_freq”是指向存放正在播放樂曲頻率的數(shù)組元素,“song_length”是指向存放正在播放樂曲音長的數(shù)組元素,“name”是指向存放正在播放樂曲名稱的數(shù)組元素?!皊ong_freq++”含義是指向數(shù)組的下一個元素。2.4.2

LCD12864液晶顯示屏介紹

12864是128×64點陣液晶模塊的點陣數(shù)簡稱,它是一種圖形點陣的液晶屏。LCD12864目前比較流行的有兩種,一種是以KS0108為主控芯片,不帶中文字庫,只能靠打點方式才能顯示漢字,即要借助取字模軟件取出漢字的字模,才能送去顯示漢字。另一種是以ST7920為主控芯片,自帶ASCII碼和中文字庫。這里主要介紹以ST7920為主控芯片的LCD12864液晶顯示屏,其外形如圖2-31所示。圖2-31

LCD12864液晶顯示屏外形

1.主要技術參數(shù)和顯示特性

電源:VDD為3.3V~5V(內(nèi)置升壓電路,無需負壓);

顯示內(nèi)容:128列×64行;

顯示顏色:黃綠;

與MCU接口:8位并行、4位并行或3位串行;

配置0ED背光;

時鐘頻率為:2MHz;

內(nèi)置漢字字庫,提供8192個16×16點陣漢字;

多種軟件功能:光標顯示、畫面移位、自定義字符、睡眠模式等;工作溫度:0°C~55°C;

存儲溫度:-20°C~+60°C。

2.LCD12864模塊引腳說明

LCD12864模塊各引腳的功能如表2-15所示。表2-15

LCD12864

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論