STM32单片机:定时器TIM输出PWM波

学习32单片机过程中使用的工具:MDK Keil5 + 正点原子精英版(STM32F103ZET6)+ STM32CubeMX + HAL开发

一、PWM的产生原理

关于PWM的产生原理网上有很多教程,这里就不详细解释了,主要来明晰几个点:
1、定时器TIM怎么产生PWM的?
使用STM32CubeMX配置PWM时,需要设置预分频系数、自动重装载值定时器(也是计数周期)ARR、PWM Mode。这里根据这几个参数对PWM进行说明:
1、STM32定时器TIM在工作时,按周期计数,计数值CNT的最大值就是我们设置的ARR的值,比如向上计数模式下,CNT从0到ARR,再从0到ARR,一直循环。
2、当PWM Mode=1,且计数方式为向上计数时,定时器在计数时就会将CNT与一个比较数(这里设为Pulse)进行比较。当CNT<Pulse时,GPIO引脚输出高电平,当CNT>Pulse时,GPIO引脚输出低电平,这样就产生了PWM的基本波形,就是一上一下的高低电平。而如果我们控制比较数Pulse的变化而保持ARR不变(ARR是计数值CNT的最大值),这样就可以改变PWM波形的占空比,产生不同的PWM波形。
3、PWM波形的频率=定时器TIM的时钟频率/ARR。
比如:已知定时器TIM4挂载在APB1总线上,APB1总线的时钟频率是72MHZ,如果我们设置定时器的预分频系数为(72-1),那么这个定时器的时钟频率就是72/72=1MHZ,如果我们又设置此时的ARR=1000,那么这个定时器产生的PWM波的频率=1000000/1000=1000HZ。
2、PWM为什么可以控制一个器件(比如利用PWM调节LED的光强)的两端电压:
https://zhuanlan.zhihu.com/p/374083276
阅读这个解释之后就理解了,调节PWM的占空比就等价于调节LED两端持续性供电电压的幅值大小,继而调节LED的电流继而控制LED的光强。

二、PWM实例:使LED0作为呼吸灯;使用按键控制LED1的光强

#include "main.h"
#include "tim.h"
#include "gpio.h"

//这个程序是存档的PWM的设置:通过定时器TIM4的通道3(PD14),和通道4(PD15)产生PWM波
//要实现的功能①:PD15输出PWM波,其占空比由小变大再由大变小,进而控制外接LED的亮度
//要实现的功能②:按键Key0控制PD14的PWM波的占空比,来控制外接LED的亮度
//STM32CubeMX的设置:PWM Mode=1; ARR=100; Pulse(脉宽)初始化为0

void SystemClock_Config(void);

	/**************** 由按键触发的外部中断回调函数 *********************/
	uint16_t Pulse3=0;									//定义TIM4通道3输出的PWM波的脉宽,占空比=Pulse3/ARR
	uint16_t Key_Pulse3=0;								//定义PWM波的脉宽调整标志位Key_Pulse3
	void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
	{
		if (Pulse3==0)									
			Key_Pulse3=0;
		if (Pulse3==1000)
			Key_Pulse3=1;
		if (Key_Pulse3==0)					//当Key_Pulse3=0时,每进入一次中断Pulse3+100
			Pulse3+=200;
		if (Key_Pulse3==1)					//当Key_Pulse3=1时,每进入一次中断Pulse3-100
			Pulse3-=200;
	}										//一个潜在的bug就是按键按下去的瞬间会抖动!有可能一次按键产生多次中断


int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM4_Init();

	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);					//打开定时器TIM4通道3的PWM的功能
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);					//打开定时器TIM4通道4的PWM的功能
	
  while (1)
  {
	for(uint16_t Pulse4=0;Pulse4<1000;Pulse4++)					//TIM4的计数值最大是ARR=1000,Pulse4是定时器通道4输出PWM波的脉宽,用来和CNT进行比较
	{
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,Pulse4);		//PWM Mode=1,CNT<Pulse4输出高电平,CNT>Pulse4输出高电平
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,Pulse3);
		HAL_Delay(1);											//占空比=Pulse4/ARR,随着Pulse4的增加,PWM波的占空比变大										
	}

	for(uint16_t Pulse4=1000;Pulse4>0;Pulse4--)
	{
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,Pulse4);
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,Pulse3);
		HAL_Delay(1);
	}    
  }
}


  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值