电子电路--PWM

最开始接触到PWM就是学习呼吸灯,所以我们这里也由呼吸灯切入主题。

呼吸灯的实现

要实现一个呼吸灯,可以通过改变一定周期内的亮灯时间占比来实现灯的亮度。持续改变这个亮灯时间占比就可以实现亮度的持续改变,进而实现呼吸灯效果。下面来看代码实现:

#include<reg51.h>
sbit LED=P1^0;

void deley(unsigned int t){
    while(t--);
}
void main(){
	unsigned char time,i;
	while(1){ 
		for(time=0;time<100;time++){
			for(i=0;i<20;i++){
			LED=0;
			deley(time);
			LED=1;
			deley(100-time);
			}
		}
		for(time=100;time>0;time--){
			for(i=0;i<20;i++){
			LED=0;
			deley(time);
			LED=1;
			deley(100-time);
			}
		}
	}
}	

这种方式,是用deley卸载主循环里,那么主循环就不能做其它事情了,所以一般PWM采用定时器的方式来实现。
有些单片机有PWD的任务,但是STC89C52没有,只能定时器来实现。

PWM基本介绍

PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域
PWM重要参数:频率 = 1 / TS 占空比 = TON / TS 精度 = 占空比变化步距

PWM的生成


通过定时器来生成周期
代码实现:

#include <REGX52.H>
#include <Timer0.h>
#define PERIOD 100 //周期长度,值越小变化越快,值越大变化越慢
unsigned char counter;//计数值
unsigned char compare;//比较值
unsigned char direction;//方向 0 灯暗到灯亮,1 灯亮到灯暗
sbit LED=P1^1;

void main(){
	Timer0_Init();
	compare=0;
	direction=0;
	while(1){
	if(counter<compare)
	{
		LED=0;
	}else{
		LED=1;
	}
	}
}
void Timer0_Routine() interrupt 1
{//晶振12MHz 100微妙执行1次,10次1毫秒,变化周期100,则是10毫秒,100个脉冲就是1000毫秒,就是1秒,从灯灭到灯亮1秒
	TL0 = 0x9C;
	TH0 = 0xFF;
	counter++;
	if(counter==PERIOD){
		if(direction){
			compare--;
		}else{
			compare++;
		}
		if(compare==PERIOD||compare==0)
		{
			direction=!direction;
		}
	}
	counter%=PERIOD;
}




posted @ 2022-03-21 15:30  今晚可以打老虎  阅读(614)  评论(0)    收藏  举报