STM32F407在TIM1计数模式为上下计数时,TIM1与TIM2同步配置同时使用TIM2触发ADC
1 概述
SVPWM作为一种脉冲调制方式已被广泛的应用在电机调速,以及变流器的控制中。在通过计算得到每个扇区作用时间后需要转换成MCU对应的计数值,根据SVPWM每个扇区作用时开关的切换顺序,如图1是扇区一作用时开关的切换顺序,可以得到最适合SVPWM的MCU计数方式是上下计数。
图一
由于STM32在使用上下计数模式时会在每一次溢出都会产生一次更新事件从而触发中断。
所以会导致事件中断频率是PWM频率的两倍,所以在这里采用TIM1与TIM2同步的方式让TIM2产生事件跟新中断,TIM2与TIM1周期相同并且同时工作,TIM2采用向上计数方式,占空比设置为50%,从而使得中断频率与PWM频率相同。
TIM1的CubeMX配置
TIM1使用内部时钟源,同时输出三路互补的PWM,计数模式为中心对齐模式1(Center Aligned mode1),频率为10KHz。根据中心对齐模式的特点,计数值为8400.
由于需要通过TIM1来触发TIM2使得TIM1与TIM2同步,所以需要使能TIM1主模式使能触发,触发源选择计数使能
这是根据F4手册中的一个例子得到的,例子中是用外部触发来使能TIM1计数再通过TIM1使能TIM2计数
接下来就是死区以及PWM占空比等等的配置,死区时间需要根据具体的开关器件来确定,本文中死区时间设置为0。
TIM2的CubeMX配置
由于TIM2需要由TIM1触发,所以从模式选着触发模式(Trigger Mode)触发源选着ITR0
时钟源选着内部时钟,由于需要使用TIM2去触发ADC,所以将通道二配置成PWM不输出
由于TIM2的总线时钟频率为TIM1时钟频率的一半(TIM2在总线APB1上TIM1在总线APB2上),所以TIM2工作在向上计数模式的时候,计数频率设置为10KHz时,计数值设为8400.需要通过TIM2来触发ADC采样,所以使能TIM2主模式,触发事件选择更新事件(Update Event),
pwm模式选着pwm mode 1.占空比设置为50%即4200。
并且开启TIM2的中断
ADC的CubeMX配置
ADC1的CubeMX配置如下图所示
由于使用了多个采用通道所以需要使能扫描模式,同时禁止连续与不连续模式,使能DMA,触发源选择Timer2 触发输出事件(Timer2 Trigger Out Event),触发检测采用上升沿检测。DMA配置如下图所示
DMA采用循环模式,数据宽度都采用Word型(32位)。
生成代码后的一些配置
首先对串口进行重定向,我是用的是UART1,在main函数的用户代码区加入如下代码
int fputc(int c, FILE *stream)
{
HAL_UART_Transmit(&huart1, (unsigned char *)&c, 1, 1000);
return 1;
}
在初始化函数下加入以下代码
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_Value,3);
HAL_TIM_Base_Start(&htim1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,4200);
HAL_TIM_Base_Start_IT(&htim2);
在tim.c里加入TIM回调函数
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_14);
Udc_in = ADC_Value[0];
Udc_out = ADC_Value[1];
Idc_out = ADC_Value[2];
}
}
其中翻转GPIOD14的目的是为了观测中断频率
同时在主函数while循环里打印ADC的值;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// OLED_P6x8Str(0,0,"DC_MODE = DC_CLOSE");
printf("%d\r\n",Udc_in);
printf("%d\r\n",Udc_out);
printf("%d\r\n",Idc_out);
}
/* USER CODE END 3 */
}
实验结果
从示波器上可以看出PWM输出频率是10K(通道一黄色),中断频率是10K(通道二蓝色显示的是5K,这是因为每一次中断才翻转一次电平),
可以看到TIM2比TIM1略有延迟,手册中也有说明
串口传输的是ADC寄存器的值