找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 44299|回復(fù): 43
打印 上一主題 下一主題
收起左側(cè)

第五章 定時(shí)器和數(shù)碼管

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
#
ID:1 發(fā)表于 2013-6-6 07:31 | 只看該作者 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式

通過上節(jié)課的實(shí)驗(yàn),大家會(huì)發(fā)現(xiàn),我們逐漸進(jìn)入比較實(shí)質(zhì)性的學(xué)習(xí)了,需要記住的內(nèi)容也更多了,個(gè)別地方可能會(huì)感覺吃力。但是大家不要擔(dān)心,要有信心。這個(gè)跟小孩學(xué)走路一樣,剛開始走路不太穩(wěn),沒關(guān)系,多走幾步多練練。看視頻的時(shí)候要注意專心,一遍看不懂,思考一下,再回頭看第二遍和第三遍,沒準(zhǔn)一下就明白了。如果三遍還看不明白,那就把不懂的問題放一放,繼續(xù)往下學(xué)兩課再回頭看一次,也可以到QQ群里或單片機(jī)論壇http://www.torrancerestoration.com/bbs/ 里多咨詢一下其他的同學(xué),討論一下,可能就會(huì)茅塞頓開。

1.1 基本數(shù)字邏輯門電路
不管是數(shù)字電路,還是C語言,我們都會(huì)經(jīng)常遇到邏輯運(yùn)算和邏輯電路,在這里我介紹一下,大家先簡單了解一下,知道有這么回事,回頭遇到了,再詳細(xì)研究。
首先,在“邏輯”這個(gè)概念范疇內(nèi),存在真和假這兩個(gè)邏輯值,而將其對(duì)應(yīng)到數(shù)字電路或C語言中,就變成了“非0值”和“0值”這兩個(gè)值,即邏輯上的“假”就是數(shù)字電路或C語言中的“0”這個(gè)值,而邏輯“真”就是其它一切“非0值”。
然后,我們來具體分析一下幾個(gè)主要的邏輯運(yùn)算符。我們假定有2個(gè)字節(jié)變量:A和B,二者進(jìn)行某種邏輯運(yùn)算后的結(jié)果為F。
以下邏輯運(yùn)算符都是按照變量整體值進(jìn)行運(yùn)算的,通常就叫做邏輯運(yùn)算符:
&&:邏輯與,F(xiàn) = A && B,當(dāng)A、B的值都為真(即非0值,下同)時(shí),其運(yùn)算結(jié)果F為真(具體數(shù)值為1,下同);當(dāng)A、B值任意一個(gè)為假(即0,下同)時(shí),結(jié)果F為假(具體數(shù)值為0,下同)。
||:邏輯或,F(xiàn) = A || B,當(dāng)A、B值任意一個(gè)為真時(shí),其運(yùn)算結(jié)果F為真;當(dāng)A、B值都為假時(shí),結(jié)果F為假。
! :邏輯非,F(xiàn) = !A,當(dāng)A值為假時(shí),其運(yùn)算結(jié)果F為真;當(dāng)A值為真時(shí),結(jié)果F為假。
以下邏輯運(yùn)算符都是按照變量內(nèi)的每一個(gè)位來進(jìn)行運(yùn)算的,通常就叫做位運(yùn)算符:
& :按位與,F(xiàn) = A & B,將A、B兩個(gè)字節(jié)中的每一位都進(jìn)行與運(yùn)算,再將得到的每一位結(jié)果組合為總結(jié)果F,例如A = 0b11001100,B = 0b11110000,則結(jié)果F就等于0b11000000。
| :按位或,F(xiàn) = A | B,將A、B兩個(gè)字節(jié)中的每一位都進(jìn)行或運(yùn)算,再將得到的每一位結(jié)果組合為總結(jié)果F,例如A = 0b11001100,B = 0b11110000,則結(jié)果F就等于0b11111100。
~ :按位取反,F(xiàn) = ~A,將A字節(jié)內(nèi)的每一位進(jìn)行非運(yùn)算(就是取反),再將得到的每一位結(jié)果組合為總結(jié)果F,例如,A = 0b11001100,則結(jié)果F就等于0b00110011;這個(gè)運(yùn)算符我們?cè)谇懊娴牧魉疅魧?shí)驗(yàn)里已經(jīng)用過了,現(xiàn)在再回頭看一眼,是不是清楚多了。
^ :按位異或,異或的意思是,如果運(yùn)算雙方的值不同(即相異)則結(jié)果為真,雙方值相同則結(jié)果為假。在C語言里沒有按變量整體值進(jìn)行的異或運(yùn)算,所以我們僅以按位異或?yàn)槔�,F(xiàn) = A ^ B,A = 0b11001100,B = 0b11110000,則結(jié)果F就等于0b00111100。
我們今后要看資料或芯片手冊(cè)的時(shí)候,會(huì)經(jīng)常遇到一些電路符號(hào),表5-1就是數(shù)字電路中的常用符號(hào),知道這些符號(hào)有利于我們理解器件的邏輯結(jié)構(gòu),尤其重點(diǎn)認(rèn)識(shí)以下表中的“國外流行圖形符號(hào)”。在這里我們先簡單看一下,后邊遇到了知道到這里查閱就可以了。
表5-1 數(shù)字邏輯門電路
圖片
1.2 定時(shí)器的學(xué)習(xí)
定時(shí)器是單片機(jī)的重點(diǎn)中的重點(diǎn),但不是難點(diǎn),大家一定要完全理解并且熟練掌握定時(shí)器的應(yīng)用。
1.2.1 定時(shí)器的初步認(rèn)識(shí)
時(shí)鐘周期:時(shí)鐘周期T是時(shí)序中最小的時(shí)間單位具體計(jì)算的方法就是1/時(shí)鐘源,我們KST-51單片機(jī)開發(fā)板上用的晶振是11.0592M,那么對(duì)于我們這個(gè)單片機(jī)系統(tǒng)來說,時(shí)鐘周期=1/11059200秒。
機(jī)器周期:我們的單片機(jī)完成一個(gè)操作的最短時(shí)間。機(jī)器周期主要針對(duì)匯編語言而言,在匯編語言下程序的每一條語句執(zhí)行所使用的時(shí)間都是機(jī)器周期的整數(shù)倍,而且語句占用的時(shí)間是可以計(jì)算出來的,而C語言一條語句的時(shí)間是不可計(jì)算的。51單片機(jī)系列,在其標(biāo)準(zhǔn)架構(gòu)下一個(gè)機(jī)器周期是12個(gè)時(shí)鐘周期,也就是12/11059200秒�,F(xiàn)在有不少增強(qiáng)型的51單片機(jī),其速度都比較塊,有的1個(gè)機(jī)器周期等于4個(gè)時(shí)鐘周期,有的1個(gè)機(jī)器周期就等于1個(gè)時(shí)鐘周期,也就是說大體上其速度可以達(dá)到標(biāo)準(zhǔn)51架構(gòu)的3倍或12倍。因?yàn)槲覀兪侵v標(biāo)準(zhǔn)的51單片機(jī),所以我們后邊的課程如果遇到這個(gè)概念,全部是指12個(gè)時(shí)鐘周期。
這兩個(gè)概念了解即可,下邊就來我們的重頭戲,定時(shí)器和計(jì)數(shù)器。定時(shí)器和計(jì)數(shù)器是單片機(jī)內(nèi)部的同一個(gè)模塊,通過配置SFR(特殊功能寄存器)可以實(shí)現(xiàn)兩種不同的功能,我們大多數(shù)情況下是使用定時(shí)器功能,因此我們的課程也是主要來講定時(shí)器功能,計(jì)數(shù)器功能大家自己了解下即可。
顧名思義,定時(shí)器就是用來進(jìn)行定時(shí)的。定時(shí)器內(nèi)部有一個(gè)寄存器,我們讓它開始計(jì)數(shù)后,這個(gè)寄存器的值每經(jīng)過一個(gè)機(jī)器周期就會(huì)加1一次,因此,我們可以把機(jī)器周期理解為定時(shí)器的計(jì)數(shù)周期。我們的秒表,每經(jīng)過一秒,數(shù)字加1,而這個(gè)定時(shí)器就是每過一個(gè)機(jī)器周期的時(shí)間,也就是12/11059200秒,數(shù)字加1。還有一個(gè)特別注意的地方,就是秒表是加到60后,秒就自動(dòng)變成0了,這種情況在單片機(jī)和計(jì)算機(jī)里我們稱之為溢出。那定時(shí)器加到多少才會(huì)溢出呢?定時(shí)器有幾種模式,假如是16位的定時(shí)器,也就是2個(gè)字節(jié),最大值就是65535,那么加到65535后,再加1就算溢出,如果有其他位數(shù)的話,道理是一樣的,對(duì)于51單片機(jī)來說,溢出后,這個(gè)值會(huì)直接變成0。從某一個(gè)初值,經(jīng)過計(jì)算確定的時(shí)間后溢出,這個(gè)過程就是其定時(shí)的含義。
1.2.2 定時(shí)器的寄存器描述
標(biāo)準(zhǔn)的51里邊只有定時(shí)器0和定時(shí)器1這兩個(gè)定時(shí)器,現(xiàn)在很多單片機(jī)也有多個(gè)定時(shí)器的,在這里我們先講定時(shí)器0和1。那么我前邊提到過,對(duì)于單片機(jī)的每一個(gè)功能模塊,都是由他的SFR,也就是特殊功能寄存器來控制。而和定時(shí)器有關(guān)的特殊功能寄存器,有以下幾個(gè),大家不需要去記憶這些寄存器的名字和作用,你只要大概知道就行,用的時(shí)候,隨時(shí)可以查手冊(cè),找到每個(gè)寄存器的名字和每個(gè)寄存器所起到的作用。
表5-2 定時(shí)值存儲(chǔ)寄存器
名稱
描述
SFR地址
TH0
定時(shí)器0高字節(jié)
8CH
TL0
定時(shí)器0低字節(jié)
8AH
TH1
定時(shí)器1高字節(jié)
8DH
TL1
定時(shí)器1低字節(jié)
8BH
表5-3 TCON--定時(shí)器/計(jì)數(shù)器控制寄存器的位分配(地址:88H)
       可位尋址;復(fù)位值:0x00;復(fù)位源:任何復(fù)位
