1. 程式人生 > >C51微控制器中斷,暫存器,定時器,PWM原理,配置及使用

C51微控制器中斷,暫存器,定時器,PWM原理,配置及使用

大家晚上好,我分享的內容大體是先介紹中斷,各暫存器使用(可能這裡有點囉嗦),然後就簡單寫一下定時器,然後PWM原理,以及它的配置和使用。大概今晚就這樣了,如果有什麼錯的,或有什麼疑問,請大家馬上提出來,一起進步。

中斷:當計算機執行正常程式時,系統中出現某些急需處理的異常情況和特殊請求.


中斷的執行:當CPU正在執行某一程式時,若有中斷響應,則CPU轉而執行中斷服務程式,當中斷服務程式執行完畢後,CPU自動返回原來的程式繼續執行.


中斷服務程式的語句寫法與函式的寫法完全相同,所以,中斷服務程式也是函式,只不過在函式頭部有不同.

中斷函式:

void 函式名()interrupt 中斷號 using 工作組

{

     中斷服務程式內容

}

一般函式:

返回值型別 函式名()

{

    函式執行程式

}


中斷服務程式的執行與函式的執行不同:函式的執行在固定位置的,是通過函式的呼叫來完成的;而中斷的執行是不固定位置的,只要有中斷響應,在一定條件下都會去響應中斷。

52微控制器中斷是分優先級別的

T2是51特有的,但我不怎麼使用。

外部中斷(INT0,INT1),定時/記時中斷(T0,T1,T2),串列埠中斷(TI/RI)要記一下。

在使用之前,通常要設定中斷允許暫存器IE(中斷開關)和中斷優先暫存器IP(優先順序順序設定),它們都是以0,1高低電平進行控制的。其實在我寫的過程中,我基本不會去改變它們優先順序,除非是那種要優先順序影響到,程式正常執行,或者是造成很大的誤差,才會去改變它們優先順序順序;中斷允許暫存器IE這個要記一下,就OK了;

EX0(EX1):外部中斷允許控制位

        EX0=1 外部中斷0開關閉合   //開外部0中斷
        EX0=0 外部中斷0開關斷開

ET0(ET1):定時中斷允許控制位

        ET0=1 定時器中斷0開關閉合 //開內部中斷0

        ET0=0 定時器中斷0開關斷開

ES: 串列埠中斷允許控制位     

        ES=1 串列埠中斷開關閉合     //開串列埠中斷

        ES=0 串列埠中斷開關斷開

EA:  全域性中斷總開關(一定要開,賦為1就好的。)

打開了暫存器,下一步是設定工作方式;

定時器/計數器工作方式暫存器TMOD

TMOD的低半位元組(D0,D1,D2,D3)用來控制定時器/計數器0

TMOD的高半位元組(D4,D5,D6,D7)用來控制定時器/計數器1

        對TMOD中的內容說明:

        GATE——門控制。(我現在編寫基本將GATE置為0,直接接用TR1和TR0啟動定時器T0、T1。)
          GATE=1時,由外部中斷引腳INT0、INT1來啟動定時器T0、T1。   
             當INT0引腳為高電平時TR0置位,啟動定時器T0;   
             當INT1引腳為高電平時TR1置位,啟動定時器T1。   
          GATE=0時,僅由TR0,TR1置位分別啟動定時器T0、T1。

        C/T——功能選擇位 (我一般用定時功能,如果要計數,用個變數,放在中斷裡累加)  
           C/T=0時為定時功能

C/T=1時為計數功能。

     
        M0、M1——方式選擇功能   
        由於有2位,因此有4種工作方式 

 外部中斷:(我沒怎麼用過)(INT0,INT1)

        IE0(IE1):外部中斷請求標誌位

          (原理)  當INT0(INT1)引腳出現有效的請求訊號,此位由微控制器自動置1,cpu開始響應,處理終端,而當入中斷程式後由微控制器自動置0.

        //外部中斷,即外部中斷相應的引腳接入低電平或下降沿訊號時,中斷開始響應。

        IT0(IT1):外部中斷觸發方式控制位(一般不用)

            IT0(IT1)=1:脈衝觸發方式,下降沿有效。

            IT0(IT1)=0:電平觸發方式,低電平有效。

