單片機(jī)學(xué)習(xí)D/A轉(zhuǎn)換——pwm呼吸燈
首先我們需要了解
PWM一種以數(shù)字方式控制模擬電路的方式。
占空比是指在一個(gè)脈沖循環(huán)內(nèi),通電時(shí)間相對(duì)于總時(shí)間所占的比例

例程:定時(shí)器制作呼吸燈
#include "reg52.h"
typedef unsigned int u16; ?
typedef unsigned char u8;
sbit PWM=P2^1; // P2^1口連接單片機(jī)的SCL,也就是時(shí)鐘線?
bit DIR ; //bit是位變量,類似bool,不過(guò)比bool省內(nèi)存 此處DIR用來(lái)控制LED呼吸?
//--定義一個(gè)全局變量--//?
u16 value,time,count; //value 有效值 time時(shí)間 count 用來(lái)計(jì)時(shí)使有效值變化??
void Timer1_Init(); //定時(shí)器1初始化函數(shù)
void breatheLED(); //該函數(shù)輸出呼吸信號(hào), 參數(shù)是每次呼吸的時(shí)間的一半?
void main()
{
Timer1_Init();? //定時(shí)器1初始化
while(1)
{
breatheLED();
}
}
void Timer1_Init() //定時(shí)器1初始化函數(shù)?
{
TMOD|=0X10; //選擇為定時(shí)器1模式,工作方式1,僅用TR1打開(kāi)啟動(dòng)
TH1 = 0xff;?
TL1 = 0xff; //計(jì)時(shí)1us
ET1=1; //打開(kāi)定時(shí)器1中斷
EA=1; //打開(kāi)總中斷
TR1=1; //打開(kāi)定時(shí)器
}
void breatheLED() //該函數(shù)輸出呼吸信號(hào)?
{
if(count>100) //每100us使得value變化一次
{??
count=0; //100us結(jié)束,count歸零?
if(DIR==1) //如果現(xiàn)在是變亮 ? ?
{
? value++; //占空比/有效值增加,燈變亮?
}
if(DIR==0) //如果現(xiàn)在是變暗?
{
? value--; //占空比/有效值變小?
}
}
if(value==1000) //如果有效值/占空比等于一個(gè)呼吸周期了 也就是現(xiàn)在亮度最大?
{
? DIR=0; //DIR置0,改為變暗
}
if(value==0) //如果有效值/占空比等于0了?
{
? DIR=1; //DIR置1,改為變亮?
}
if(time < value)//PWM,如果在一個(gè)1000us周期里,有value的時(shí)間,燈亮著的?
{
PWM=1;
}
else if(time > 1000) //如果 time大于1000us,進(jìn)行下一周期?
{
time = 0; //time歸零,下一個(gè)周期開(kāi)始?
}
else //在1000us里,除了value的時(shí)間,燈是滅的?
{
PWM=0;
}
}
void Time1(void) interrupt 3? ? //3 為定時(shí)器1的中斷號(hào)
{
TH1 = 0xff; //重裝計(jì)時(shí)器?
TL1 = 0xff;? ? //1us
time++; //1us,時(shí)間增長(zhǎng)?
? count++;?
}
其中程序是以
10us的高電平在每個(gè)1000us的周期中,高電平逐漸+1的形式逐漸變亮的。最后如果占空比達(dá)到了整個(gè)周期,就會(huì)逐漸的-1的形式變暗,直到10us后PWM全部占空比為0.如此循環(huán)往復(fù),就是“呼吸燈”。
