STM32Cube的PWM控制应用篇(二)用两个个定时器生成三个相位差120度的等效正弦波

24 篇文章 12 订阅
8 篇文章 4 订阅

STM32Cube的PWM控制基础篇(一)一路PWM设置
STM32Cube的PWM控制基础篇(二)多路占空比不同的PWM
STM32Cube的PWM控制基础篇(三)定时器的PWM设置详解
STM32Cube的PWM控制应用篇(一)用一个定时器改变另一个定时器下的三个PWM波占空比
拖更好几天,所以今天来点干货!!
以下说明要建立在以上基础篇知识已经搞清楚的情况下来操作!!!!!

通过之前的学习,我们可以基本上操作我们需要的PWM波形,今天就在这个基础上做一些衍生,个人见解,不喜一定要在评论区喷我。

今日目标:用两个个定时器生成三个相位差120度的正弦波

一、实验原理

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

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

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

芯片选择

2、选好芯片之后照旧设置RCC为外部时钟

设置RCC

3、设置定时器TIM1为三路PWM模式,并设置时钟源位内部时钟,定时器TIM2启动即可,如图:

定时器设置

4、配置时钟树

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

5、定时器设置(设置PWM频率)

点击TIM1进入配置界面
在这里插入图片描述
我现在需要使PWM频率达到500Hz,此时时钟树APB2设置为72MHz,所以存在以下计算公式:

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

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

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

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

由于计数是从0开始,所以需要在设置量上减1得到以下设置图
在这里插入图片描述
之后下拉滑动条,根据下图设置进行更改,原理看博客顶部基础篇(三)
在这里插入图片描述
以上设置效果为PWM低电平有效,PWM关闭时引脚为高电平

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

在这里插入图片描述
启动TIM2中断
在这里插入图片描述
完成之后设置完毕,点击菜单栏
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按照以上设置生成项目(会玩的根据自己的习惯搞)。

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语言用的是弧度,所以这里把角度转换成了弧度

7、测试部分

用逻辑分析仪三个频道夹子夹到对应PWM引脚,底线接板子底线,进行分析得到结果:

在这里插入图片描述
由图可知,一个正弦波周期大概为0.2s,之后我们放大来看:
在这里插入图片描述
在这里插入图片描述
大概10个脉冲改变一次占空比,所以20ms改变一次占空比

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

										Good Game!!!!!!

					接下来会推出一系列的关于PWM控制电机的分享,有需要的猿们敬请关注!!!!!

以上内容欢迎大家转载引用,标明出处即可!!!!!

  • 14
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用STM32定时器进行捕获测量相位差之前,需要了解待测量的两个方波的频率,以确定定时器的配置参数。以下是一个简单的方法来实现这个任务: 1. 确定定时器的输入时钟频率和预分频器值。输入时钟频率通常是CPU时钟频率,而预分频器的值则决定了计数器每计数一次所需的时钟脉冲数。例如,如果输入时钟频率为72MHz,预分频器的值为72,则计数器每计数一次需要1us。 2. 设定定时器的计数模式和计数范围。在本例中,我们需要使用定时器的捕获模式来测量两个方波的上升沿/下降沿到达时间。因此,我们需要将定时器设置为捕获模式,并选择捕获上升沿/下降沿的触发条件。此外,需要设定计数器的计数范围,以防止计数器溢出。 3. 配置定时器的通道和捕获寄存器。在本例中,我们需要使用两个定时器通道来捕获两个方波的时间戳。每个通道对应一个捕获寄存器,用于存储捕获时间戳的值。 4. 在定时器中断中读取捕获寄存器的值,并计算两个方波的相位差。由于我们已经知道了方波的频率和计数器每计数一次所需的时间,因此可以使用捕获时间戳的差值计算出相位差。 下面是一个简单的代码示例,用于捕获测量两个不同频率方波的相位差: ```c #include "stm32f10x.h" uint32_t capture1 = 0, capture2 = 0; uint32_t period1 = 0, period2 = 0; float phase_diff = 0; void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); capture1 = TIM_GetCapture1(TIM2); period1 = capture1 - TIM_GetCapture2(TIM2); } else if(TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); capture2 = TIM_GetCapture2(TIM2); period2 = capture2 - TIM_GetCapture1(TIM2); } if(period1 != 0 && period2 != 0) { if(period1 > period2) { phase_diff = (capture1 - capture2) * 360.0 / (period2 * 2.0); } else { phase_diff = (capture2 - capture1) * 360.0 / (period1 * 2.0); } } } int main(void) { // 初始化GPIO和定时器 GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM2, &TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInit(TIM2, &TIM_ICInitStructure); TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); while(1); } ``` 在上面的代码中,我们使用TIM2通道1和通道2来捕获两个方波的上升沿和下降沿。当捕获到上升沿或下降沿时,将触发TIM2_IRQHandler中断,并读取相应的捕获寄存器的值。根据捕获时间戳的差值,计算出两个方波的相位差。最后,我们可以将相位差转换为角,并将其存储在phase_diff变量中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值