51單片機(jī)PWM的控制(呼吸燈)
一、PWM
Pulse Width Modulation脈沖寬度調(diào)制,簡稱PWM。
PWM(脈沖寬度調(diào)制)對模擬信號電平進(jìn)行數(shù)字編碼的方法,計(jì)算機(jī)只能輸出0或5V的數(shù)字電壓值而不能輸出模擬電壓,而我們?nèi)绻氆@得一個(gè)模擬電壓值,則需通過使用高分辨率計(jì)數(shù)器,改變方波的占空比來對一個(gè)模擬信號的電平進(jìn)行編碼。
仍輸出數(shù)字信號,因?yàn)闈M幅值的直流供電只有5V(1)和0V(0)兩種。電壓是以一種連接(1)或斷開(0)的重復(fù)脈沖序列被夾到模擬負(fù)載上去的,連接即是直流供電輸出,斷開即是直流供電斷開。通過對連接和斷開時(shí)間的控制,只要帶寬足夠,可以輸出任意不大于最大電壓值的模擬電壓。
輸出電壓=(接通時(shí)間/脈沖時(shí)間)*最大電壓值
12
二、51單片機(jī)的Timer
作者用的單片機(jī)是STC89C52,其內(nèi)部有3個(gè)16位Timer,分別為T/C0,T/C1,T/C2,通過配置相關(guān)寄存器即可實(shí)現(xiàn)Timer的功能控制。
控制PWM需要用到定時(shí)器來生成不同占空比的波形,采用定時(shí)器中斷的方式。
相關(guān)寄存器:
1.IE寄存器
位 | 名稱 | 功能 |
---|---|---|
0 | EX0 | 外部中斷0的中斷允許位 |
1 | ET0 | Timer0的溢出中斷允許位 |
2 | EX1 | 外部中斷1的中斷允許位 |
3 | ET1 | Timer1的溢出中斷允許位 |
4 | ES | 串行口中斷允許位 |
5 | ET2 | Timer |
6 | - | - |
7 | EA | 中斷允許總控制位 |
2. TCON寄存器
位 | 名稱 | 功能 |
---|---|---|
0 | IT0 | 外部中斷0的觸發(fā)方式選擇位。功能和IE1類似 |
1 | IE0 | 外部中斷0的中斷請求標(biāo)志位。功能和IE1類似 |
2 | IT1 | 外部中斷1的觸發(fā)方式選擇位。當(dāng)IT1=1時(shí),為下降沿觸發(fā)方式,也就是從高到低的跳變會(huì)觸發(fā)外部中斷1。當(dāng)IT1=0時(shí),為低電平觸發(fā),也就是單片機(jī)檢測到該引腳電平為低時(shí),會(huì)觸發(fā)外部中斷1 |
3 | IE1 | 外部中斷1的中斷請求標(biāo)志位。當(dāng)IE1=1的時(shí)候,表示外部中斷1被觸發(fā),正在請求單片機(jī)處理中斷事件。當(dāng)單片機(jī)相應(yīng)中斷,處理中斷事件時(shí),該位由單片機(jī)自動(dòng)清零 |
4 | TR0 | 啟動(dòng)定時(shí)器/計(jì)數(shù)器0啟動(dòng)位,功能和TR1類似 |
5 | TF0 | 定時(shí)器/計(jì)數(shù)器T0溢出中斷請求標(biāo)志位。功能和TF1類似. |
6 | TR1 | 啟動(dòng)定時(shí)器/計(jì)數(shù)器1啟動(dòng)位,TR=1啟動(dòng)計(jì)時(shí),TR=0停止計(jì)時(shí) |
7 | TF1 | 定時(shí)器/計(jì)數(shù)器T1溢出中斷請求標(biāo)志位。當(dāng)T1溢出時(shí),該位自動(dòng)置1。單片機(jī)響應(yīng)相應(yīng)中斷時(shí),系統(tǒng)自動(dòng)清零TF1,也可以程序清零 |
3. TMOD寄存器
控制Timer0/1的工作方式
位 | 名稱 | 功能 |
---|---|---|
0 | M0 | 工作方式選擇位 |
1 | M1 | 工作方式選擇位 |
2 | C/T | 計(jì)數(shù)器模式和定時(shí)器模式選擇位,C/T=1時(shí),為計(jì)數(shù)器模式,C/T=0時(shí),為定時(shí)器模式。C為counter的縮寫,T為timer的縮寫,這樣方便理解 |
3 | GATE | T1(0)的啟動(dòng)源選擇位,GATE=1時(shí),用外部中斷引腳INT1(INT0)上的高電平來啟動(dòng)T1(T0);GATE=0時(shí),用TCON里的TR1(TR0)來啟動(dòng)T1(T0)。 |
4 | M0 | 相似于0位 |
5 | M1 | 相似于1位 |
6 | C/T | 相似于2位 |
7 | GATE | 相似于3位 |
M1 | M0 | 工作方式 |
---|---|---|
0 | 0 | 方式0,由TH1(TH0)的8位和TL1(TL0)的低5位組成一個(gè)13位定時(shí)器。 |
0 | 1 | 方式1,由TH1(TH0)的8位和TL1(TL0)的8位組成一個(gè)16位定時(shí)器。 |
1 | 0 | 方式2,TL1(TL0)溢出后,TH1(TH0)的數(shù)值自動(dòng)填充到TL1(TL0)。 |
1 | 1 | 方式3,僅適用于T0,T0分成兩個(gè)8位計(jì)數(shù)器,T1停止計(jì)數(shù)。 |
4. Timer0/1計(jì)數(shù)寄存器
TL0
TL1
TH0
TH1
當(dāng)定時(shí)開啟后,TL0(TL1)自動(dòng)跟隨機(jī)器周期加一。當(dāng)TL0(TL1)滿了后,自動(dòng)清零同時(shí)向TH0(TH1)進(jìn)一位,不需要手動(dòng)操作.
而當(dāng)TL0(TL1)和TH0(TH1)都滿了以后,此時(shí)如果定時(shí)中斷和總中斷都已經(jīng)打開,那么就會(huì)發(fā)生溢出中斷,同時(shí)這兩個(gè)寄存器清零
三、運(yùn)用PWM完成呼吸燈
1. 硬件電路
2. 軟件驅(qū)動(dòng)
unsigned char PWM_COUNT; //計(jì)數(shù)
unsigned int HUXI_COUNT; //占空比更新時(shí)間
unsigned char PWM_VLAUE; //占空比比對值
bit direc_flag; //占空比更新方向
void timer0_init()
{
TMOD=0x02; //模式設(shè)置,00010000,定時(shí)器0,工作于模式2(M1=1,M0=0)
TH0=0x47; //定時(shí)器溢出值設(shè)置,每隔200us發(fā)起一次中斷。
TL0=0X47;
TR0=1; //定時(shí)器0開始計(jì)時(shí)
ET0=1; //開定時(shí)器0中斷
EA=1; //開總中斷
PWM_COUNT =0;
}
void time0() interrupt 1
{
PWM_COUNT++;
HUXI_COUNT++;
if(PWM_COUNT == PWM_VLAUE) //判斷是否到了點(diǎn)亮LED的時(shí)候
LED = 1; //點(diǎn)亮LED
if(PWM_COUNT == 10) //當(dāng)前周期結(jié)束
{
LED = 0; //熄滅LED
PWM_COUNT = 0; //重新計(jì)時(shí)
}
if((HUXI_COUNT == 600) && (direc_flag == 0))
{ //占空比增加10%
HUXI_COUNT = 0;
PWM_VLAUE++;
if(PWM_VLAUE == 9) //占空比更改方向
direc_flag = 1;
}
if((HUXI_COUNT == 600) && (direc_flag == 1))
{ //占空比減少10%
HUXI_COUNT = 0;
PWM_VLAUE--;
if(PWM_VLAUE == 1) //占空比更改方向
direc_flag = 0;
}
}
void main()
{
HUXI_COUNT = 0;
PWM_COUNT = 0;
PWM_VLAUE = 5;
direc_flag = 0;
LED = 1; //默認(rèn)LED熄滅
timer0_init(); //定時(shí)器0初始化
while(1);
}
編輯:admin 最后修改時(shí)間:2018-05-18