7
6
5
4
3
2
1
0
符號(hào)
TF1
TR1
TF0
TR0
IE1
IT1
IE0
IT0
表5-4 TCON--定時(shí)器/計(jì)數(shù)器控制寄存器的位描述
符號(hào)
描述
7
TF1
定時(shí)器1溢出標(biāo)志。一旦定時(shí)器1發(fā)生溢出時(shí)硬件置1。清零有兩種方式:軟件清零,或者進(jìn)入定時(shí)器中斷時(shí)硬件清零。
6
TR1
定時(shí)1運(yùn)行控制位。軟件置位/清零來進(jìn)行啟動(dòng)/關(guān)閉定時(shí)器。
5
TF0
定時(shí)器0溢出標(biāo)志。一旦定時(shí)器0發(fā)生溢出時(shí)硬件置1。清零有兩種方式:軟件清零,或者進(jìn)入定時(shí)器中斷時(shí)硬件清零。
4
TR0
定時(shí)0運(yùn)行控制位。軟件置位/清零來進(jìn)行啟動(dòng)/關(guān)閉定時(shí)器。
3
IE1
外部中斷部分,與定時(shí)器無關(guān),暫且不看
2
IT1
1
IE0
0
IT0
    大家注意在表5-4中的描述中,只要寫到硬件置1或者清0的,就是指一旦符合條件,單片機(jī)自動(dòng)完成的動(dòng)作,只要寫軟件置1或者清0的,是指我們用程序去完成這個(gè)動(dòng)作,后邊課程中不再做說明。
    表5-2中的寄存器,是存儲(chǔ)計(jì)數(shù)器的計(jì)數(shù)值的,兩個(gè)字節(jié)的用于定時(shí)器1,兩個(gè)字節(jié)用于定時(shí)器0。
