[应用相关] 用两个个定时器生成三个相位差120度的等效正弦波

[复制链接]
 楼主| heimaojingzhang 发表于 2021-7-1 17:06 | 显示全部楼层 |阅读模式
实验原理

要求:用定时器TIM1构建三个500Hz的等效正弦波,用定时器TIM2中断三条正弦波的相位
由于三个正弦波相位一个相差120°,三个PWM波形为500Hz,但是我们需要实现的等效正弦波为50Hz,所以可以确定为10个PWM周期为一个正弦波周期,所以我们改变占空比的频率也为50Hz,每次升高36°,10次为一个正弦波周期。
结果应该为每0.02s一个PWM周期,0.1s为一个正弦波周期,每0.2秒改变次PWM占空比。

注意:由于STM32只能生成0或3.3V电压信号,在梦游外部电路情况下不可以生成负电平信号,
     所以这里只是阐述正弦波的的半波(正弦波所有部分都在正半轴)的情况。


 楼主| heimaojingzhang 发表于 2021-7-1 17:07 | 显示全部楼层
1、根据自己的stm32的芯片型号来选择,我这里是STM32F103RBTx

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


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

20190622211401462.png


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

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


 楼主| heimaojingzhang 发表于 2021-7-1 17:08 | 显示全部楼层
4、配置时钟树

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


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

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


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

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

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


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

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


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

1636960dd8637d992c.png


 楼主| heimaojingzhang 发表于 2021-7-1 17:09 | 显示全部楼层
之后下拉滑动条,根据下图设置进行更改
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg
以上设置效果为PWM低电平有效,PWM关闭时引脚为高电平
 楼主| heimaojingzhang 发表于 2021-7-1 17:09 | 显示全部楼层

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

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


 楼主| heimaojingzhang 发表于 2021-7-1 17:09 | 显示全部楼层
启动TIM2中断
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FTV2F0ZXJiZW5iZW4=,size_16,color_FFFFFF,t_70.jpg
 楼主| heimaojingzhang 发表于 2021-7-1 17:10 | 显示全部楼层
完成之后设置完毕,点击菜单栏
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
 楼主| heimaojingzhang 发表于 2021-7-1 17:10 | 显示全部楼层
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,首先在包含一下math.h和定义一下π的值,这里用PI表示

/* USER CODE BEGIN 0 */
#include "math.h"
#define PI 3.14159265358979323846
/* USER CODE END 0 */



在最下方的用户代码1部分添加如下TIM2中断回调函数:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        extern uint8_t stat;

    if (htim->Instance == TIM2)
                {
                if (stat<10)  stat++;                               
                else  stat=0;

                 __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 1000*sin((((float)stat*36)/360)*2*PI));
                 __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 1000* sin(((((float)stat*36)+120)/360)*2*PI));
                 __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3,  1000*sin(((((float)stat*36)-120)/360)*2*PI));                                       
                }
}



由于C语言用的是弧度,所以这里把角度转换成了弧度


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

7799360dd86a2d8fca.png
由图可知,一个正弦波周期大概为0.2s,之后我们放大来看:
4180960dd86a8564c6.png

1188560dd86b25904b.png

大概10个脉冲改变一次占空比,所以20ms改变一次占空比

三个PWM由于正弦计算相差120°且跨步为36°的原因,下面两项无法到0°、180°、360°这三个特殊角度,所以占空比不为0,看相位的话要把输出波形加一个RC滤波器变为电流后观察,由于本人没钱、买不起滤波器的原因,这里大家将就看,主要看三相脉宽宽度较大区域密集的部分和脉宽宽度较小区域密集的部分分别为波峰和波谷,至此为止,实验目的达到,实验结束!!


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

本版积分规则

106

主题

4333

帖子

4

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

106

主题

4333

帖子

4

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