新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于單片機(jī)的計(jì)時(shí)器與中斷系統(tǒng)

        關(guān)于單片機(jī)的計(jì)時(shí)器與中斷系統(tǒng)

        作者: 時(shí)間:2016-11-23 來源:網(wǎng)絡(luò) 收藏
        關(guān)于嵌入式,我就自己的XXX長(zhǎng)話短說一下,說來話就長(zhǎng)了,學(xué)過Java、JavaWebandsoon,也做過一些東西,說實(shí)話成就感還是蠻大的,但是,學(xué)過之后卻總是感覺這些東西都太淺顯了,用另一總話說來,就是感覺學(xué)這些東西,站在巨人的肩膀上,卻看不到巨人。什么東西都是封裝好的,知道怎么用就行了,說實(shí)話,確實(shí),學(xué)這些東西壓力很小,但是總感覺不是真本事。所以生產(chǎn)實(shí)習(xí)的時(shí)候自己報(bào)的是Java,但是老是跑到嵌入式的去聽課,之前也沒聽過嵌入式的課,所以是云里霧里。Java的課也沒聽過幾節(jié),最后做東西的時(shí)候根本不知道老師叫做個(gè)什么東西。對(duì)于Java的圖形化編程我還是比較討厭的,沒什么技術(shù)含量還麻煩的要死,到最后XXX說讓我?guī)蛶兔Γf實(shí)話我是真的不會(huì)。生產(chǎn)實(shí)習(xí)的結(jié)果就是最后兩頭都沒撈著好(嵌入式寫了一些驅(qū)動(dòng),但是他們說跟他們用的接口不一樣,最后發(fā)現(xiàn)老師給的有范例,直接按照上面改就行了,搞的我跟傻X一樣,Java直接寫都不想寫,真不知道那段能兩個(gè)星期不洗澡的日子是怎么熬過來的)。我自己感覺最后的大體方向就是:底層開發(fā),包括操作系統(tǒng)什么的這一系列開發(fā),當(dāng)然,扎實(shí)的硬件、匯編、語言、算法等基礎(chǔ)是少不了的。為什么寫這些東西呢?因?yàn)樵诩掖蠖斓倪@么冷,手都不想伸出來寫代碼,只能學(xué)學(xué)理論,實(shí)際實(shí)踐缺少了很多,所以寫下加深印象,也為以后查資料方便(課程設(shè)計(jì)的時(shí)候我的博客真是一大寶庫啊!!!:-),下面是以我的51單片機(jī)為例說明的)。
        下面進(jìn)入正題:

        1、計(jì)時(shí)器

        下面先看一個(gè)圖:


        其中可以清楚的看到,TH0和TL0是兩個(gè)8位寄存器,這兩個(gè)寄存器組合成T0加1計(jì)數(shù)器,所以計(jì)數(shù)器為16位計(jì)數(shù)器。同理,TL1和TH1組合成了T1加1計(jì)數(shù)器。
        再看TMOD寄存器,它是一個(gè)8位寄存器,名字叫做工作方式寄存器,顯然它是控制工作方式的,看電路圖上看它有兩條灰色的線條延伸到T0和T1,即它可控制T0和T1的工作方式,也可以清楚的看到,其低四位控制T0的工作方式,高4位控制T1的工作方式。
        那么什么叫做工作方式呢?工作方式就是指開或者關(guān),芯片是工作在定時(shí)模式還是計(jì)數(shù)模式,和寄存器的使用情況。總體如下:
        GATE是門控位,GATE=0時(shí),TCON中TR0/TR1=1時(shí)可啟動(dòng)。
        GATE=1時(shí),TCON中TR0/TR1=1,且外部中斷引腳為高電平時(shí)可啟動(dòng)。

        C/T=0:定時(shí)模式。C/T=1:計(jì)數(shù)模式。

        M1M0組合使用,其值如下:

        0013位定時(shí)/計(jì)數(shù)器
        0116位定時(shí)/計(jì)數(shù)器
        108位自動(dòng)重裝定時(shí)/計(jì)數(shù)器
        11T0分成兩個(gè)定時(shí)/計(jì)數(shù)器,T1停止
        關(guān)于這四種方式的使用下面再介紹。

        再看TCON寄存器,它與TMOD一樣,叫做控制寄存器,它是用于控制外部中斷啟動(dòng)、申請(qǐng)的一系列工作的。定時(shí)器/計(jì)數(shù)器的工作要依賴于溢出中斷,在中斷處理中處理相關(guān)事件T0或者T1寄存器溢出時(shí)會(huì)申請(qǐng)中斷,然后再處理。比如所以如果想要使用T0計(jì)數(shù)100,那么就用16位寄存器的溢出值減去初始值,既是計(jì)數(shù)值,那么就是65536-100=65436(65536-65436=100),所以T0要首先置初始值65436。這里先介紹TCON的高4位。

        TF1:T1溢出中斷請(qǐng)求標(biāo)志位,T1溢出時(shí)TF1為1,相應(yīng)中斷后自動(dòng)清0,也可使用軟件控制。

        TR1:T1運(yùn)行控制位,TR1為1時(shí),T1工作,TR1為0時(shí),T1停止工作。

        TF0:T0溢出中斷請(qǐng)求標(biāo)志位。同理TF1。

        TR0:T0運(yùn)行控制位,同理TR1。

        M1M0控制的四種工作方式如下:
        0013位計(jì)數(shù),使用了TL0的低5位和TH0的8位組成,TH0溢出置TF0中斷。
        0116位計(jì)數(shù),使用T0。同00。
        10自動(dòng)重裝初值的8位計(jì)數(shù)方式。
        11T1停止,TH0和TL0分開計(jì)數(shù)。

        計(jì)時(shí)器使用步驟:
        ·對(duì)TMOD賦值,確定T1、T0的工作方式。
        ·計(jì)算初值,并將其寫入T0或者T1。
        ·對(duì)IE(IE后面再介紹)賦值,開放中斷。
        ·使TR0或者TR1置位,啟動(dòng)計(jì)數(shù)。

        二、中斷

        中斷估計(jì)都知道是干啥的,這些就不啰嗦了,這里先上一幅圖:


        看這圖估計(jì)都沒心情,下面剖開來看:


        其他的先不看,先看這點(diǎn)圖,這是一個(gè)中斷源,其中IT0是選擇中斷的方式,IT0=1時(shí)為選擇下降沿有效,IT0=0時(shí)為低電平有效(有一個(gè)非門)。當(dāng)中斷觸發(fā)時(shí)就將IE0置1,此時(shí),向CPU申請(qǐng)中斷。那么,IT0和IE0是在什么地方呢?
        還記得上面講的TCON嗎?現(xiàn)在把低四位也加進(jìn)去:
        TF1TR1TF0TR0IE1IT1IE0IT0
        2、




        參照1:INT0。
        3、


        TF0中斷,上面已經(jīng)介紹。
        4、


        TF1中斷,上面已經(jīng)介紹。
        5、(RI或TI中斷)


        串行口中斷請(qǐng)求標(biāo)志,當(dāng)串行口接收完一幀串行數(shù)據(jù)時(shí),置位RI或當(dāng)串行口發(fā)送完一幀串行數(shù)據(jù)時(shí)置位TI,向CPU申請(qǐng)中斷。

        TCON中斷

        其中,TCON中的中斷標(biāo)志有如下幾個(gè):
        TF1TR1TF0TR0IE1IT1IE0IT0
        IT0:外部中斷0觸發(fā)方式門控位。
        ·IT0=0為下降沿有效
        ·IT0=1為負(fù)邊沿觸發(fā)
        IE0:外部中斷0中斷請(qǐng)求標(biāo)志位。
        IT1:外部中斷1觸發(fā)方式控制位(同IT0)。
        IE1:外部中斷1中斷請(qǐng)求標(biāo)志位。
        TF0:T0溢出中斷。
        TF1:T1溢出中斷。

        SCON中斷

        SCON中的中斷如下:
        TIRI
        RI:串行口接收中斷標(biāo)志位。當(dāng)允許串行口接收數(shù)據(jù)時(shí),每接收完一個(gè)串行幀,由硬件置位RI,同樣,RI必須由軟件清除。
        TI:串行口發(fā)送中斷標(biāo)志位。當(dāng)CPU將一個(gè)發(fā)送數(shù)據(jù)寫入串行口發(fā)送緩沖器時(shí),就啟動(dòng)了發(fā)送過程,每發(fā)送完一個(gè)串行幀,由硬件置位TI,CPU響應(yīng)中斷時(shí),不能自動(dòng)清除TI,TI必須由軟件清除。

        下面再看上圖的下一部分:


        這部分叫做中斷允許控制,當(dāng)一個(gè)中斷發(fā)生時(shí),必須由中斷允許控制來檢測(cè)是否允許,如果允許則轉(zhuǎn)入中斷處理,否則不處理。
        先看右邊的EA,這個(gè)是總的中斷允許控制位,CPU想要處理中斷,必須開此中斷允許。
        再看左邊:
        其中各個(gè)中斷允許控制如下:
        ·EX0:外部中斷0允許位
        ·ET0:T0中斷允許位
        ·EX1:外部中斷1允許位
        ·ET1:T1中斷允許位
        ·ES:串行口中斷允許位
        其中,這幾個(gè)位都是由中斷允許寄存器IE控制的,IE寄存器具體如下:
        EAESET1EX1ET0EX0

        很明了,中斷響應(yīng)條件如下:
        1、有中斷請(qǐng)求
        2、中斷源中斷允許位為1
        3、CPU開中斷(EA=1)

        其中,8051有兩個(gè)中斷優(yōu)先級(jí),可以實(shí)現(xiàn)二級(jí)中斷嵌套。每個(gè)中斷源的中斷優(yōu)先級(jí)都是由中斷優(yōu)先級(jí)寄存器IP中的相應(yīng)位的狀態(tài)來規(guī)定的。
        IP寄存器如下:


        PT2PSPT1PX1PT0PX0
        PX0:外部中斷0優(yōu)先級(jí)設(shè)定位,當(dāng)將其設(shè)置為1時(shí)中斷優(yōu)先級(jí)較高。
        可以按照上圖以此類推。
        (這里,PT2是80C52的中斷,不介紹)
        優(yōu)先級(jí)高的中斷可以打斷優(yōu)先級(jí)低的中斷而先執(zhí)行,實(shí)現(xiàn)中斷嵌套。那么同一優(yōu)先級(jí)之間不能打斷,如果多個(gè)同優(yōu)先級(jí)中斷同時(shí)申請(qǐng),則按照自然優(yōu)先級(jí)順序執(zhí)行中斷,自然優(yōu)先級(jí)如下:
        中斷源中斷標(biāo)志中斷服務(wù)程序入口優(yōu)先級(jí)順序
        外部中斷0IE00003H
        T0TF0000BH
        外部中斷1IE10013H
        T1TF1001BH
        串行口中斷RI或者TI0023H

        中斷使用方法如下所示:
        函數(shù)名interruptxusingy
        例如:voidfun()interrupt0using1
        那么,這里的x代表的是何種中斷具體如下:
        0:代表外部中斷0
        1:定時(shí)/計(jì)數(shù)器0
        2:外部中斷1
        3:定時(shí)/計(jì)數(shù)器1
        4:串行口中斷
        這里y代表寄存器組,可取0~7,也可以不寫。
        例如,外部中斷0可以寫:
        interrupt0using1
        外部中斷1可寫
        interrupt2using1


        下面看一個(gè)使用定時(shí)器和中斷的數(shù)字時(shí)鐘的例子:

        #include

        #defineucharunsignedchar

        ucharsecond=1; //秒,全局變量
        ucharcount=0; //中斷次數(shù)
        ucharcodetab[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xe7};

        voidDelay(inta){ //延遲
        inti;
        while(a--){
        for(i=0;i<148;i++);
        }
        }

        //次函數(shù)表明使用的是定時(shí)器,定時(shí)為50ms
        voidTime0_Init()
        {
        TMOD=0x01;
        //TMOD為00000001 表明定時(shí)器處于定時(shí)模式,
        //且為16位定時(shí)器,GATE=0,配合下面TR0=1,則啟動(dòng)寄存器
        TH0=0x4c;
        //設(shè)定初值,即設(shè)定定時(shí)時(shí)間
        TL0=0x00;
        //設(shè)定初值,即設(shè)定定時(shí)時(shí)間
        IE =0x82;
        //0x82二進(jìn)制為10000010,即RA=1,ET0=1,
        //設(shè)定允許響應(yīng)總中斷和T0中斷
        TR0=1;
        //設(shè)置TCON中TR0=1,允許T0工作
        }

        voidTime0_Int()interrupt1 //中斷處理
        {
        TH0=0x4c;
        //重新設(shè)定初值
        TL0=0x00;
        count++;
        if(count==20){
        count=0;
        second++;
        //時(shí)間秒數(shù)加1
        }
        }

        ucharkeyscan(){//4×4鍵盤掃描檢測(cè)
        ucharhang[4]={0xfe,0xfd,0xfb,0xf7};
        uchartemp;
        inti,j;
        for(i=0;i<4;i++){
        P1=hang[i];
        temp=0x10;
        for(j=0;j<4;j++){
        if(!(temp&P1)){
        returni*4+j;
        }
        temp<<=1;
        }
        }
        return0;
        }

        ucharshow_hour(ucharh){ //顯示小時(shí)
        ucharx=h/24;
        uchary=h$;
        P2=0;
        P0=tab[y/10]-0x80;
        Delay(1);
        P2=1;
        P0=tab[y];
        returnx;
        }

        ucharshow_minute(ucharm){ //顯示分鐘
        ucharx=m/60;
        uchary=m`;
        P2=3;
        P0=tab[y/10]-0x80;
        Delay(1);
        P2=4;
        P0=tab[y];
        returnx;
        }

        ucharshow_second(uchars){ //顯示秒
        ucharx=s/60;
        uchary=s`;
        P2=6;
        P0=tab[y/10]-0x80;
        Delay(1);
        P2=7;
        P0=tab[y];
        returnx;
        }

        voidmain()
        {
        ucharhour=1,minute=1;
        ucharh,m,s;
        uchark,mk=0;
        Time0_Init();
        while(1){
        Delay(1);
        if(mk==0){
        s=show_second(second);
        second%=60;
        mk++;
        }
        elseif(mk==1){
        minute+=s;
        m=show_minute(minute);
        minute%=60;
        mk++;
        }else{
        hour+=m;
        h=show_hour(hour);
        hour%=24;
        mk++;
        mk=mk%3;
        }
        k=keyscan();//檢測(cè)按鍵
        if(12==k||13==k||14==k){
        Delay(50);
        k=keyscan(); //軟件消抖
        if(12==k||13==k||14==k){
        if(12==k)hour++;
        elseif(13==k)minute++;
        elseif(14==k)second++;
        }
        }
        }
        }



        評(píng)論


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

        關(guān)閉
        主站蜘蛛池模板: 凭祥市| 襄城县| 鄯善县| 璧山县| 米脂县| 吉隆县| 延寿县| 衡阳市| 丰县| 淮滨县| 边坝县| 洛浦县| 玉树县| 凤山市| 从化市| 雅安市| 平昌县| 洱源县| 博乐市| 昌都县| 龙州县| 始兴县| 松溪县| 韶关市| 松阳县| 大同县| 昌吉市| 德保县| 营口市| 绥中县| 库尔勒市| 田东县| 法库县| 碌曲县| 高青县| 申扎县| 松桃| 宁蒗| 威宁| 抚顺县| 盖州市|