表5-3中有TF1、TR1、TF0、TR0這4位需要我們理解清楚。兩位定時(shí)器1的,兩位定時(shí)器0的,我們只解釋定時(shí)器1的,定時(shí)器0的同理。先看TR1,當(dāng)我們程序中寫TR1 = 1以后,定時(shí)器值就會(huì)每經(jīng)過一個(gè)機(jī)器周期加1,當(dāng)我們程序中寫TR1 = 0以后,定時(shí)器值就會(huì)保持不變化。TF1,這個(gè)是一個(gè)標(biāo)志位,他的作用是告訴我們定時(shí)器溢出了。比如我們的定時(shí)器設(shè)置成16位的定時(shí)器,那么每經(jīng)過一個(gè)機(jī)器周期,TL1加1一次,當(dāng)TL1加到255后,再加1,TL1變成0,TH1會(huì)加1一次,如此一直加到TH1和TL1都是255(即TH1和TL1組成的16位整型數(shù)為65535)以后,再加1一次,那么就會(huì)溢出,TH1和TL1同時(shí)都變?yōu)?,只要一溢出,TF1馬上自動(dòng)變成1,告訴我們定時(shí)器溢出了,僅僅是提供給我們一個(gè)信號(hào),讓我們知道定時(shí)器溢出了,它不會(huì)對(duì)定時(shí)器是否繼續(xù)運(yùn)行產(chǎn)生任何影響。
表5-5 TMOD--定時(shí)器方式控制寄存器的位分配(地址 89H)
       不可位尋址;復(fù)位值:0x00;復(fù)位源:任何復(fù)位
7
6
5
4
3
2
1
0
符號(hào)
GATE
(T1)
C/T
(T1)
M1
(T1)
M0
(T1)
GATE
(T0)
C/T
(T0)
M1
(T0)
M0
(T0)
細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),TCON那個(gè)地方標(biāo)注的是“可位尋址”,TMOD這里標(biāo)注的是“不可位尋址”。這個(gè)地方的意思就是比如TCON有一位TR1,我們可以在程序中直接進(jìn)行TR1 = 1;這樣操作。但是(T1)M1 = 1;這樣的操作就是錯(cuò)誤的。我們要操作就必須一次操作一個(gè)字節(jié),就是必須一次性對(duì)TMOD所有位操作,不能對(duì)其中某一位單獨(dú)進(jìn)行操作。
表5-6 TMOD--定時(shí)器/計(jì)數(shù)器方式控制寄存器的位描述
符號(hào)
描述
T1/T0
在表5-5中,標(biāo)T1的表示控制定時(shí)器1的位,標(biāo)T0的表示控制定時(shí)器0的位。
GATE
該位被置1時(shí)為門控位。僅當(dāng)INTx腳為高并且TRx控制位被置1時(shí)使能定時(shí)器x,定時(shí)器開始計(jì)時(shí),當(dāng)該位被清0時(shí),只要TRx位被置1,定時(shí)器x就使能開始計(jì)時(shí),不受到單片機(jī)引腳INTx外部信號(hào)的干擾,常用來測(cè)量外部信號(hào)脈沖寬度。這是定時(shí)器一個(gè)額外功能,本節(jié)課暫不介紹。
C/T
定時(shí)器或計(jì)數(shù)器選擇位。該位被清零時(shí)用作定時(shí)器功能(內(nèi)部系統(tǒng)時(shí)鐘),被置1用作計(jì)數(shù)器功能。
 
