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;
}
}
如果有什麼錯誤的地方,望各位多多指教。如果有什麼疑問也可以提出來,大家一起學習進步。