這是我總結(jié)的51單片機(jī)的中斷定時(shí)器原理,之后會(huì)附上附件。第一次發(fā)帖,不足之處請(qǐng)多多包含!
我總結(jié)的文稿畫(huà)面很花,所以給上個(gè)參考,各位不習(xí)慣的話,請(qǐng)酌情選擇。
定時(shí)器.jpg (25.83 KB, 下載次數(shù): 347)
下載附件
2017-12-26 22:53 上傳
參考.jpg (75.2 KB, 下載次數(shù): 235)
下載附件
2017-12-26 23:12 上傳
目錄 一、原理: 1、對(duì)中斷和定時(shí)器進(jìn)行初始化: ①定時(shí)器/計(jì)數(shù)器工作方式寄存器 ②設(shè)定初值 ③開(kāi)啟中斷和定時(shí)器 2、設(shè)置中斷服務(wù)程序: 3、主函數(shù): 二、各個(gè)定時(shí)器和工作方式: 方式0: 方式2: 方式3: 借鑒:郭天祥《新概念51單片機(jī)C語(yǔ)言教程》 一、原理:51單片機(jī),擁有兩個(gè)定時(shí)器,用來(lái)中斷計(jì)數(shù),分別是T0和T1。而52單片機(jī)和51單片機(jī)的定時(shí)器是一樣的,只是52比51多了一個(gè)定時(shí)器/計(jì)數(shù)器T2,它們的設(shè)置都大同小異,下面我來(lái)總結(jié)各個(gè)定時(shí)器的用法。 定時(shí)器T0與T1不同之處在于它們的工作方式3不同,方式0、1、2相同。 | | | | | 方式0,13位定時(shí)器/計(jì)數(shù)器 | | | 方式1,16位定時(shí)器/計(jì)數(shù)器 | | | 方式2,8位自動(dòng)重裝的8位定時(shí)器/計(jì)數(shù)器 | | | 方式3,僅適用于T0,分成兩個(gè)8位計(jì)數(shù)器, 當(dāng)設(shè)置成T1時(shí)停止計(jì)數(shù) |
首先我們看要使用定時(shí)器T0應(yīng)該設(shè)置的東西: 1、對(duì)中斷寄存器和定時(shí)器進(jìn)行初始化:初始化函數(shù)里的內(nèi)容也可以寫(xiě)在頭文件里,但是為了美觀和好查閱,就把它單獨(dú)寫(xiě)出來(lái),后面在頭文件里直接調(diào)用就行。那么應(yīng)該要進(jìn)行初始化的設(shè)置: ①設(shè)置定時(shí)器的工作方式單片機(jī)內(nèi),有其中一個(gè)特殊寄存器叫TMOD,這是用來(lái)設(shè)置定時(shí)器工作方式的寄存器,通過(guò)軟件,將其寄存器內(nèi)的D0~D7位置0或1,從而達(dá)成對(duì)定時(shí)器的操作。 寄存器TMOD | | | | | | | | | | | | | | C/  | | | | C/  | | |
如表格,這是定時(shí)器的工作方式寄存器TMOD,要更改定時(shí)器的工作方式,我們只用到M1、M2所以其他位一般置0,又因?yàn)槲覀兪褂玫氖荰0的定時(shí)器,所以就有:
控制M1、M0將它們置1或0,即可達(dá)成操作控制方式的目的,然后轉(zhuǎn)換成16進(jìn)制即方便查閱。 同理,使用定時(shí)器1時(shí)也是這么設(shè)置。注意,有時(shí)候也有使用兩個(gè)定時(shí)器T0、T1的時(shí)候,那么就是0001 0001兩個(gè)都是工作方式1。請(qǐng)大家舉一反三。 ②設(shè)定初值先說(shuō)說(shuō)總值: 以方式1為例(之后會(huì)介紹其他方式): 方式1為16位的定時(shí)器/計(jì)數(shù)器,對(duì)定時(shí)器T0來(lái)說(shuō)是分成兩個(gè)寄存器(可以形象地比作容器吧,網(wǎng)上有比我更形象的比喻,我就不多寫(xiě)了,請(qǐng)自行查閱):TH0為高八位,TL0為低八位,組成了16位的定時(shí)器,當(dāng)?shù)臀籘L0計(jì)滿就向高位TH0移一個(gè)數(shù),然后清零。 以12Mhz的晶振來(lái)說(shuō),機(jī)器周期是1us,計(jì)滿TH0、TL0就需要216-1個(gè)數(shù),再來(lái)一個(gè)數(shù)就“溢出”產(chǎn)生中斷,一次溢出也就是65536us,約等于65.5ms,如果要定時(shí)50ms的話就要給他們裝一個(gè)預(yù)裝值(初值),總值-需要值=預(yù)裝值, 也就是65536-50000=15536,預(yù)裝后,定時(shí)器從預(yù)裝值開(kāi)始加值,定時(shí)器溢出中斷后,會(huì)重新從預(yù)裝值開(kāi)始加值加到50ms就再產(chǎn)生中斷,從而達(dá)到了定時(shí)的目的。如果要定時(shí)1s就可以讓定時(shí)器中斷1000ms/50ms=20次。 另外一點(diǎn),TH0和TL0中應(yīng)該裝入的總數(shù)是15536,然后把15536對(duì)256求模:15536/256=60裝入TH0中,把15536對(duì)256求余:15536%256=176裝入TL0中,因?yàn)檫@是兩個(gè)八位28*28的容器。 所以就有了 TH0=(65535-50000)/256 TL0=(65535-50000)%256 ③開(kāi)啟中斷和定時(shí)器關(guān)于中斷,需要用到中斷允許寄存器: IE
定時(shí)器中斷需要的是: 總中斷EA:用來(lái)開(kāi)啟全局中斷。 ET0、1、2:各個(gè)定時(shí)器中斷位。 使用中斷位只用將其置1就行,例如EA=1;ET0=1; 打開(kāi)了中斷開(kāi)關(guān)只是完成了一半,還需要定時(shí)器控制寄存器: TCON
使用方法也是和中斷寄存器一樣, 定時(shí)器0運(yùn)行控制位TR0:用來(lái)開(kāi)啟定時(shí)器0. 把TR0置1,TR0=1;就開(kāi)啟了定時(shí)器。 2、設(shè)置中斷服務(wù)程序:中斷服務(wù)程序:就是當(dāng)計(jì)滿TH0、TL0時(shí)溢出申請(qǐng)中斷,然后單片機(jī)允許中斷時(shí),所要發(fā)生的事情。允許后就自動(dòng)跳轉(zhuǎn)到中斷服務(wù)程序,并執(zhí)行。 在服務(wù)程序中,如果不裝入初值,那定時(shí)器中斷服務(wù)完成后,就會(huì)從0開(kāi)始重新計(jì)時(shí),所以要在中斷程序中重新計(jì)算并裝入初值。 然后給一個(gè)變量(變量的意義為中斷次數(shù)),變量+1,當(dāng)中斷次數(shù)達(dá)到20次的時(shí)候(50ms*20次=1000ms=1s),次數(shù)清零,并且讓產(chǎn)生指令(例如讓二極管亮呀,讓I/O口發(fā)生什么事呀)。 3、主函數(shù):由于有了初始化函數(shù),所以直接調(diào)用即可(不然主函數(shù)很混亂)。 While(1);這段是為了等待函數(shù)發(fā)生,挺含糊的。 另外:一般中斷服務(wù)程序中不要寫(xiě)過(guò)多的處理語(yǔ)句,否則程序會(huì)來(lái)不及執(zhí)行代碼,下一次中斷又來(lái)襲,結(jié)果程序久而久之就亂套了。 所以while處可以改成:把if處理語(yǔ)句寫(xiě)到while處。 附上完整程序: 二、各個(gè)定時(shí)器和工作方式:先來(lái)看看工作方式: | 方式0,13位定時(shí)器/計(jì)數(shù)器 | 方式1,16位定時(shí)器/計(jì)數(shù)器 | 方式2,8位自動(dòng)重裝的8位定時(shí)器/計(jì)數(shù)器 | 方式3,僅適用于T0,分成兩個(gè)8位計(jì)數(shù)器, 當(dāng)設(shè)置成T1時(shí)停止計(jì)數(shù) |
工作方式有四種:0、1、2、3。我們之前已經(jīng)學(xué)習(xí)了方式1的工作方式,那么接下來(lái)就先來(lái)看看其他的工作方式: 方式0:方式0,的用法和方式1的用法一樣,但是值得注意的是: 方式0是13位的定時(shí)器,它的低位TL0是五位的,所以它的總值是28*25=8192。它能裝的值也不能那么多了,于是就裝入5ms: TH0(8192-5000)/32; TL0(8192-5000)%32; 32是5位寄存器的容量。 所以要中斷200次才能達(dá)到1s。 這個(gè)方式0可以用來(lái)做短時(shí)間中斷。 方式2:方式0和方式1,當(dāng)計(jì)數(shù)溢出后,計(jì)數(shù)器變?yōu)?,所以要反復(fù)重新裝填初值,這會(huì)影響定時(shí)精度。但是方式2可以解決這個(gè)問(wèn)題。 如圖,其中低位TL0是8位定時(shí)器,而TH0是常數(shù)緩沖器,當(dāng)?shù)臀籘L0溢出時(shí),在溢出標(biāo)志位TF0置1的同時(shí),自動(dòng)將高位TH0的常數(shù)重新裝入TL0中,讓TL0從初值開(kāi)始重新計(jì)數(shù),這樣就不用人為軟件重新裝入初值帶來(lái)的誤差,從而提高精度。 由于兩個(gè)是分開(kāi)的,所以計(jì)算初值可以不用求余取模: TL0=總值-要計(jì)數(shù)的個(gè)數(shù); TH0=總值-要計(jì)數(shù)的個(gè)數(shù);
以11.0592MHz為晶振,那么機(jī)械周期為12x(1/11059200)≈1.085us,以計(jì)時(shí)1s為例,當(dāng)要計(jì)250個(gè)數(shù)時(shí)耗時(shí)1.0851x250=271.275us,再來(lái)算計(jì)時(shí)1s要用多少次,即1000000/271.275≈3686次。 那么就是:
TL0=256-250=6; TH0=256=250=6; 由于方式2是自動(dòng)裝填,已經(jīng)不用人為裝填了,所以: 中斷服務(wù)程序中只有一句num++ 整個(gè)過(guò)程就是:
方式3:接下來(lái)介紹方式3,方式3不同于其他三個(gè)方式,它只能用于T0,也就是定時(shí)器0,和方式2差不多,也是把TL0、TH0分成兩個(gè)獨(dú)立的寄存器,但是TH0也參與計(jì)數(shù),也就是兩個(gè)獨(dú)立的8位定時(shí)器/計(jì)數(shù)器。 普通的使用一樣,TL0計(jì)數(shù)溢出后置位TF0,并申請(qǐng)中斷,之后重裝。但是由于TL0占用了TR0和TF0,所以TH0只能占用定時(shí)器 T1的TR1和TF1。所以定時(shí)器T1一定不要用在有中斷的場(chǎng)合,當(dāng)然,T1同樣可以正常工作在方式0、1、2下。通常這種情況,T1都被用來(lái)當(dāng)做串行口的波特率發(fā)生器。 首先把T0、T1的中斷位和控制位打開(kāi): 然后分別給低位TL0和高位TH0設(shè)置中斷服務(wù)程序: 可以注意到interrupt后面的數(shù)值,這個(gè)是編譯器識(shí)別不同中斷的唯一符號(hào): 52單片機(jī)的中斷級(jí)別
然后到主函數(shù): 調(diào)用init(); 可以看到if語(yǔ)句里面的符號(hào)是>=,為什么呢?因?yàn)楫?dāng)if語(yǔ)句的值到了時(shí),主程序停止下來(lái)判斷num1==3686是否為真,當(dāng)它還在判斷的時(shí)候,num2是還在走的,于是當(dāng)主程序判斷好num1的時(shí)候再去判斷num2,為時(shí)已晚,num2這時(shí)可能已經(jīng)是1844或者1845或者更高的數(shù)了,所以要變成>=。
完整的Word格式文檔51黑下載地址:
51定時(shí)器.docx
(148.84 KB, 下載次數(shù): 669)
2017-12-26 23:14 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|