表5-7 TMOD--定時(shí)器方式控制寄存器M1/M0工作模式
M1
M0
工作模式
描述
0
0
0
兼容8048單片機(jī)的13位定時(shí)器,THn的8位和TLn的5位組成一個(gè)13位定時(shí)器
0
1
1
THn和TLn組成一個(gè)16位的定時(shí)器
1
0
2
8位自動(dòng)重裝模式,定時(shí)器溢出后THn重裝到TLn中
1
1
3
禁用定時(shí)器1,定時(shí)器0變成2個(gè)8位定時(shí)器
以上這4種模式的配置,其中模式0是為了兼容老的8048單片機(jī)而設(shè)的,現(xiàn)在的51幾乎不會(huì)用到這種模式,而模式3根據(jù)我的應(yīng)用經(jīng)驗(yàn),他的功能模式2完全可以取代,所以基本上也是不用,那么我們重點(diǎn)就學(xué)習(xí)模式1和模式2。
模式1就是THn和TLn組成了一個(gè)16位的定時(shí)器,取值范圍是0到65535,溢出后,只要不對(duì)THn和TLn重新賦值,則從0開始計(jì)數(shù)。模式2的功能是自動(dòng)裝載,就是TLn溢出后,TFn就直接置1了,并且THn的值直接賦給TLn,然后TLn從新賦值的這個(gè)數(shù)字開始計(jì)數(shù)。這個(gè)功能可以用來產(chǎn)生串口的通信波特率,我們講串口的時(shí)候要用到,本章節(jié)我們重點(diǎn)來學(xué)習(xí)模式1。為了加深大家理解這個(gè)定時(shí)器原理,我們來看一下他的模式1的電路示意圖5-1。
圖片
5-1 定時(shí)器/計(jì)數(shù)器模式1示意圖
我?guī)е蠹襾矸治鲆幌逻@個(gè)示意圖,后邊如果手冊(cè)中遇到,大家也就會(huì)自己研究了。OSC框表示時(shí)鐘頻率,因?yàn)槲覀?個(gè)機(jī)器周期等于12個(gè)時(shí)鐘周期,所以那個(gè)d就等于12。下邊GATA右邊的那個(gè)門是一個(gè)非門電路,再右側(cè)是一個(gè)或門,再往右是一個(gè)與門電路,大家可以對(duì)照一下5-1節(jié)的內(nèi)容。
圖上可以看出來,下邊部分電路是控制了上邊部分,那我們先來看下邊是如何控制的,我們以定時(shí)器0為例。
1、TR0和下邊或門電路的結(jié)果要進(jìn)行與門運(yùn)算,TR0如果是0的話,與運(yùn)算完了肯定是0,所以確定如果要讓定時(shí)器工作,TR0 = 1。
2、與門結(jié)果要想是1,那或門出來的信號(hào)必須也得是1才行。在GATE位為1的情況下,經(jīng)過一個(gè)非門變成0,或門電路結(jié)果要想是1的話,那INT0即P3.2引腳必須是1的情況下,這個(gè)時(shí)候定時(shí)器才會(huì)工作,而INT0引腳是0的情況下,定時(shí)器不工作,這就是GATE位的作用。
3、當(dāng)GATE位為0的時(shí)候,經(jīng)過一個(gè)非門變成1,不管INT0引腳是什么電平,經(jīng)過或門電路后則肯定是1,定時(shí)器就會(huì)工作。
4、要想讓定時(shí)器工作,就是加1,從圖上看有兩種方式,第一種方式是那個(gè)開關(guān)打到上邊的箭頭,就是C/T = 0的時(shí)候,一個(gè)機(jī)器周期TL就會(huì)加1一次,當(dāng)開關(guān)打到下邊的箭頭,即C/T =1的時(shí)候,T0引腳即P3.4引腳來一個(gè)脈沖,TL就加1一次,這也就是計(jì)數(shù)器功能。
INT0引腳是P3.2,INT1引腳是P3.3,T0引腳是P3.4,T1引腳是P3.5,這個(gè)可以從我們KST-51開發(fā)板原理圖上看出來。
1.2.3 定時(shí)器程序應(yīng)用
了解了定時(shí)器相關(guān)的寄存器,那么我們下面就來做一個(gè)定時(shí)器的程序,鞏固一下我們學(xué)到的內(nèi)容。我們這節(jié)課的程序先使用定時(shí)器0,在使用定時(shí)器的時(shí)候,需要以下幾個(gè)步驟:
第一步:設(shè)置特殊功能寄存器TMOD,配置好工作模式;
第二步:設(shè)置計(jì)數(shù)寄存器TH0和TL0的初值;
第三步:設(shè)置TCON,通過打開TR0位來讓定時(shí)器開始計(jì)數(shù)。
第四步:判斷TCON寄存器的TF0位,監(jiān)測(cè)定時(shí)器溢出情況。
寫程序之前,我們要先來學(xué)會(huì)計(jì)算如何用定時(shí)器定時(shí)時(shí)間。我們的晶振是11.0592M,時(shí)鐘周期就是1/11059200,機(jī)器周期就是12/11059200,我們假如要定時(shí)20ms,就是0.02秒,要經(jīng)過x個(gè)機(jī)器周期得到0.02秒,我們來算一下x*12/11059200=0.02,得到x= 18432。那么我們現(xiàn)在16位的定時(shí)器溢出值是65536,我們可以這樣,先給TH0和TL0一個(gè)初值,讓他們經(jīng)過18432個(gè)機(jī)器周期后剛好溢出,溢出后我們可以通過檢測(cè)TF0位得知,就剛好是0.02秒。這個(gè)初值y = 65536 - 18432 = 47104,轉(zhuǎn)成16進(jìn)制就是0xB800,那么就是TH0 = 0xB8,TL0 = 0x00。
那0.02秒我們已經(jīng)定時(shí)出來了,細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),我們?nèi)绻踔抵苯咏o一個(gè)0x0000,一直到65536溢出,定時(shí)器定時(shí)值最大也就是71ms左右,那么我們想定時(shí)更長時(shí)間怎么辦呢?用你小學(xué)學(xué)過的邏輯,倍數(shù)關(guān)系就可以解決此問題。
那好了,我們下面就用程序來實(shí)現(xiàn)以下這個(gè)功能。
#include<reg52.h>               //包含寄存器的庫文件                   
sbit  LED = P0^0;
sbit  ADDR0 = P1^0;
sbit  ADDR1 = P1^1;
sbit  ADDR2 = P1^2;
sbit  ADDR3 = P1^3;
sbit  ENLED = P1^4;
void main()    
{
    unsigned char counter = 0;
    ENLED = 0; ADDR0 = 0; ADDR1 = 1;
    ADDR2 = 1; ADDR3 = 1; LED = 1;  //74HC138和LED燈初始化部分
    TMOD = 0x01;   //設(shè)置定時(shí)器0為模式1
    TH0  = 0xB8;
    TL0  = 0x00;   //定時(shí)值初值
    TR0  = 1;      //打開定時(shí)器0
    while(1)
    {
        if(1 == TF0)            //判斷定時(shí)器0是否溢出
        {
            TF0 = 0;
            TH0 = 0xB8;        //一旦溢出后,重新賦值
            TL0 = 0x00;
            counter++;
            if(50 == counter) //判斷定時(shí)器0溢出是否達(dá)到50次
            {
                 counter = 0;  //counter清0,重新計(jì)數(shù)
                 LED = !LED;   //LED取反操作,0-->1,1-->0
            }                 
        }                       
    }
}   
程序都有注釋,不難理解,這里要解釋一個(gè)地方,就是兩次if判斷,細(xì)心的同學(xué)會(huì)發(fā)現(xiàn),if(1 == TF0)這句,我把1寫前邊,這個(gè)地方我推薦新手按照我這樣來寫,因?yàn)槿绻覀儗慽f(TF0 == 1),作為新手來說,不小心丟掉一個(gè)=號(hào)后,寫成if(TF0 = 1),這樣實(shí)際上在語法上是可以通過的,我們用的Keil4還會(huì)出一個(gè)警告說明一下,Keil以前的版本以及一些其他軟件,可能根本不會(huì)出任何錯(cuò)誤或者警告提示,但是這樣產(chǎn)生的Hex文件下載到單片機(jī)里邊,程序就錯(cuò)了,大家可以改改試試看。
本程序?qū)崿F(xiàn)的結(jié)果是我們板子上最右邊的小燈點(diǎn)亮持續(xù)一秒,熄滅持續(xù)一秒,也就是以0.5HZ的頻率進(jìn)行閃爍。
1.3 數(shù)碼管學(xué)習(xí)
小燈是一種簡單的LED,給我們視覺效果只能通過亮和滅來表達(dá)簡單信息。而這節(jié)課我們要來學(xué)習(xí)一種表達(dá)更加明確的器件,數(shù)碼管。
1.3.1 數(shù)碼管的基本介紹
先給大家提供一張?jiān)韴D看一下,如圖5-1所示。
圖片
5-2 數(shù)碼管原理圖
這是比較常見的數(shù)碼管的原理圖,我們板子上一共有6只數(shù)碼管。前邊有了LED小燈的學(xué)習(xí),數(shù)碼管學(xué)習(xí)就會(huì)輕松的多了。從圖5-1能看出來,數(shù)碼管共有a,b,c,d,e,f,g,dp這8個(gè)段,而實(shí)際上,這8個(gè)段每一段都是一個(gè)LED小燈,所以數(shù)碼管就是由8個(gè)LED小燈所組成的。我們看一下數(shù)碼管內(nèi)部結(jié)構(gòu)圖5-2。
圖片
5-3 數(shù)碼管結(jié)構(gòu)圖
數(shù)碼管分為共陽數(shù)碼管和共陰數(shù)碼管,所謂的共陰數(shù)碼管就是8只LED小燈的陰極是接在一起的,也就是陰極是公共端,由陽極來控制小燈是否亮滅。同理,共陽數(shù)碼管就是陽極是接到一起的,大家可以仔細(xì)研究下圖5-2。細(xì)心的同學(xué)也會(huì)發(fā)現(xiàn),數(shù)碼管上邊有2個(gè)com,實(shí)際上就是我們數(shù)碼管的公共端。為什么有2個(gè),我個(gè)人認(rèn)為,一方面有2個(gè)可以起到對(duì)稱的效果,剛好是10個(gè)引腳,另外一個(gè)方面,公共端通過的電流較大,我們初中就學(xué)過,并聯(lián)電路電流之和等于總電流,用2個(gè)com可以把公共電流平均到2個(gè)引腳上去,降低線路承受的電流。
從我們板子的電路圖上能看出來,我們所用的數(shù)碼管是共陽數(shù)碼管,如圖5-3所示。
圖片
5-4 共陽數(shù)碼管電路
他們的com是接到了正極上,當(dāng)然了,和LED小燈電路類似,也是由74HC138控制了三極管的導(dǎo)通來控制整個(gè)數(shù)碼管的電流,我們先來看DS1這個(gè)數(shù)碼管。原理圖上可以看出來,控制DS1的三極管是Q17,控制Q17的引腳是LEDS0,對(duì)應(yīng)到74HC138上邊就是Y0端的輸出。
圖片
圖5-5 74HC138控制圖
我們現(xiàn)在的目的是讓LEDS0這個(gè)引腳輸出低電平,相信大家現(xiàn)在可以獨(dú)立根據(jù)前邊學(xué)到的內(nèi)容把ADDR0,ADDR1,ADDR2,ADDR3,ENLED這4個(gè)輸入狀態(tài)寫出來,現(xiàn)在大家不要偷懶,都去根據(jù)138的手冊(cè)去寫一下,不需要你記住這些結(jié)論,但是遇到就寫一次,鍛煉過幾次后,遇到同類芯片自己就知道如何去解決問題了。
數(shù)碼管通常是用來顯示數(shù)字的,我們板子上的6個(gè)數(shù)碼管,習(xí)慣上我們稱之為6位,那控制位選擇的就是74HC138了。而數(shù)碼管內(nèi)部的8個(gè)LED小燈我們稱之為數(shù)碼管的段,那么數(shù)碼管的段選擇(即該段的亮滅)是通過P0口控制,經(jīng)過74HC245驅(qū)動(dòng)。
1.3.2 數(shù)碼管的真值表
數(shù)碼管的8個(gè)段,我們直接當(dāng)成8個(gè)LED小燈來控制,那就是a、b、c、d、e、f、g、dp一共8個(gè)LED小燈。我們通過圖5-1可以輕而易舉的看出來,如果我們點(diǎn)亮b和c這兩個(gè)LED小燈,也就是數(shù)碼管的b段和c段,其他的所有的段都熄滅的話,就可以讓數(shù)碼管DS1顯示一個(gè)數(shù)字1,那么這個(gè)時(shí)候?qū)嶋H上P0的值的二進(jìn)制就是0b11111001,十六進(jìn)制就是0xF9。也有可以自動(dòng)生成數(shù)碼管段位碼的軟件可以從http://www.torrancerestoration.com/mcudown/ 下載文件名是"數(shù)碼管段位設(shè)碼程序.rar",那么我們寫一個(gè)程序進(jìn)去,看看讓數(shù)碼管顯示一下看看。
    #include<reg52.h>               //包含寄存器的庫文件                   
    sbit  ADDR0 = P1^0;
    sbit  ADDR1 = P1^1;
    sbit  ADDR2 = P1^2;
    sbit  ADDR3 = P1^3;
    sbit  ENLED = P1^4;
    
    void  main()
    {
        unsigned char j = 0;
        unsigned int  i = 0;
        
        ENLED = 0;
        ADDR0 = 0;
        ADDR1 = 0;
         ADDR2 = 0;
        ADDR3 = 1;           //74HC138開啟三極管Q17           
        while(1)             //程序死循環(huán)  
        {
             P0 = 0xF9;      //打開數(shù)碼管b和c段   
        }
}
大家把這個(gè)程序編譯一下,下載到單片機(jī)里會(huì)發(fā)現(xiàn),最右側(cè)的數(shù)碼管成功顯示1這個(gè)數(shù)字。
同樣的方法,我們可以把其他的數(shù)字都成功的在數(shù)碼管上顯示出來,而數(shù)碼管顯示的數(shù)字對(duì)應(yīng)給P0的賦值,我們叫做數(shù)碼管的真值表。我們來列一下我們這個(gè)電路圖的數(shù)碼管真值表,注意,這個(gè)真值表里顯示的數(shù)字都不帶小數(shù)點(diǎn)。
表5-1 數(shù)碼管真值表
數(shù)字
0
1
2
3
4
5
6
7
真值表
0xC0
0xF9
0xA4
0xB0
0x99
0x92
0x82
0xF8
數(shù)字
8
9
A
B
C
D
E
F
真值表
0x80
0x90
0x88
0x83
0xC6
0xA1
0x86
0x8E
大家可以把上邊那個(gè)數(shù)碼管顯示1的那個(gè)程序中的P0的賦值隨便修改成我們表5-1中的真值表里的數(shù)字試試看,把數(shù)碼管顯示的數(shù)字顯示出來。
1.3.3 數(shù)碼管的靜態(tài)顯示
從第三課我們學(xué)習(xí)74HC138以后,我們了解到74HC138同時(shí)一次只能讓一個(gè)輸出口為低電平,也就是在一個(gè)時(shí)刻內(nèi),我們只能讓一個(gè)數(shù)碼管顯示,始終選通數(shù)碼管并且可以根據(jù)我們的P0總線的信號(hào)來改變這個(gè)數(shù)碼管的值,我們可以理解為數(shù)碼管的靜態(tài)顯示。
數(shù)碼管靜態(tài)顯示是對(duì)應(yīng)動(dòng)態(tài)顯示而言的,靜態(tài)顯示對(duì)于一兩個(gè)數(shù)碼管還行,多個(gè)數(shù)碼管,靜態(tài)顯示實(shí)現(xiàn)的意義就沒有了。這節(jié)課我們先用一個(gè)數(shù)碼管的靜態(tài)顯示來實(shí)現(xiàn)一個(gè)簡單的秒表,為下節(jié)課的動(dòng)態(tài)顯示打下基礎(chǔ)。
先來介紹一個(gè)51單片機(jī)的關(guān)鍵字code。我們前邊課程定義變量的時(shí)候,一般用到unsigned char或者unsigned int這兩個(gè)關(guān)鍵字,這樣定義的變量都是放在我們的單片機(jī)的RAM中,我們?cè)诔绦蛑锌梢噪S意去改變這個(gè)變量的值。但是還有一種常數(shù),我們?cè)诔绦蛑幸褂�,但是卻不進(jìn)行對(duì)這個(gè)值的改變,這種值我們可以加一個(gè)code關(guān)鍵字修飾一下,修飾完畢后,這個(gè)值就會(huì)存儲(chǔ)到我們的程序空間flash中,這樣可以大大節(jié)省我們單片機(jī)的RAM的使用量,畢竟我們的RAM空間比較小,而程序空間是很大的。比如我們現(xiàn)在要使用的數(shù)碼管真值表,我們來看一下我們下邊的這個(gè)程序。
#include<reg52.h>               //包含寄存器的庫文件                   
sbit  LED = P0^0;
sbit  ADDR0 = P1^0;
sbit  ADDR1 = P1^1;
sbit  ADDR2 = P1^2;
sbit  ADDR3 = P1^3;
sbit  ENLED = P1^4;
unsigned char code LedChar[] = {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8e
};                  //用數(shù)組來存儲(chǔ)數(shù)碼管真值表,下一課詳細(xì)介紹數(shù)組
void main()
{
    unsigned char counter = 0;
    unsigned char j = 0;
    ENLED = 0; ADDR0 = 0; ADDR1 = 0;
     ADDR2 = 0; ADDR3 = 1; P0 = 0XFF;  //74HC138和P0初始化部分
     TMOD = 0x01;                    //設(shè)置定時(shí)器0為模式1
     TH0  = 0xB8;
    TL0  = 0x00;                   //定時(shí)值初值
     TR0  = 1;                      //打開定時(shí)器0
    while(1)
    {
        if(1 == TF0)                 //判斷定時(shí)器0是否溢出
        {
            TF0 = 0;
            TH0 = 0xB8;              //溢出后,重新賦值
            TL0 = 0x00;
            counter++;
            if(50 == counter)      //判斷定時(shí)器0溢出是否達(dá)到50次
            {
                counter = 0;        //counter清0,重新計(jì)數(shù)
                P0 = LedChar[j++]; //把數(shù)組里的對(duì)應(yīng)值送給P0
                if(16 == j)         //當(dāng)顯示到F后,歸0重新開始
                {
                     j = 0;
                }
             }
         }
    }
}
1.4 作業(yè)
1、熟練掌握單片機(jī)定時(shí)器的原理和應(yīng)用方法。
2、通過研究定時(shí)器模式1的示意圖,自己打開STC89C52RC數(shù)據(jù)手冊(cè)的定時(shí)器部分,獨(dú)立研究模式0、模式2和模式3的示意圖,鍛煉一下研究示意圖的能力。
3、使用定時(shí)器來做流水燈的左右移動(dòng)以及花樣變化的跑馬燈。
4、了解數(shù)碼管的原理,掌握數(shù)碼管的真值表的計(jì)算方法。
5、編程實(shí)現(xiàn)數(shù)碼管靜態(tài)顯示秒表的倒計(jì)時(shí)。
上一課:第四章 C語言基礎(chǔ)以及流水燈的實(shí)現(xiàn)
下一課:第六章 中斷的學(xué)習(xí)