內部中斷:

        TF0(TF1):內部定時器/計數器溢位中斷標誌位

          (原理)  當定時器、計數器計數溢位的時候,此位由微控制器自動置1,cup開始響應,處理中斷,而當進入中斷程式後由微控制器自動置0.

     //內部中斷實際上就是利用內部的計數器,只不過提供計數的脈衝來自微控制器自身。

內部中斷,我經常使用的,將GATE置為0,直接接用TR0和TR1啟動定時器T0、T1。

        TRO(TR1):定時器/計數器啟動位                    //啟動定時器

        TRO(TR1)=1; 啟動定時器/計數器0

        TR0(TR1)=0; 關閉定時器/計數器0

其實定時器中斷時間是就將一個容器填滿的<時間>,因為是16位定時器,TH0表示的是高八位,TL0表示的是低八位,如何算出比較精確的時間,這就不細講了,

這是52微控制器精準延時1ms

最基本的程式,就簡寫了

TMOD=0x01;//0000 0001選擇16位定時器

TH0=(65535-45872)/256;//高八位重灌初值

TL0=(65535-45872)%256;//低八位重灌初值

EA=1;//總開關

ET0=1;//開定時器0的中斷

TR0=1;//啟動定時器0

void T0_time()interrupt 1    //使用T0暫存器  晶振是11.0592MHZ的1ms

{

TH0=(65535-45872)/256;//重灌初值 較精準的1ms的初值

TL0=(65535-45872)%256;

    自個新增程式碼片段

}

PWM的基本原理:

PWM就是脈衝寬度調製,也就是佔空比可變的脈衝波形。

佔空比:就是輸出的PWM中,高電平保持的時間 與 該PWM的時鐘週期的時間之比。

該技術以該結論為理論基礎,對半導體開關器件的導通和關斷進行控制,使輸出端得到一系列幅值相等而寬度不相等的脈衝,用這些脈衝來代替正弦波或其他所需要的波形。按一定的規則對各脈衝的寬度進行調製,既可改變逆變電路輸出電壓的大小,也可改變輸出頻率。

我個人對PWM的理解,就是利用用微控制器定時器(也可以延時函式進行控制,但是不太精準)控制PWM的高電平的輸出時間對時鐘週期所佔的比值的不同,進而對PWM進行控制。

這是我寫的PWM,請大家看一下;

雖然看起來比較繁雜,但所用到的計算公式比較全面,步驟比較清晰;

這裡我就不展開講了,計算好多內容的;有興趣的可以去了解一下;

void pwm(unsigned int zhankongbi,unsigned int fr)//fr是機器頻率,一般是50HZ,zhankongbi是佔空比

{

   if(zhankongbi>100)//這幾句是將佔空比控制在0-100;

      zhankongbi=100;

   else if(zhankongbi<0)

      zhankongbi=0;

   T0out_h=(65536-(zhankongbi/100)*((11059200/12)/fr)+12)/256;

   T0out_l=(65536-(zhankongbi/100)*((11059200/12)/fr)+12)%256;

   T0in_h=(65536-((100-zhankongbi)/100)*((11059200/12)/fr)+12)/256;

   T0in_l=(65536-((100-zhankongbi)/100)*((11059200/12)/fr)+12)%256;//這幾句就不展開講了

   TH0=T0out_h;//初始化 高八位

   TL0=T0out_l; //初始化 低八位

   TR0=1;//啟動T0定時器

  b=1;//控制開關的變數

}

int main()

{

    TMOD=0x01; //0000 0001選擇16位定時器

    IE=0X82;//開啟IE暫存器中的EA總開關和ET0定時器中斷0開關

       TH0=0xfe;//高八位裝初值

       TL0=0x33;//低八位裝初值(初值是經過一系列的計算)

       TR0=1; //啟動T0定時器

}

void Time_T0()interrupt 1//T0定時器進行一系列高低電平的變換

{

   if(b==1)

   {

        TH0=T0in_h;

        TL0=T0in_l;

        b=0;

   }

   else

   {

         TH0=T0out_h;

       TL0=T0out_l;

      b=1;

   }

}


如果有什麼錯誤的地方,望各位多多指教。如果有什麼疑問也可以提出來,大家一起學習進步。