PWM波的产生和呼吸灯程序理解

/* PWM的周期为2000uS;
采用定时器T0的方式2;
占空比每120mS更新一次;
上电时,占空比从50%开始,每次增加5%,增加到95%之后,开始减少,每次占空比减少5%,减少到50%之后,便开始再次增加

分析:由于里面有多个时间需要计数,有PWM波的周期2000uS, 每5%(2000*5%=100uS)变化,占空比120mS
但是只用到了一个定时器,故而必须要求得这三个时间的最大公约数为100uS 每中断一次就是100uS,PWM_VLAUE*/
#include<reg52.h>
unsigned char PWM_COUNT; //计数 每过一个中断就加1,当等于20时,PWM到周期
unsigned int HUXI_COUNT;// 占空比更新时间 必须要累加1200次进行一次更新
unsigned char PWM_VLAUE;//占空比比对值 用来确定什么时候电平该翻转了
bit direc_flag;//占空比更新方向 位大小定义 只有两种状态 非0即1
Sbit LED =P2^0;
void timer0_init()
{
TMOD=0x02; //模式设置,00010000,定时器0,工作于模式2(M1=1,M0=0)
TH0=0xA3; //定时器溢出值设置,每隔200us发起一次中断。 原程序为 TH0=0x47;
TL0=0xA3; //一个机器周期为1.085uS, 100uS /1.085=92个机器周期 255-92
TR0=1; //定时器0开始计时
ET0=1; //开定时器0中断
EA=1; //开总中断
//PWM_COUNT =0;
}
void time0() interrupt 1
{
PWM_COUNT++; //周期累加的变量 一次中断为100uS 那么2000uS就是20次
HUXI_COUNT++; //占空比更新时间累加的变量

if(PWM_COUNT == PWM_VLAUE)//判断是否到了点亮LED的时候 默认为LED =1 电平翻转
LED = 0;//点亮LED

if(PWM_COUNT == 20) //PWM波周期到了,清零 20*100 =2000um 一个周期时间 原来为10
{
LED = 1; //熄灭LED
PWM_COUNT = 0;//重新计时
}

if((HUXI_COUNT == 1200) && (direc_flag == 0)) //占空比的更新的判断 120*100uS =120mS,占空比更新一次(时间是否到了120ms) 方向和当前的方向是否匹配 因为上 电的时候默认为增加的故而现在任然为0
{//占空比增加5%
HUXI_COUNT = 0; //由于占空比到了120mS就要重新计数,故而清零
PWM_VLAUE++; // 原来默认为10现在加1 占空比为11 为55% 对比MCU起航视频
if(PWM_VLAUE == 19)//占空比更改方向 此处进行方向的判断,如果PWM—VALUE自加到占空比为95% 时,就不能再加,需要改变方向 表示这个占空比已经达到95%
direc_flag = 1; //此时占空比不能增加,要减少,故而方向就要变化
}

if((HUXI_COUNT == 1200) && (direc_flag == 1)) //原来为600
//占空比减少5%
{
HUXI_COUNT = 0;
PWM_VLAUE--;
if(PWM_VLAUE == 1)// 占空比更改方向 此时实际波形的占空比为5%
direc_flag = 0; //此时在增加
}
}
void main()
{
HUXI_COUNT = 0;
PWM_COUNT = 0;
PWM_VLAUE = 10; //默认为由于上电时,默认为50%的占空比 原来为5
direc_flag = 0; //当flag=0时,表示增加 flag=1时,减少
LED = 1;//默认LED熄灭
timer0_init();//定时器0初始化
while(1);
}

原文地址:https://www.cnblogs.com/wises/p/9539427.html