STM32G4 TIM1触发ADC转换

STM32G4 TIM1触发ADC转换


  • ✨继欧拉电子无刷电机驱动相关视频学习 – STM32G4 FOC开发实战—TIM1 ADC COMP DAC级联

STM32G4 FOC开发实战—TIM1 ADC COMP DAC级联

  • 🌿相对应的文章:https://mp.weixin.qq.com/s?__biz=MzkwMDIzNjA1MQ==&mid=2247484140&idx=1&sn=38128f6f5f8b7afc35a9dd191a4718a8&chksm=c0465490f731dd864907d18ec837e37801062578ac0971eed810268a2efccece02990606e874&mpshare=1&scene=23&srcid=03247g3pxdbfnU0CUA8vrM2i&sharer_shareinfo=411eecf8ebc86fc522cf982bb036e8b0&sharer_shareinfo_first=411eecf8ebc86fc522cf982bb036e8b0#rd

✨跟着视频学习过程中,还是出现了不少状况,在实际测试过程中,发现测试结果并不如视频效果预期。于是各种检查和找问题。

  • 🔖在以上参考内容中,解决了不能进入ADC中断的问题。

⛳注意事项

  • 🌿在上面的视频讲解和文章内容中,没有提及在STM32CubeMX软件中对ADC中断的开启。
  • 🌿ADC注入转换,需要开启对应的中断。具体参考下面main代码初始化配置。

📙本篇工程功能实现概要

  • 🌾STM32G4高级定时器1(TIM1)产生3路互补PWM。:PWM互补输出通过调整PWM信号的占空比来控制电机的转速,通过改变信号的极性来控制电机的转向,从而实现精确的电机控制。
  • 🌾利用高级定时器1(TIM1)通道4,触发ADC采样。
  • 🌾使能ADC1注入通道:ADC1 ->AIN3、ADC1 -> AIN11
  • 🌾使能ADC2注入通道:ADC2 ->AIN1
  • 配合内部的OPAMP,ADC准确的采样三相电流。
  • 🌾使能DAC3 OUT1输出,映射到芯片内部外设。
  • 在三相电流过流时及时封波.
  • TIM1通道4触发ADC注入转换测试:
    在这里插入图片描述

🛠代码配置

  • 📝main
int main(void)
{
  /* USER CODE BEGIN 1 */
//     float temp[5];
//	uint8_t TempData[12];//16  ADC:12;PWM:16 OPM:24
  /* 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_TIM1_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  MX_COMP1_Init();
  MX_DAC3_Init();
  MX_ADC2_Init();
  MX_OPAMP1_Init();
  MX_OPAMP2_Init();
  MX_OPAMP3_Init();
  /* USER CODE BEGIN 2 */
    //	TIM1->PSC = 30000;//VOFA上位机观测,开启
    //	TIM1->ARR = 10000;

//    TIM1->CCR1 = 2000;
//    TIM1->CCR2 = 5000;
//    TIM1->CCR3 = 4000;

    HAL_TIM_Base_Start(&htim1);
    //	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);


    HAL_OPAMP_Start(&hopamp1);
    HAL_OPAMP_Start(&hopamp2);
    HAL_OPAMP_Start(&hopamp3);

    //HAL_UART_Receive_IT(&huart3,(uint8_t *)&aRxBuffer,1);
    HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);//ADC自校验
    HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);
		
    TIM1->ARR = 8000 - 1;
    TIM1->CCR4 = 8000 - 2;//PWM_F=160MHz/(8000*2)=10KHz
    HAL_TIM_Base_Start(&htim1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);//用于产生ADC触发事件

		 __HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC);//需要开启ADC注入中断
		 __HAL_ADC_ENABLE_IT(&hadc2, ADC_IT_JEOC);
    
		HAL_ADCEx_InjectedStart_IT(&hadc1);
		HAL_ADCEx_InjectedStart(&hadc2);
		
    HAL_DAC_Start(&hdac3, DAC_CHANNEL_1);
		HAL_DAC_SetValue(&hdac3, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 3000);
    
		HAL_COMP_Start(&hcomp1);//启动比较器
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    while(1) {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        HAL_ADC_Start(&hadc1);
        HAL_ADC_Start(&hadc2);
        Vpoten = HAL_ADC_GetValue(&hadc1);
        adc_vbus = HAL_ADC_GetValue(&hadc2);
        Vbus = adc_vbus * 3.3f / 4096 * 26;
        HAL_Delay(10);

    }
  /* USER CODE END 3 */
}
  • 🌿按键中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    /*Preventunusedargument(s)compilationwarning */
    // UNUSED(GPIO_Pin);
    if(KEY1_Pin == GPIO_Pin) {
        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);
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
    // if(KEY2_Pin == GPI0_Pin)//没有配置该按键
    //	{
    // HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
    // HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
    // HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
    // HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);
    // HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);
    // HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);
    //	}
}
  • 🌿ADC注入中断回调
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    static uint8_t cnt;
    /*Preventunused argument(s)compilation warning */