評(píng)分

參與人數(shù) 4黑幣 +15 收起 理由
莫子棟 + 8 很給力!
zycwswws + 1 贊一個(gè)!
俗人 + 1 贊一個(gè)!
hk18774830405 + 5 厲害

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏15 分享淘帖 頂4 踩
回復(fù)

使用道具 舉報(bào)

43#
ID:985401 發(fā)表于 2021-12-30 21:55 | 只看該作者
今天繼續(xù)來上課
回復(fù)

使用道具 舉報(bào)

42#
ID:815563 發(fā)表于 2020-10-28 16:22 | 只看該作者
電路知識(shí)是學(xué)好單片機(jī)的基底,一定要扎實(shí)。
回復(fù)

使用道具 舉報(bào)

41#
ID:421770 發(fā)表于 2018-11-21 10:35 | 只看該作者
點(diǎn)亮數(shù)碼管b,c段,P0應(yīng)該是 1001 1111才對(duì)啊,為什么P0是 1111 1001呢?
我的理解是:a→P0.0,  b→P0.1,c→P0.2, .......g→P0.6, dp→P0.7
所以點(diǎn)亮b,c:       1001 1111
回復(fù)

使用道具 舉報(bào)

40#
ID:421770 發(fā)表于 2018-11-21 10:25 | 只看該作者
languang 發(fā)表于 2015-12-12 16:02
**** 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽 ****

