向未知探索 2024-12-19 09:07 采纳率: 37.5%
浏览 19

如何配置STM32G0,使BLDC的载波中断与载波频率异步?

1、需求:将BLDC的载波周期从128us提高到64us,但其载波中断的周期不变、仍为128us,要求提供STM32 Cube MX TIM1和ADC0的配置截图

背景:目前使用STM32G0的TIM1驱动ADC转换完了中断,每128us进中断1次,输出载波1次;开发环境是KEIL+STM32CUBEMX,MCU运行频率是64MHZ

  • 写回答

1条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2024-12-19 10:04
    关注
    让【道友老李】来帮你解答,本回答参考通义千问大模型编写,并整理提供,如果还有疑问可以点击头像关注私信或评论。
    如果答案让您满意,请采纳、关注,非常感谢!
    要满足你的需求,我们需要将BLDC的载波周期从128us提高到64us,但保持载波中断的周期为128us。这意味着我们需要调整TIM1的配置,使得载波频率加倍,同时确保每128us触发一次中断。我们还需要确保ADC0在每个载波周期内完成一次转换。

    以下是详细的步骤和配置方法:

    1. 配置TIM1

    • 时钟源:选择内部时钟(默认)
    • 预分频器:设置为63,使得TIM1的计数频率为1MHz(64MHz / 64 = 1MHz)
    • 自动重装载值:设置为63,使得载波周期为64us(1MHz / 15.625kHz = 64us)
    • 中断:配置更新中断(Update Interrupt),每128us触发一次

    STM32 Cube MX TIM1配置截图

    请参考以下配置: - 时钟源:Internal Clock - 预分频器 (PSC):63 - 自动重装载值 (ARR):63 - 中断:启用Update Interrupt

    TIM1 Configuration

    2. 配置ADC0

    • 时钟源:选择APB2时钟(默认)
    • 采样时间:设置为2.5个周期(根据需要调整)
    • 转换模式:单次转换
    • 触发源:选择TIM1 TRGO
    • 数据对齐:右对齐
    • DMA:禁用(如果不需要DMA传输)

    STM32 Cube MX ADC0配置截图

    请参考以下配置: - 时钟源:APB2 Clock - 采样时间:2.5 Cycles - 转换模式:Single Conversion - 触发源:TIM1 TRGO - 数据对齐:Right Aligned - DMA:Disabled

    ADC0 Configuration

    3. 代码实现

    在生成的代码中,我们需要手动添加一些代码来确保每128us触发一次中断。

    #include "stm32g0xx_hal.h"
    
    TIM_HandleTypeDef htim1;
    ADC_HandleTypeDef hadc1;
    
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_TIM1_Init(void);
    static void MX_ADC1_Init(void);
    
    int main(void)
    {
        HAL_Init();
        SystemClock_Config();
        MX_GPIO_Init();
        MX_TIM1_Init();
        MX_ADC1_Init();
    
        // 启动TIM1
        HAL_TIM_Base_Start(&htim1);
        // 启动ADC
        HAL_ADC_Start(&hadc1);
    
        uint32_t counter = 0;
    
        while (1)
        {
            if (__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_UPDATE) != RESET)
            {
                __HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_UPDATE);
    
                if (counter == 2)
                {
                    // 每128us触发一次中断
                    HAL_ADC_Start_IT(&hadc1);
                    counter = 0;
                }
                else
                {
                    counter++;
                }
            }
        }
    }
    
    static void MX_TIM1_Init(void)
    {
        TIM_ClockConfigTypeDef sClockSourceConfig = {0};
        TIM_MasterConfigTypeDef sMasterConfig = {0};
    
        htim1.Instance = TIM1;
        htim1.Init.Prescaler = 63;
        htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
        htim1.Init.Period = 63;
        htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
        htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
        if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
        {
            Error_Handler();
        }
        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
        if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
        {
            Error_Handler();
        }
        sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
        sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
        if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
        {
            Error_Handler();
        }
    }
    
    static void MX_ADC1_Init(void)
    {
        ADC_ChannelConfTypeDef sConfig = {0};
    
        hadc1.Instance = ADC1;
        hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
        hadc1.Init.Resolution = ADC_RESOLUTION_12B;
        hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
        hadc1.Init.ScanConvMode = DISABLE;
        hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
        hadc1.Init.LowPowerAutoWait = DISABLE;
        hadc1.Init.ContinuousConvMode = DISABLE;
        hadc1.Init.NbrOfConversion = 1;
        hadc1.Init.DiscontinuousConvMode = DISABLE;
        hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO;
        hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
        hadc1.Init.DMAContinuousRequests = DISABLE;
        hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
        if (HAL_ADC_Init(&hadc1) != HAL_OK)
        {
            Error_Handler();
        }
    
        sConfig.Channel = ADC_CHANNEL_0;
        sConfig.Rank = 1;
        sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
        if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
        {
            Error_Handler();
        }
    }
    

    4. 解释

    • TIM1配置:通过设置预分频器和自动重装载值,使TIM1的周期为64us。
    • ADC配置:通过TIM1的TRGO信号触发ADC转换,确保每个载波周期内完成一次转换。
    • 中断处理:通过计数器确保每128us触发一次中断,并启动ADC转换。

    请根据实际情况调整配置和代码。希望这些信息对你有帮助!

    评论

报告相同问题?

问题事件

  • 创建了问题 12月19日