【51】PWM控制使用

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值)。

通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%(周期T - 低电平T2 = 占空比)

2.怎么实现单片机的PWM引脚输出呢?

(1)可以通过芯片的PWM引脚输出。这种自带有PWM输出功能的芯片在程序设计方面更加简便,同时数据更精确,输出更加平滑,一般来说芯片都会标注明PWM引脚。

(2)对于没有PWM引脚的芯片可以通过模拟输出PWM信号实现。其实PWM 信号其实就是一高一低不同时间的一系列电平组合在一起,可以通过定时器计数来实现此类功能。这类方法对于精度、频率等要求不是很高的场合可以这样做。

 PWM信号通常应用于很多场景,像蜂鸣器驱动,直流电机调速,灯光调光等等。

比如呼吸灯,其实就是利用了余辉效应:

       呼吸灯的开关频率速度非常快,人眼捕抓的速度有限,通过PWM(脉宽调制)输出驱动LED,逐渐增加PWM的占空比(高电平时间)从而实现LED模拟呼吸的过程,即渐亮再渐暗再渐亮再渐暗.......如此往复,因为LED开关的频率非常快,加上人眼的视觉暂留效应,所以看上去就和人的呼吸一样。

3.应用实例(通过51演示)

8051系列的单片机由于是没有PWM引脚的,所以我们通过普通引脚输出信号模拟PWM的方式实现呼吸灯效果。

3.1呼吸灯

#include <REGX52.H>			
//8051单片机呼吸灯程序 (简易版) 

sbit LED = P2^0;       //定义接LED的IO口 

void Delay(unsigned int t)    //一个非常快的延时函数,用于改变LED亮灭的时间 
{
		while(t--);
}

void main()
{
	while(1)
	{
  		unsigned int Time;			
  		
	for(Time=0;Time<600;Time++)	       //由暗到亮
    {
		  LED=1;				    //LED亮 ,使用开发板P2口LED这里改成=0
		  Delay(Time);				//经过fou循环,Time从0开始,每次亮的时间+1,直到 >=600 结束 
		  LED=0;				    //LED灭 ,使用开发板P2口LED这里改成=1
		  Delay(600-Time);			//总的时间 - 亮的时间 = 灭的时间 
	 }
	 
	 for(Time=600;Time>0;Time--)	  //由亮到暗 
    {
		  LED=1;					//LED亮 ,使用开发板P2口LED这里改成=0
		  Delay(Time);				//亮的时间从600开始减,一直到0结束 
		  LED=0;				    //LED灭 ,使用开发板P2口LED这里改成=1
		  Delay(600-Time);			//总的时间 - 亮的时间 = 灭的时间 
	 }
	 
	}
}

3.2 按键调档位(定时器方式)

#include <REGX52.H>

sbit LED = P2^0;		//定义电机
sbit Key_1 = P3^1; 		//定义按键 
unsigned char Counter,Compare;	//计数值和比较值,用于输出PWM
unsigned char KeyNum,Speed;		//全局变量存放按键返回值,占空比速度

/**
  * @brief  延时函数,1ms@11.0592MHz 误差 -0.651041666667us
  * @param  无
  * @retval 无
  */
void Delay(unsigned int i)  
{
   unsigned char a,b;
    for(;i>0;i--)
      for(b=102;b>0;b--)
        for(a=3;a>0;a--);
}


/**
  * @brief  定时器0初始化,100us@11.0592MHz
  * @param  无
  * @retval 无
  */
void Timer0_Init(void)
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	
	TL0 = 0xA4;	    	//设置定时初始值
	TH0 = 0xFF;		    //设置定时初始值   高八位低八位0xFFA4 组成 100us 
	
	TF0 = 0;		    //清除TF0标志
	TR0 = 1;		    //定时器0开始计时
	ET0=1;		    	//允许定时器T0中断
	EA=1;		     	//开启总中断
	PT0=0;		     	//优先级为低
}


/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~1,无按键按下时返回值为0
  */
   unsigned char Key()
{
	unsigned char KeyNumber = 0;		//键码初始值为0 

	if(Key_1 == 0)			//按键按下 
	{  
	  Delay(20);			//按键消抖 Delay(20) = 20ms 
	  while(Key_1 == 0);	//等待按键释放 
	  Delay(20);			 
	  KeyNumber = 1;		//键码值变为 1 
	}
	
	return KeyNumber;	   	//返回键码值
}


/**
  * @brief  主程序
  * @param  无
  * @retval 无
  */
void main()
{
	Timer0_Init();			//定时器初始化
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)		//按键按下
		{
			Speed++;		//速度加1
			Speed%=4;		//速度范围0~3,等于4的时候清0
			if(Speed==0) {Compare=0;}   	//速度0档,PWM占空比为0
			if(Speed==1) {Compare=25;}  	//速度1档,PWM占空比为25
			if(Speed==2) {Compare=60;}  	//速度2档,PWM占空比为60
			if(Speed==3) {Compare=100;}	    //速度3档,PWM占空比全速
		}
	}
}


void Timer0() interrupt 1	 //进入定时器中断
{
	TL0 = 0xA4;	    	//重新赋初始值 
	TH0 = 0xFF;
	
	Counter++;			 //计数值自加 
	Counter%=100;		 //计数值变化范围限制在0~99

	if(Counter < Compare)	 //计数值小于比较值
	 LED = 1;		   	     //输出高电平 点亮 (注意:51开发板LED为低电平点亮) 
				   
	else				//计数值大于比较值
  	 LED = 0;		        //输出低电平 熄灭 
}

相关资料链接:

延时函数的计算方法icon-default.png?t=N7T8http://t.csdn.cn/4yiAb

51定时器详解icon-default.png?t=N7T8http://t.csdn.cn/lYJOY

由于工作问题,博客也很少更了,在这里也希望自己的一些文章能帮到大家。

  • 17
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
51单片机中,可以使用定时器/计数器来实现PWM波形的输出。具体的步骤如下: 1. 配置定时器/计数器的工作模式为PWM模式。 2. 设置定时器/计数器的计数值,该值决定了PWM波形的频率,即PWM信号的周期。 3. 设置占空比,即PWM信号高电平所占的比例。占空比的计算公式为:占空比 = (TH / (TH + TL)) x 100%,其中TH为高电平时间,TL为低电平时间。 4. 启动定时器/计数器开始计数,当计数值达到TH时,输出PWM信号高电平,当计数值达到TH+TL时,输出PWM信号低电平,即一个PWM信号周期完成。 5. 通过改变TH的值,可以实现占空比的调节。 下面是一个简单的示例代码,实现了调节PWM波形占空比的功能: ```C #include <reg52.h> sbit led = P1^0; // 定义LED连接的IO口 void main() { TMOD = 0x01; // 定时器1工作在模式1,16位定时器/计数器 TH1 = 0x00; // 设置TH的初始值为0 TL1 = 0x00; // 设置TL的初始值为0 TR1 = 1; // 启动定时器1 while(1) { for(int i = 0; i < 100; i++) // 循环调节占空比 { TH1 = i; // 设置TH的值,调节占空比 TL1 = 100 - i; // TL的值为100 - TH的值 led = 1; // 输出PWM信号高电平 while(TF1 == 0); // 等待定时器1计数完成一次 TF1 = 0; // 定时器1计数完成后清零 led = 0; // 输出PWM信号低电平 } } } ``` 在上面的代码中,通过改变TH的值,可以实现占空比的调节。循环100次,每次将TH的值从0逐渐增加到99,TL的值从100逐渐减小到1,实现了占空比从0%到99%的变化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值