[应用相关] 用一个定时器改变另一个定时器下的三个PWM波占空比

[复制链接]
 楼主| tpgf 发表于 2021-7-1 16:53 | 显示全部楼层 |阅读模式
一、实验原理
问题:我们在之前的学习中可以通过STM32Cube来设置好定时器,但是我们在改变定时器下PWM的占空比时只能在代码中改变其占空比值,PWM波就按照该占空比一直运行,但是我们如果需要占空比随时间变化呢?

(解决方案是在不占用main.c主循环来处理的,以便于大家在使用操作系统或者想在main.c主循环写一些其他东西的时候不影响PWM的输出)
解决方案:我们通过另一个定时器中断来改变当前定时器下的PWM波的占空比,写好计算方法之后就可以按照我们的计算方法来处理PWM。

总而言之就是用一个定时器去改变另一个定时器PWM的参数


 楼主| tpgf 发表于 2021-7-1 16:53 | 显示全部楼层
二、操作步骤

要求:用定时器TIM1构建三个500Hz,脉冲宽度为50%的PWM波,用定时器TIM2中断以50Hz的频率使三个PWM在占空比为50%和80%之间来回变化

1、根据自己的stm32的芯片型号来选择,我这里是STM32F103RBTx

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg


 楼主| tpgf 发表于 2021-7-1 16:53 | 显示全部楼层
2、选好芯片之后照旧设置RCC为外部时钟

20190622211401462.png


 楼主| tpgf 发表于 2021-7-1 16:53 | 显示全部楼层
3、设置定时器TIM1为三路PWM模式,并设置时钟源位内部时钟,定时器TIM2启动即可,如图:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg


 楼主| tpgf 发表于 2021-7-1 16:54 | 显示全部楼层
4、配置时钟树

9691360dd82a67c1d1.png
时钟源选择外部时钟,外部时钟为8MHz倍频9倍后变为72MHz后导入系统时钟,通过AHB分频后得到硬件时钟HCLK后分配给各个部件,图中标识了时钟频率最大值,根据后边的分频来保证各个部件不超过最大频率(按照需求配置,不要小于PWM的频率即可。PS:频率越低越节能,越高性能越好)


 楼主| tpgf 发表于 2021-7-1 16:54 | 显示全部楼层
5、定时器设置(设置PWM频率)

点击TIM1进入配置界面
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg


 楼主| tpgf 发表于 2021-7-1 16:55 | 显示全部楼层
我现在需要使PWM频率达到500Hz,此时时钟树APB2设置为72MHz,所以存在以下计算公式:

                                                目的定时器频率=时钟源/(预分频系数*自动重载值)

                                                时钟源:72MHz
                                                目的定时器频率:500Hz


所以我们可以自己设置自动重载值和预分频系数使等式成立:

预分频系数:144
自动重载值:1000


由于计数是从0开始,所以需要在设置量上减1得到以下设置图
2157160dd82e955a6d.png

之后下拉滑动条,根据下图设置进行更改
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg

以上设置效果为PWM低电平有效,PWM关闭时引脚为高电平

点击ok保存,点击TIM2进入配置界面


 楼主| tpgf 发表于 2021-7-1 16:56 | 显示全部楼层
我现在需要使TIM2频率达到50Hz,此时时钟树APB2设置为72MHz,所以存在以下计算公式:

                                                目的定时器频率=时钟源/(预分频系数*自动重载值)

                                                时钟源:72MHz
                                                目的定时器频率:50Hz


所以我们可以自己设置自动重载值和预分频系数使等式成立:
所以我们可以自己设置自动重载值和预分频系数使等式成立:

预分频系数:1440
自动重载值:1000


由于计数是从0开始,所以需要在设置量上减1得到以下设置图

5284360dd832bc8cd1.png

完成之后设置完毕,点击菜单栏
20190622214451968.png
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg

按照以上设置生成项目(会玩的根据自己的习惯搞)

 楼主| tpgf 发表于 2021-7-1 16:56 | 显示全部楼层
6、代码部分(设置PWM占空比)
由于本次应用不占用main.c主循环,我们大多代码是在tim.c中添加的
首先第一步,一定要在main.c中启动定时器TIM2中断

  /* USER CODE BEGIN 2 */
        HAL_TIM_Base_Start_IT(&htim2); \\启动TIM2中断
        HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);\\启动TIM1的PWM1
        HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);\\启动TIM1的PWM2
        HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);\\启动TIM1的PWM3
  /* USER CODE END 2 */




之后再在main.c中的/* USER CODE BEGIN PV */部分定义全局变量stat,中断需要使用

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t stat=0;
/* USER CODE END PV */



改完main.c文件后打开tim.c,在最下方的用户代码1部分添加如下TIM2中断回调函数:

/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        extern uint8_t stat;
    if (htim->Instance == TIM2)
                        {
                                if (stat==0)  stat=1;                                \\改变状态
                                else  stat=0;
                               
                                if(stat==0)                                                        \\判断状态,状态为0时设定占空比为50%
                                {
                                        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 500);
                                        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 500);
                                        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 500);
                                }
                                else                                                                \\判断状态,状态为1时设定占空比为80%
                                {
                                        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 800);
                                        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 800);
                                        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 800);
                                }
                               
                        }
}

/* USER CODE END 1 */



工作结束,编译下载!!


 楼主| tpgf 发表于 2021-7-1 16:57 | 显示全部楼层
7、测试部分
用逻辑分析仪三个频道夹子夹到对应PWM引脚,底线接板子底线,进行分析得到结果:

237760dd8377a0913.png
眼神不好的同学放大看!!!!!
本次实验为低电平有效,所以周期内有效部分是低电平部分

本次实验PWM频率为500Hz,控制定时器TIM2频率为50Hz,所以应该是10个PWM周期进行一次变化、

由图可知,10个占空比为50%的波形结束后变为10个80%占空比的波形,之后又变为50%占空比
由图可知,一个周期为2.0ms,10个周期改变一次

                                                        fpwm=1/Tpwm=1/0.02s=500Hz
                    fpwm:PWM频率
                        Tpwm:PWM周期
                                                        fc=1/Tc=1/(0.02s*10)=50Hz
                    fc:控制频率
                        Tc:控制周期


由此可知,PWM频率500Hz,占空比每0.2秒变化一次,控制频率为50Hz,占空比变化为50%-80%-50%-80%循环,实验目标达成!


您需要登录后才可以回帖 登录 | 注册

本版积分规则

2347

主题

17448

帖子

21

粉丝
快速回复 在线客服 返回列表 返回顶部