问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32F405 FOC 使用Timer 触发 ADC采集

创作时间:
作者:
@小白创作中心

STM32F405 FOC 使用Timer 触发 ADC采集

引用
CSDN
1.
https://m.blog.csdn.net/sinat_22081411/article/details/138347903

本文详细介绍了在STM32F405微控制器上使用Timer触发ADC(模数转换器)采集的多种方法,包括DMA软件触发、DMA+TIM触发以及ADC注入模式采集。文章通过具体的代码示例和配置说明,为从事电机控制和嵌入式系统开发的工程师提供了实用的参考指南。

1. ADC采集模式

根据STM32F405数据手册,可以看到ADC block diagram,ADC主要有两种触发模式:

  1. regular conversion mode:常规通道
  2. injected conversion mode:注入通道

2. 高级Timer模式

这里我们用到的是高级定时器的TRGO功能。

3. ADC1 连续采集

连续采集有两种实现方式:

3.1 DMA软件触发

转换完成中断中,再次启动DMA转换

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    printf("%d \t %d \t %d \t %d \r\n",adc1_value[0], adc1_value[1], adc1_value[2], adc1_value[3]);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1_value, ADC_CHNNELS);
}

3.2 DMA+TIM触发

DMA+TIM触发,由TIM trigger event触发DMA采集,只需要在main函数中启动一次DMA采集即可

参考 STM32CubeMX | HAL库的ADC多通道数据采集(轮训、DMA、DMA+TIM)、读取内部传感器温度)配置,但是发现只能启动一次DMA,测试发现需要将ADC1的DMA continuous request设置为enable

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
    printf("init finished \r\n");
    HAL_Delay(100);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rcv_buff, sizeof(rcv_buff));
    HAL_TIM_Base_Start(&htim3);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_Value, ADC_CHNNELS);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
      commander_run();
      HAL_Delay(500);
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4. ADC 注入模式采集

  1. 启动TIM1,默认设置占空比50%
  2. 启动ADC中断,注入模式
__HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC);
HAL_ADCEx_InjectedStart(&hadc1);
    /*启动TIM1 */
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
    /*启动ADC1,regular conversion DMA模式*/
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1_value, ADC_CHNNELS);
    /*启动ADC1,Enable the ADC end of conversion interrupt.*/
    __HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC);
    HAL_ADCEx_InjectedStart(&hadc1);
  1. 在ADC注入中断回调函数中采集,并通过PC4引脚查看是否有输出

这里设置TIM1的Repetition Counter = 1, 每2次计数周期触发一次Trigger out event。通道2-PWM-CH1(24KHz),通道1-PC4脚(12KHz)。

可以看到PWM-CH1通道周期24KHz,一个计数周期3500,每2个计数周期(7000),触发一次Trigger out event,中断内PC4转换电平。

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    m0_phB = hadc->Instance->JDR1;
    m0_phC = hadc->Instance->JDR2;
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);
}

PS:小问题,这里是PWM1通道高电平打开时,触发ADC转换。实际FOC中需要下管为高时采样。需要把PWM CH polarity和PWM CHN polarity设置为low。但是这样设置会导致FOC计算出来的Ta,Tb,Tc参数都需要调整

5. 最终使用方法

采用TIM1的Channel4作为Trigger Event,以此来触发ADC采样。而不用第2节中的Timer update Event。

ADC设置不用改变,仍然使用注入模式,Trigger source 选择Timer1 Trigger out event

参考:

  1. STM32 定时器触发 ADC 多通道采集,DMA搬运至内存
  2. STM32CubeMX | HAL库的ADC多通道数据采集(轮训、DMA、DMA+TIM)、读取内部传感器温度
  3. 野火STM32电机系列(六)Cubemx配置ADC规则和注入通道
  4. 电机FOC控制(三)STM32 CUBEMX 配置ADC采样
  5. 电机FOC控制(二)STM32 CUBEMX 配置三相PWM互补输出
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号