单片机学习D/A转换——pwm呼吸灯
首先我们需要了解
PWM一种以数字方式控制模拟电路的方式。
占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例

例程:定时器制作呼吸灯
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit PWM=P2^1; // P2^1口连接单片机的SCL,也就是时钟线
bit DIR ; //bit是位变量,类似bool,不过比bool省内存 此处DIR用来控制LED呼吸
//--定义一个全局变量--//
u16 value,time,count; //value 有效值 time时间 count 用来计时使有效值变化
void Timer1_Init(); //定时器1初始化函数
void breatheLED(); //该函数输出呼吸信号, 参数是每次呼吸的时间的一半
void main()
{
Timer1_Init(); //定时器1初始化
while(1)
{
breatheLED();
}
}
void Timer1_Init() //定时器1初始化函数
{
TMOD|=0X10; //选择为定时器1模式,工作方式1,仅用TR1打开启动
TH1 = 0xff;
TL1 = 0xff; //计时1us
ET1=1; //打开定时器1中断
EA=1; //打开总中断
TR1=1; //打开定时器
}
void breatheLED() //该函数输出呼吸信号
{
if(count>100) //每100us使得value变化一次
{
count=0; //100us结束,count归零
if(DIR==1) //如果现在是变亮
{
value++; //占空比/有效值增加,灯变亮
}
if(DIR==0) //如果现在是变暗
{
value--; //占空比/有效值变小
}
}
if(value==1000) //如果有效值/占空比等于一个呼吸周期了 也就是现在亮度最大
{
DIR=0; //DIR置0,改为变暗
}
if(value==0) //如果有效值/占空比等于0了
{
DIR=1; //DIR置1,改为变亮
}
if(time < value)//PWM,如果在一个1000us周期里,有value的时间,灯亮着的
{
PWM=1;
}
else if(time > 1000) //如果 time大于1000us,进行下一周期
{
time = 0; //time归零,下一个周期开始
}
else //在1000us里,除了value的时间,灯是灭的
{
PWM=0;
}
}
void Time1(void) interrupt 3 //3 为定时器1的中断号
{
TH1 = 0xff; //重装计时器
TL1 = 0xff; //1us
time++; //1us,时间增长
count++;
}
其中程序是以
10us的高电平在每个1000us的周期中,高电平逐渐+1的形式逐渐变亮的。最后如果占空比达到了整个周期,就会逐渐的-1的形式变暗,直到10us后PWM全部占空比为0.如此循环往复,就是“呼吸灯”。
