来源:【STM32】动画讲解轻松学会STM32的PWM_哔哩哔哩_bilibili
基本概念
周期/频率
计算公式:PWM周期=1个高电平用时+1个低电平用时
PWM的频率=1/周期
如图所示此时周期为1ms,即1s内存在1000组这样的高低电平,PWM的频率为1000hz。
占空比
计算公式:PWM占空比=高电平用时/PWM周期
即高电平在一个PWM周期内占用的时间比例就叫做占空比。
如图所示1个周期为1ms的PWM方波中高电平占用0.8ms,那么这个PWM方波的占空比就是80%。
用途
PWM设计初衷就是利用数字信号尽可能地拟合模拟信号,手段就是调节PWM的占空比。
如图所示,高电平为3.3V,低电平为0V,那么设置占空比为50%就可以从宏观角度实现输出直流信号幅值为1.65V。
那么同理,占空比为10%时,信号幅值为0.33V。
最关键的是PWM可以实现动态变化,比如如图所示的用PWM拟合sin函数(原理是傅里叶变换,感兴趣的同学可以去看正点原子的手册)。合理调节占空比和频率后输出的PWM信号,就可以控制电机的转速、灯泡的明暗程度、蜂鸣器的音调、舵机的角度等外部设备参数。
TIM实现PWM的输出的原理
定时器的输出比较模式可以输出我们想要的脉冲宽度。在输出比较模式下,我们首先要在比较寄存器中写入一个数值。之后定时器会一直比较计数器值与比较寄存器数值的大小关系,根据这个大小关系来决定输出有效电平还是无效电平。
输入捕获的几种模式:
①冻结模式:输出通道GPIO口不理会比较结果,依旧维持旧的输出状态
②强制有效\强制无效:强制输出通道GPIO口输出有效\无效电平
③匹配有效\匹配无效:比较计数器值与比较寄存器数值相等时输出有效电平\无效电平(如果相等前就是有效\无效电平则维持)
④匹配翻转:二值完全相等时翻转当前输出的电平,这种模式可以输出占空比为50%的方波
④PWM模式:第一种比较计数器值<比较寄存器数值,输出有效电平,反之输出无效电平;第二种比较计数器值>比较寄存器数值,输出有效电平,反之输出无效电平。
同时注意存在向上计数、向下计数以及中央对其模式,下图为三者的矩阵形式概述图:
但一般我们也只用向上计数。
实际操作
首先可以看看拙作:利用STM32的定时器输出PWM方波_stm32f030 定时器方波-CSDN博客
下面介绍一下kk讲的:
CubeMX
①选中可以输出PWM的定时器Channel
②在Timers的mode面板上,设置Clock Source为Interal Clock;输出通道选择PWM输出模式
③在Timers的Configuration面板上设置参数
(加粗的是重点参数)
Counter Settings(计数器设置):
1.Prescaler/Counter Period(预分频系数/计数周期):
PWM周期=(Prescaler+1)(Counter Period+1)/挂载定时器的时钟总线频率,通过这个公式填写预分频系数和计数周期
2.Counter Mode(计数模式):向上计数
3.Internal Clock Division(内部时钟预分频) :No Division
4.auto-reload preload(自动重装载):Disable
Trigger Output Parameters(触发输出参数):
5.Master/Slave Mode(主从符合模式):Disable
6.Trigger Event Selection(触发事件选择):Reset
PWM Generation Channelx(PWM生成通道设置):
7.Mode(模式):PWM mode 1(模式1)
8.Pulse(脉冲):它的范围∈[0,Counter Period];假设为50,又因为这里设置成了PWM模式1,所以0~50输出有效电平,50~99输出无效电平
9.Output compare preload(输出比较预装载):Enable,使能之后需要在下一个计数周期才会生效,以免影响当前周期的比较
10.Fast Mode(快速模式):Disable,不用输出高频PWM波形
11.CH Polarity(输出极性):HIgh(正向)/Low(反向)
编程
进入主循环前开启通道:
/* USER CODE BEGIN TIM3_Init 2 */
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
/* USER CODE END TIM3_Init 2 */
主循环内:
for(int i=0;i<100;i++){
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,i);
HAL_Delay(10);
}
for(int i=99;i>=0;i--){
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,i);
HAL_Delay(10);
}
知识补充
PWM输出时GPIO口是什么模式呢?
/**TIM3 GPIO Configuration
PC7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
__HAL_AFIO_REMAP_TIM3_ENABLE();
复用推挽输出模式(Alternative Function Push Pull),这里更推荐大家去阅读一下生成的HAL库代码而不是直接查看CubeMX。当然修改的话肯定还是推荐改ioc文件的,和实际代码不一致后面维护起来很困难。