51微控制器使用定時器中斷模擬PWM控制埠電壓
最近應實驗室需求寫一篇51微控制器產生PWM的文章供參考.
微控制器晶片STC89C52,晶振12MHz,編譯環境Keil5.
分析:若使微控制器埠為高電平, 則微控制器輸出電壓為恆值5V. 反之低電平輸出電壓為0V. 但是我們如果在週期為T的時間內使微控制器高電平出現t1秒, 低電平出現t2秒, 那麼在週期內, 高電平出現的時間為, 低電平時間為. 由於週期T的時間極短, 那麼在連續的時間t內, 相應埠輸出電壓為.
實驗使用定時器0, 定時器0由兩個暫存器進行控制,分別為定時器/計數器工作方式暫存器TMOD, 定時器/計數器控制暫存器TCON.
TMOD是一個八位暫存器,如下:
,
TMOD暫存器高4位控制定時器1低四位控制定時器0:
1. GATE位為門控制位, 選擇是否讓外部中斷控制定時器,此位一般置0, 即不讓外部中斷控制定時器.
2. C/T位為選擇定時器/計數器模式選擇, 此實驗中使用定時器模擬時間週期T, 所以置0選擇定時器模式.
3. M1和M0為定時器工作方式選擇位, 控制方式如下:
一般在週期短,要求定時精度高的情況下選擇方式2,但此實驗選擇方式1的16位計數器.
16位計數器的意思是週期T的長度不超過機器週期的倍,在12MHz晶振的作用下,機器週期為1us,故週期T不超過65536us.
TCON控制暫存器暫存器的高4位用於控制定時/計數器的啟動和中斷申請, 低4位用於控制外部中斷(此處不介紹).
- TF1:定時器1溢位中斷請求標誌位。定時器1計數溢位時由硬體自動置TF1為1。CPU響應中斷後TF1由硬體自動清0。定時器1工作時,CPU可隨時查詢TF1的狀態。所以,TF1可用作查詢測試的標誌。TF1也可以用軟體置1或清0,同硬體置1或清0的效果一樣。
- TR1:定時器1執行控制位。TR1置1時,定時器1開始工作;TR1置0時,定時器1停止工作。TR1由軟體置1或清0。所以,用軟體可控制定時/計數器的啟動與停止。
- TF0:定時器0溢位中斷請求標誌位,其功能與TF1類同。
- TR0:定時器0執行控制位,其功能與TR1類同。
定時器工作方式: (以工作方式1為模板)
方式1為16位計數,由定時器的低8位 和 定時器的高8位組成。定時器的低8位溢位時向定時器的高8位進位+1,定時器的高8位溢位時,置位TCON中的TF0標誌,然後定時器高8為與低8位請零, 並向CPU發出中斷請求.
TL0->TH0->TF0->產生中斷(TL0/TH0/TF0清零)
下面介紹個定時器0實現PWM控制LED亮度的程式碼:
利用定時器0產生週期為100*100us, 低電平持續時間為100*20us的方波.
方波如下:
因為這裡我們是產生週期為10ms(100Hz)的PWM,所以可設定中斷的時間基準為100us, 中斷100次即為10ms. 並在中斷裡設定時間變數為n.
1、當n>20時(0< n <T),讓單片相應的埠輸出低電平;(LED燈亮)
2、當20<n<=T時,讓單片相應的埠輸出高電平,此時PWM中低電平的佔空比就為%n。
3、當n=100時,表明週期T已滿,n清零;
下面程式產生20%佔空比的pwm:
#include <reg52.h>
#define T 100 //定義時間進度為100個機器週期,即100us
sbit LED=P1^0;
unsigned int pwm_num=20; //PWM中低電平出現的時間t2
void main()
{
TMOD = 0x01; //選擇為定時器0 工作方式1
TH0=(65536-T)/256; //定時器高八位
TL0=(65536-T)%256; //定時器低八位
TR0=1; //開啟定時器
ET0=1; //開啟定時器1的中斷使能
EA=1; //開啟總中斷
while (1); //等待中斷髮生
}
void Timer1() interrupt 1 //中斷1(定時器0專用中斷通道)
{
static unsigned char n; //靜態變數n 可以看成每100us加一次的時間t
TH0=(65536-T)/256; //重灌定時器的值
TL0=(65536-T)%256;
n++; //表明週期T已到100*100us
if (n==100)
n=0;
LED = (n<=pwm_num) ? 0 : 1; //判斷時間是否超過t2
}
最終實驗現象為:LED燈亮度變低.
若覺文章有助於你,可以在下面留言點贊哦 (<_>)!
如覺文章何處不明也可留言.
若轉載本文請註明出處.