我還是沒明白為什么要反過來,我的理解應(yīng)該也是1001 1111才對(duì)啊
回復(fù)

使用道具 舉報(bào)

39#
ID:381830 發(fā)表于 2018-8-15 12:15 | 只看該作者
為什么要定義j和i為0?
回復(fù)

使用道具 舉報(bào)

38#
ID:229981 發(fā)表于 2018-8-14 14:41 | 只看該作者
歐陽云天 發(fā)表于 2018-5-10 21:41
弱弱的問一下,邏輯或的那兩豎怎么打出來

|||丨丨丨丨丨丨
|丨丨丨丨||丨|||丨|||
好吧,告訴你吧,前邊的是\n的\鍵加shift,后邊的是(gun)或者(shu)
回復(fù)

使用道具 舉報(bào)

37#
ID:93625 發(fā)表于 2018-6-28 09:35 | 只看該作者
今天繼續(xù)來上課
回復(fù)

使用道具 舉報(bào)

36#
ID:1 發(fā)表于 2018-5-10 23:16 | 只看該作者
歐陽云天 發(fā)表于 2018-5-10 21:41
弱弱的問一下,邏輯或的那兩豎怎么打出來

回車鍵的左邊
回復(fù)

使用道具 舉報(bào)

35#
ID:320097 發(fā)表于 2018-5-10 21:41 | 只看該作者
弱弱的問一下,邏輯或的那兩豎怎么打出來
回復(fù)

