在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)定時器中斷原理

            單片機(jī)定時器中斷原理

            作者: 時間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
            #define _1231_C_

            #include "reg51.h"

            本文引用地址:http://www.biyoush.com/article/201611/321287.htm

            //sbit OE=P2^3;

            unsigned int SystemTime;

            void timer0(void) interrupt 1 using 3 //中斷部分代碼,見下文的釋疑

            {

            TH0 = 0xdb;

            TL0 = 0xff;

            // TF0 = 0;

            SystemTime++;

            }

            void main()

            {

            TMOD &= 0xF0;

            TMOD |= 0x01; //TMOD的值表示定時器工作方式選擇

            TH0 = 0xdb; //寫入初始值,初始值可以決定定時多久

            TL0 = 0xff;

            //根據(jù)下文的木桶比喻的話,如果TH0 = 0x00;TL0 = 0x00;則表示從桶底開始裝水。

            //TH0 = 0xdb;TL0 = 0xff;可以這樣子理解相當(dāng)于木桶里已經(jīng)有部分液鉛在里面,

            //TH0和TL0這個兩個值表示木桶里液鉛的高度,即此時桶里只能從液鉛的高度以上開始裝水,

            //TH0 = 0xff;TL0 = 0xff;即表示桶的最高位置.

            TF0 = 0; //計(jì)數(shù)到時TF0為1,即當(dāng)TH0 = 0xff;TL0 = 0xff;再運(yùn)行一步TF0 = 1;

            TR0 = 1; //開始計(jì)數(shù),從這時起,每運(yùn)行一步TH0和TL0都會增加,直到TH0 = 0xff;TL0 = 0xff;

            //相當(dāng)于開水龍頭,如TR0=0則TH0和TL0不變

            ET0 = 1; //允許定時器0中斷

            EA=1; //開總中斷

            //下面是個死循環(huán),程序里每運(yùn)行一步TH0和TL0都會增加,當(dāng)增加到TH0 = 0xff;TL0 = 0xff;

            //單片機(jī)會從死循環(huán)里退出,去執(zhí)行中斷部分的代碼,即開始運(yùn)行void timer0(void) interrupt 1 using 3{}

            //運(yùn)行完中斷部分的代碼后,接著繼續(xù)執(zhí)行死循環(huán)里的代碼。

            //注意:當(dāng)TH0 = 0xff;TL0 = 0xff;再運(yùn)行,TF0并沒有從0變?yōu)?,個人猜測TF0=1;時觸發(fā)了中斷,并重新被置零。

            //如把ET0 = 1;和EA=1;注釋掉,當(dāng)TH0 = 0xff;TL0 = 0xff;再運(yùn)行,TF0會變?yōu)?,此時不會再執(zhí)行中斷部分代碼。

            while(1)

            {

            if ((SystemTime0)<50) //SystemTime除以100,余數(shù)小于50為真

            {

            …………;

            }

            else

            {

            …………;

            }

            };

            }

            釋疑:void Timer0() interrupt 1 using 1

            Timer0 是函數(shù)名,隨便取的

            interrupt xx using y

            跟在interrupt 后面的xx 值得是中斷號,就是說這個函數(shù)對應(yīng)第幾個中斷端口,一般在51中

            0 外部中斷0

            1 定時器0

            2 外部中斷1

            3 定時器1

            4 串行中斷

            實(shí)際上編譯的時候就是把你這個函數(shù)的入口地址方到這個對應(yīng)中斷的跳轉(zhuǎn)地址

            using y 這個y是說這個中斷函數(shù)使用的那個寄存器組,51里面一般有4組 r0 -- r7寄存器,一共有32個,如果你的終端函數(shù)和別的程序用的不是同一個寄存器組則進(jìn)入中斷的時候就不會將寄存器組壓入堆棧返回時也不會談出來節(jié)省代碼和時間

            初始值算法:定時器是當(dāng)總數(shù)達(dá)到FFFFH后產(chǎn)生中斷吧!那你要讓它計(jì)數(shù)10000,是不是用FFFF(16進(jìn)制)減去10000(十進(jìn)制)的數(shù)當(dāng)計(jì)數(shù)初值?。縏H0=-(10000/256); TL0=-(10000%6)跟FFFF(16進(jìn)制)減去10000(十進(jìn)制)的數(shù)是一樣的。從TH0=-(10000/256); TL0=-(10000%6)開始計(jì)數(shù),計(jì)數(shù)到10000剛好滿。跟用FFFF(16進(jìn)制)減去10000(十進(jìn)制)的數(shù)一樣?。?!寫起來更簡單,不用算?。。?/p>

            看看原碼、補(bǔ)碼就知道。正數(shù)的補(bǔ)碼是對應(yīng)的二進(jìn)制數(shù),符號位為零,負(fù)數(shù)的補(bǔ)碼是它的絕對值對應(yīng)的二進(jìn)制數(shù)按位取反再加一,符號位為一。無符號數(shù)不考慮符號,那么這個結(jié)果就跟用FFFF減去它的絕對值一樣

            我們學(xué)習(xí)了用指令延時閃燈,但是用指令方式閃燈有cpu不能做其他工作的缺點(diǎn)。

            這一課,我們將學(xué)習(xí)如何使用定時器方式使燈閃爍。

            中斷的理解。

            這里將涉及到單片機(jī)中斷的應(yīng)用,在cpu的一步步按照指令運(yùn)行的過程中(主程序),可能會有其它的更緊急的需要做的事情(中斷服務(wù)程序),需要cpu暫時停止當(dāng)前的程序(主程序),做完了(中斷服務(wù)程序)之后,又可以繼續(xù)去運(yùn)行先前的程序(主程序)。就像你正在吃飯,一邊又在給水桶里放水,吃著吃著,水滿了,你就得趕快去把水龍頭關(guān)掉或者換一個空的水桶,再回來吃飯。

            單片機(jī)的定時器就像是一個水桶,你讓它啟動了,也就是水龍頭打開了;開始裝水了;定時在每個機(jī)器周期不斷自動加1,最后溢出了;水桶的水不斷增加,最也就滿出來了;定時器溢出時,你就要去做處理了;水桶的水滿了,你也應(yīng)該處理一下了;處理完后,單片機(jī)又可以回到剛剛開停止的地方繼續(xù)運(yùn)行;水桶處理了,先前你在做什么也可以繼續(xù)去做什么了。

            單片機(jī)的主程序是從0x0000開始運(yùn)行的,單片機(jī)服務(wù)程序從哪里開始運(yùn)行呢?在51里,有多個中斷服務(wù)程序入口,0號入口是外中斷0,地址在0x0003;1號入口是定時器0,在 0x000B;2號入口是外中斷1;地址在0x0013,3號入口是定時器2;地址在0x001B,等等。當(dāng)中斷發(fā)生時,程序就記下當(dāng)前運(yùn)行的位置,跳到對應(yīng)的中斷入口去運(yùn)行中斷服務(wù)程序,運(yùn)行完之后,又跳回到原來的位置繼續(xù)運(yùn)行。

            在C51中,你不用理會中斷服務(wù)程序放在哪里,會怎么跳轉(zhuǎn)。你只要把某個函數(shù)標(biāo)識為幾號中斷服務(wù)函數(shù)就可以了。在發(fā)生了對應(yīng)的中斷時,就會自動的運(yùn)行這個函數(shù)。

            請看一下相關(guān)的51的硬件的書,對定時器工作的寄存器設(shè)置做進(jìn)一步的了解。也可以做完試驗(yàn)再了解,因?yàn)槔讨卸家呀?jīng)為您設(shè)置好了。

            請看程序,主程序里的循環(huán)里是個死循環(huán),什么也沒有做,在實(shí)際應(yīng)用中這里是放的主程序。

            在定時器服務(wù)函數(shù)里,需要重新置入定時器的值,這樣才能保證每次溢出時,都是你指定的時間。這里置入的是0x0006,還需要走 0x10000-0x0006個機(jī)器周期才溢出。換成10進(jìn)制也就是每65530個機(jī)器周期中斷一次。我們仿真的晶振是22118400HZ,每12個時鐘一個機(jī)器周期。65530×12/22118400=0.036秒。也就是差不多28HZ的閃爍頻率。

            因?yàn)?1的定時器最大只有0xffff,溢出的速度很快,無法做出更久的閃爍頻率來,這一課就先觀察一下這個28HZ左右頻率。在下一課我們會用靜態(tài)變量的辦法,做一個長達(dá)1秒鐘的LED閃爍頻率。

            另外,由于51從中斷發(fā)生到進(jìn)入中斷的時間不定,是3至8個機(jī)器周期,我們在進(jìn)入了中斷后才重新置新的定時器初始值,這樣就會存在定時誤差。也就是不是精確定時,如果要精確定時,需要使用定時器自動裝載方式,也就是在定時器溢出的同時,硬件邏輯就自動把定時器初始值裝載進(jìn)去了,而不是在中斷服務(wù)程序里賦初始值,這樣就可以實(shí)現(xiàn)精確定時,誤差只出現(xiàn)晶振的頻率上。這是下一顆的內(nèi)容。

            現(xiàn)在請仔細(xì)研究一下程序,并編譯,進(jìn)入仿真,全速運(yùn)行,觀察運(yùn)行結(jié)果。我們可以看到P10上的LED在快速閃爍。

            順便,也請?jiān)倬毩?xí)一下停止,單步,斷點(diǎn)等等的調(diào)試方法。

            一個特殊的地方,使用DX516在單步時運(yùn)行時,可能無法進(jìn)入到中斷服務(wù)函數(shù)中。這是因?yàn)橹袛嗪瘮?shù)可能在單步處理的瞬間已經(jīng)運(yùn)行過去了。如果要單步調(diào)試中斷服務(wù)函數(shù),請?jiān)谥袛喾?wù)函數(shù)內(nèi)設(shè)置斷點(diǎn),再點(diǎn)全速。稍后就會停止在斷點(diǎn)上,就可以繼續(xù)單步運(yùn)行了。



            評論


            技術(shù)專區(qū)

            關(guān)閉