打印
[其他ST产品]

STM32实现PWM输出与PWM输入捕获(HAL库)

[复制链接]
楼主: 大鹏2365
手机看帖
扫描二维码
随时随地手机跟帖
21
大鹏2365|  楼主 | 2023-10-29 00:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
若有效电平为Low,则上述(3)、(4)公式变为1-Duty,计数方式(向上向下计数)并不影响占空比的计算公式 。

使用特权

评论回复
22
大鹏2365|  楼主 | 2023-10-29 00:12 | 只看该作者
其中TimerClock为对应定时器的时钟频率;Prescaler为预分频系数;CounterPeriod为重装载值;CCRx为比较寄存器的值,在代码工程中可以使用函数__HAL_TIM_SetCompare()修改CCRx的值从而修改PWM的占空比。

使用特权

评论回复
23
大鹏2365|  楼主 | 2023-10-29 00:12 | 只看该作者
PWM模式一: 在PWM1模式下,无论是向上计数还是向下计数,TIMx_CNT<TIMx_CCR1时通道1为有效电平,有效电平可以在 CH Polarity 参数中设置。

使用特权

评论回复
24
大鹏2365|  楼主 | 2023-10-29 00:12 | 只看该作者
PWM模式二: 在PWM2模式下,无论是向上计数还是向下计数,TIMx_CNT>TIMx_CCR1时通道1为有效电平。

使用特权

评论回复
25
大鹏2365|  楼主 | 2023-10-29 00:12 | 只看该作者
初始脉冲宽度(Pulse): 脉冲宽度即高电平持续的时间,Pluse与CounterPeriod+1的比值即为PWM的初始占空比。

使用特权

评论回复
26
大鹏2365|  楼主 | 2023-10-29 00:13 | 只看该作者
自动预重装载(auto-reload preload): 当使能自动预重装载时,自动重装载寄存器写入新值后,计数器立即产生计数溢出,然后开始新的计数周期;当不使能自动预重装载时,自动重装载寄存器写入新值后,计数器完成当前旧的计数后,再开始新的计数周期。

使用特权

评论回复
27
大鹏2365|  楼主 | 2023-10-29 00:13 | 只看该作者
假设采用如上配置,配置TIM2通道一作为PWM输出,只需在代码工程中调用如下两条函数便可以实现PWM的控制。

使用特权

评论回复
28
大鹏2365|  楼主 | 2023-10-29 00:14 | 只看该作者
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//初始化,开启PWM

__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,1000);//设置比较寄存器CCRx的值,占空比=CCRx/ARRx 此处 CCRx=1000,ARRx=65536

使用特权

评论回复
29
大鹏2365|  楼主 | 2023-10-29 00:14 | 只看该作者
STM32 PWM输入捕获
定时器的PWM输入捕获的框图如下,由通用定时器的框图剪裁得到(去掉了一些与输入捕获无关的功能):

使用特权

评论回复
30
大鹏2365|  楼主 | 2023-10-29 00:14 | 只看该作者
PWM输入捕获流程如下:
1. PWM信号由TIMx_CH1进入,依据是上升沿还是是下降沿从而触发TI1FP1或TI1FP2。

使用特权

评论回复
31
大鹏2365|  楼主 | 2023-10-29 00:14 | 只看该作者
2. 当捕捉到第一次上升沿时,触发TI1FP1,计数器复位,计数值CNT清零。

使用特权

评论回复
32
大鹏2365|  楼主 | 2023-10-29 00:15 | 只看该作者
3. 当捕捉到下降沿时,触发TI1FP2,CNT计数值在TIMx_CH2中被记录到TIMx_CCR2寄存器中。

使用特权

评论回复
33
大鹏2365|  楼主 | 2023-10-29 00:15 | 只看该作者
4. 当再次捕捉到上升沿时,触发TI1FP1,CNT计数值在TIMx_CH1中被记录到TIMx_CCR1寄存器中,同时计数器复位,计数值清零。

使用特权

评论回复
34
大鹏2365|  楼主 | 2023-10-29 00:15 | 只看该作者
5. 依据TIMx_CCR1、TIMx_CCR2的值便可以计算PWM的周期、频率、占空比。TIMx_CCR1的值就是周期,T I M x C C R 2 T I M x C C R 1 \frac{TIMxCCR2}{TIMxCCR1}
TIMxCCR1
TIMxCCR2

的值就是占空比。

使用特权

评论回复
35
大鹏2365|  楼主 | 2023-10-29 00:15 | 只看该作者
关于PWM的输入捕获,有两种CubeMX的配置方式,虽然配置方式不一样但是效果和原理都是完全一致的。

使用特权

评论回复
36
大鹏2365|  楼主 | 2023-10-29 00:19 | 只看该作者
方法一:
这是网上大多数帖子的推荐配置,非常麻烦,这里不推荐使用。

使用特权

评论回复
37
大鹏2365|  楼主 | 2023-10-29 00:19 | 只看该作者

使用特权

评论回复
38
大鹏2365|  楼主 | 2023-10-29 00:19 | 只看该作者
方法二(推荐使用):

方法二与方法一原理与效果是一样的,只不过ST官方考虑到PWM输入捕获较为常用,可以一键配置。只需在Combined Channels中选择PWM Input on CH1同时打开定时器中断即可。

使用特权

评论回复
39
大鹏2365|  楼主 | 2023-10-29 00:19 | 只看该作者
配置完成后在代码中完成定时器的中断回调函数,便可计算PWM的占空比、频率、周期。

/**
*  [url=home.php?mod=space&uid=247401]@brief[/url] 定时器中断回调函数
*  [url=home.php?mod=space&uid=536309]@NOTE[/url]  htim 定时器句柄
*/

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
        if(htim == &htim2)
        {
                if(htim2.Channel == HAL_TIM_ACTIVE_CHANNEL_1)   
                {
                        /* 记录TIM2_CCR1的值 */
                        PWM_RisingCount = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
                       
                        if(PWM_RisingCount != 0 && PWM_FallingCount!= 0)
                        {
                                PWM_Duty        = (float)(PWM_FallingCount / PWM_RisingCount);//占空比
                                PWM_Period      = PWM_RisingCount*0.000001f;                  //周期
                                PWM_Frequency   = 1/PWM_Period;                               //频率
                        }
                }
                else if(htim2.Channel == HAL_TIM_ACTIVE_CHANNEL_2)
                {       
                        /* 记录TIM2_CCR2的值 */
                        PWM_FallingCount = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
                }
        }
}

使用特权

评论回复
40
大鹏2365|  楼主 | 2023-10-29 00:20 | 只看该作者
实战项目

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则