使用道具 舉報(bào)

34#
ID:254774 發(fā)表于 2018-3-16 17:34 | 只看該作者
講解的非常細(xì)致
回復(fù)

使用道具 舉報(bào)

33#
ID:280978 發(fā)表于 2018-2-5 18:00 | 只看該作者
wzg1103 發(fā)表于 2017-11-23 11:15
為什么要加這句話呢?
  if(TF0==1)            //判斷定時(shí)器0是否溢出
如果TF0=0,那不是一直在空跑嗎? ...

TF0==1是判斷是否溢出,和中斷有關(guān)。不存在空跑
回復(fù)

使用道具 舉報(bào)

32#
ID:280978 發(fā)表于 2018-2-5 17:58 | 只看該作者
aojieage 發(fā)表于 2018-1-10 14:40
if(1 == TF0)            //判斷定時(shí)器0是否溢出
        {
            TF0 = 0;

只要TR0=1,就會(huì)一直跑。TF0是溢出標(biāo)志位
回復(fù)

使用道具 舉報(bào)

31#
ID:275418 發(fā)表于 2018-1-12 23:29 | 只看該作者
去年暑假自學(xué)的單片機(jī),就像老師說的,到了第二個(gè)階段,好高騖遠(yuǎn),今年寒假再學(xué)的時(shí)候,發(fā)現(xiàn)之前學(xué)的真的就是一觸就破一點(diǎn)都不扎實(shí)。
回復(fù)

使用道具 舉報(bào)

30#
ID:275418 發(fā)表于 2018-1-12 23:29 | 只看該作者
去年暑假自學(xué)的單片機(jī),就像老師說的,到了第二個(gè)階段,好高騖遠(yuǎn),今年寒假再學(xué)的時(shí)候,發(fā)現(xiàn)之前學(xué)的真的就是一觸就破一點(diǎn)都不扎實(shí)。
回復(fù)

使用道具 舉報(bào)

29#
ID:85073 發(fā)表于 2018-1-10 14:40 | 只看該作者
if(1 == TF0)            //判斷定時(shí)器0是否溢出
        {
            TF0 = 0;
想請(qǐng)問樓主一個(gè)問題,當(dāng)程序執(zhí)行到這里時(shí),定時(shí)器是否仍在繼續(xù)工作?還是在下兩條語句裝了初值后才開始工作,雖然這幾句語句只是幾個(gè)微秒,但如果用這個(gè)程序制作一個(gè)電子表,誤差還是比較大吧?
回復(fù)

使用道具 舉報(bào)

28#
ID:126826 發(fā)表于 2017-11-23 11:15 | 只看該作者
為什么要加這句話呢?
  if(TF0==1)            //判斷定時(shí)器0是否溢出
如果TF0=0,那不是一直在空跑嗎?難道TF0的初始值正好是1?
回復(fù)

使用道具 舉報(bào)

27#
ID:155764 發(fā)表于 2017-10-22 22:48 | 只看該作者
絕世好貼!
回復(fù)

使用道具 舉報(bào)

26#
ID:234590 發(fā)表于 2017-9-21 10:52 | 只看該作者
贊一個(gè)   學(xué)習(xí)下贊一個(gè)  一直在學(xué)習(xí)�。�!
回復(fù)

使用道具 舉報(bào)

25#
ID:230395 發(fā)表于 2017-9-1 14:01 | 只看該作者
學(xué)到很多,對(duì)于初學(xué)者很用幫助
回復(fù)

使用道具 舉報(bào)

24#
ID:228733 發(fā)表于 2017-8-24 09:01 | 只看該作者
看了三遍,很好,學(xué)習(xí)了,謝謝老師
回復(fù)

使用道具 舉報(bào)

23#
ID:220342 發(fā)表于 2017-8-8 08:23 | 只看該作者
     TR0  = 1;                      //打開定時(shí)器0

打開定時(shí)器0后,最好再加以下一行
EA=1;   //中斷使能
回復(fù)

使用道具 舉報(bào)

22#
ID:51268 發(fā)表于 2017-3-17 22:47 | 只看該作者
贊一個(gè)   學(xué)習(xí)下贊一個(gè)   學(xué)習(xí)下贊一個(gè)   學(xué)習(xí)下
回復(fù)

使用道具 舉報(bào)

21#
ID:151661 發(fā)表于 2016-12-27 20:54 來自觸屏版 | 只看該作者
云里霧里,先往下看。
回復(fù)

使用道具 舉報(bào)

20#
ID:143842 發(fā)表于 2016-11-2 19:18 來自觸屏版 | 只看該作者
linxue1988925 發(fā)表于 2014-2-13 09:38
**** 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽 ****

定時(shí)器計(jì)滿溢出時(shí),就是計(jì)到65536時(shí)TF置一,發(fā)出中斷請(qǐng)求
回復(fù)

使用道具 舉報(bào)

19#
ID:141262 發(fā)表于 2016-10-8 13:14 | 只看該作者
說明的很詳細(xì)
回復(fù)

使用道具 舉報(bào)

18#
ID:117939 發(fā)表于 2016-6-5 01:03 | 只看該作者
贊一個(gè)!
回復(fù)

使用道具 舉報(bào)

17#
ID:85630 發(fā)表于 2016-1-28 11:10 | 只看該作者
去年暑假自學(xué)的單片機(jī),就像老師說的,到了第二個(gè)階段,好高騖遠(yuǎn),今年寒假再學(xué)的時(shí)候,發(fā)現(xiàn)之前學(xué)的真的就是一觸就破一點(diǎn)都不扎實(shí)。
回復(fù)

使用道具 舉報(bào)

16#
ID:99358 發(fā)表于 2015-12-12 16:02 來自觸屏版 | 只看該作者
languang 發(fā)表于 2015-12-11 21:36
老師,bc段接的不是p0口的第二位第三位DB1.DB2嗎,那不是0x9F嗎。為啥是0xF9呀?謝謝

想明白了,0b1001  1111,其實(shí)是1111對(duì)應(yīng)a b c ,d所以應(yīng)該反過來
回復(fù)

使用道具 舉報(bào)

15#
ID:99358 發(fā)表于 2015-12-11 21:36 來自觸屏版 | 只看該作者
老師,bc段接的不是p0口的第二位第三位DB1.DB2嗎,那不是0x9F嗎。為啥是0xF9呀?謝謝
回復(fù)

使用道具 舉報(bào)

14#
ID:99358 發(fā)表于 2015-12-11 21:30 來自觸屏版 | 只看該作者
bc段,二進(jìn)制不是應(yīng)該是10011111嗎,為什么會(huì)是11111001啊
回復(fù)

使用道具 舉報(bào)

13#
ID:74225 發(fā)表于 2015-3-9 22:28 | 只看該作者
lcd_pos(78);                                 lcd_wdat(speed/10+48);                                 lcd_pos(79);                                 lcd_wdat(speed%10+48);
回復(fù)

使用道具 舉報(bào)

12#
ID:73308 發(fā)表于 2015-2-5 20:28 | 只看該作者
yingtn 發(fā)表于 2014-9-19 14:56
數(shù)字8與字母B真值表為什么不同?

是b不是B
回復(fù)

使用道具 舉報(bào)

11#
ID:69598 發(fā)表于 2014-11-28 22:44 | 只看該作者
很贊!
回復(fù)

使用道具 舉報(bào)

10#
ID:66004 發(fā)表于 2014-9-19 14:56 | 只看該作者
數(shù)字8與字母B真值表為什么不同?
回復(fù)

使用道具 舉報(bào)

9#
ID:66128 發(fā)表于 2014-9-13 18:32 來自觸屏版 | 只看該作者
講的很透切
回復(fù)

使用道具 舉報(bào)

8#
ID:66004 發(fā)表于 2014-9-12 17:22 | 只看該作者
定時(shí)器的程序順序還是沒弄懂
回復(fù)

使用道具 舉報(bào)

7#
ID:60132 發(fā)表于 2014-3-29 15:03 | 只看該作者
請(qǐng)問視頻在哪里看?
回復(fù)

使用道具 舉報(bào)

6#
ID:59092 發(fā)表于 2014-2-13 09:38 | 只看該作者
TF0是從哪里由0變?yōu)?的啊
回復(fù)

使用道具 舉報(bào)

5#
ID:58922 發(fā)表于 2014-1-24 21:15 | 只看該作者
圖片顯示不了
回復(fù)

使用道具 舉報(bào)

地板
ID:56266 發(fā)表于 2013-10-25 17:04 | 只看該作者
求圖片
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表