//     UNUSED(hadc);
    if(hadc == &hadc1) {
        if(ADC_offset == 0) {
            cnt++;
            adc1_in1 = hadc1.Instance->JDR1;
            adc1_in2 = hadc2.Instance->JDR1;
            adc1_in3 = hadc1.Instance->JDR2;
            IA_Offset += adc1_in1;
            IB_Offset += adc1_in2;
            IC_Offset += adc1_in3;
        }
        if(cnt >= 10) {
            ADC_offset = 1;
            IA_Offset = IA_Offset / 10;
            IB_Offset = IB_Offset / 10;
            IC_Offset = IC_Offset / 10;
        }
    } else {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
        adc1_in1 = hadc1.Instance->JDR1;
        Ia = (adc1_in1 - IA_Offset) * 0.0193359375f;
        adc1_in2 = hadc2.Instance->JDR1;
        Ib = (adc1_in2 - IB_Offset) * 0.0193359375f;
        adc1_in3 = hadc1.Instance->JDR2;
        Ic = (adc1_in3 - IC_Offset) * 0.0193359375f;
        TIM1->CCR1 = 2000;
        TIM1->CCR2 = 4000;
        TIM1->CCR3 = 6000;
        load_data[0] = Ia;
        load_data[1] = Ib;
        load_data[2] = Ic;
        load_data[3] = 0;
        load_data[4] = 0;
//        memcpy(tempData, (uint8_t *)&load_data, sizeof(load_data));
//        HAL_UART_Transmit_DMA(&huart1, (uint8_t *)tempData, 6 * 4);
    }
}

📚测试工程源码

链接:https://pan.baidu.com/s/1eWC-KZDSMnUfOTAn-wMgmg?pwd=s50q 
提取码:s50q
### 回答1: 通过TIM1产生6路PWM信号,并使用CCR4触发ADC1的注入通道进行采样。 首先,我们需要配置TIM1来产生PWM信号。在TIM1的配置中,我们需要设置计数方式为向上计数,使能自动重载寄存器(ARR),设置预分频器的分频系数,配置PWM输出模式和极性。同时,我们还需要设置6个PWM通道的比较输出模式和比较值(CCR)。 接下来,我们需要配置CCR4来触发ADC1的注入通道进行采样。我们需要设置注入通道的采样时间,采样间隔和注入通道的顺序。然后,我们需要配置ADC1的注入通道,并设置注入通道的采样时间和采样顺序。 在使用的时候,我们需要启动TIM1以开始产生PWM信号,并启动ADC1进行注入通道的采样。当CCR4触发时,ADC1将开始采样,并将采样结果存放在指定的寄存器中,可以通过读取这些寄存器来获取采样结果。 请注意,以上是大致的步骤,具体的配置和代码实现可能会因为不同的硬件平台和开发环境而有所区别。 ### 回答2: 使用TIM1产生6路PWM信号,可以通过将TIM1配置为PWM模式,并设置输出比较通道CCR1至CCR6的占空比来实现。首先,需要配置TIM1的时钟和重载值,以确定PWM信号的频率和周期。然后,通过设置CCR1至CCR6寄存器的值,来确定占空比的大小。 接下来,使用CCR4触发ADC1的注入通道采样。首先,需要将TIM1的CCR4通道配置为PWM输出模式,并设置触发ADC1的注入通道。然后,通过设置TIM1的CCR4寄存器的值,来确定ADC1的触发时机。 由于题目中没有提供具体的参数和配置要求,因此无法提供详细的代码实现。但是,上述步骤可以作为整体的框架来实现用TIM1产生6路PWM,并用CCR4触发ADC1的注入通道采样。具体的配置和代码实现,需要根据具体的硬件平台和需求进行调整和编写。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值