你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G4高级定时器配置互补输出驱动出现波形抖动

[复制链接]
miracle_shaw 提问时间:2025-3-11 15:05 / 已解决

想使用STM32G474VET6的TIM1(高级定时器)作为PWM输出控制三相电机,希望使用互补带死区功能CH1,CH1N,CH2,CH2N,CH3,CH3N。参考官方Demo和CubeMx,使用以下代码生成PWM

TIM_HandleTypeDef htim1;
void InitTimer1(void){
    TIM_OC_InitTypeDef sConfigOC = {0};
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

    __HAL_RCC_TIM1_CLK_ENABLE();

    htim1.Instance                  = TIM1;
    htim1.Init.Prescaler            = 0;
    htim1.Init.CounterMode          = TIM_COUNTERMODE_CENTERALIGNED2;
    htim1.Init.Period               = 4249;                     //170MHz / 20KHz / 2 - 1
    htim1.Init.ClockDivision        = TIM_CLOCKDIVISION_DIV1;
    htim1.Init.AutoReloadPreload    = TIM_AUTORELOAD_PRELOAD_DISABLE;
    htim1.Init.RepetitionCounter    = 0;
    HAL_TIM_PWM_Init(&htim1);

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);

    //TODO
    sMasterConfig.MasterOutputTrigger   = TIM_TRGO_RESET;
    sMasterConfig.MasterOutputTrigger2  = TIM_TRGO2_RESET;
    sMasterConfig.MasterSlaveMode       = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

    sConfigOC.OCMode                = TIM_OCMODE_PWM1;                  //CCMR1_OCxM
    sConfigOC.Pulse                 = 300;
    sConfigOC.OCPolarity            = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCNPolarity           = TIM_OCNPOLARITY_HIGH;
    sConfigOC.OCFastMode            = TIM_OCFAST_DISABLE;
    sConfigOC.OCIdleState           = TIM_OCIDLESTATE_RESET;
    sConfigOC.OCNIdleState          = TIM_OCNIDLESTATE_RESET;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3);

    __HAL_TIM_ENABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_1);
    __HAL_TIM_ENABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_2);
    __HAL_TIM_ENABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_3);

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);

    LL_TIM_GenerateEvent_UPDATE(TIM1);

}
static void SetSysClockTo170_HSE8(void){
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);

    RCC_OscInitTypeDef RCC_OscInitStruct;
    RCC_ClkInitTypeDef RCC_ClkInitStruct;

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
    RCC_OscInitStruct.PLL.PLLN = 85;            //8-127
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV16;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV6;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
        while(1);
    }
    /*The maximum frequency of the AHB, the APB1 and the APB2 domains is 170 MHz.*/
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){
        while(1);
    }
}
int main(void){

    HAL_Init();
    SetSysClockTo170_HSE8();

    InitGpio();
    InitTimer1();
    //InitTimer1_LL();

    while(1){
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        HAL_Delay(250);
    }
    return 0;
}


void InitGpio(void){
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOE_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.Pin = GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                         //推挽
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    //LED Red-PE0 Green-PE1
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                         //推挽
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    //upper bridge arm U-PA8 V-PA9 W-PA10
    GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;                             //复用推挽
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    //lower bridge arm U-PB13 V-PB14
    GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;                             //复用推挽
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    //lower bridge arm W-PB15
    GPIO_InitStruct.Pin = GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;                             //复用推挽
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_TIM1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

经过测试,发现在使能输出以后,正脉冲宽度会有波动,在示波器上可以看出明显余晖,如下图所示,按照代码设计,PWM频率应为20KHz,占空比约为7.06%,正脉冲宽度约为3.529us,大部分波形符合预期。

tek00002.png

小部分波形脉冲宽度仅为3.375us,缩小画面后发现波形异常时PWM频率为20.06KHz

tek00003.png

tek00004.png

使用示波器脉冲宽度小于阈值触发多个波形可以发现,正常波形占大多数,异常波形不会连续出现(下图图片上方白色倒三角为搜索正脉冲宽度小于3.4us的波形所在位置)

tek00005.png


通过查阅手册以及在开发板上测试,发现仅开启一组互补输出时,不会发生该现象,如仅开启CH1,CH1N;开启两组及两组以上互补输出时,会发生该现象;计数器使用上升或下降模式(边沿)计数时,不会发生该现象;使用上下模式(中心对称)计数时会产生此现象。

已尝试的方法还有

1、使用LL库

2、修改HAL库,修改外设使能顺序,MOE,UG寄存器使能顺序

3、去掉死区

以上方法均不能解决该问题,请求各位帮助👀️

tek00002.png
收藏 评论2 发布时间:2025-3-11 15:05

举报

2个回答
butterflyspring 最优答案 回答时间:前天 17:41
刚好有给G474的nucleo 板,按照您的信息测试了一下,还没有发现有速度明显变快的脉冲(<3.45US)。

不过板子上用的是24MHZ 晶振。

STM32G474 PWM COM .PNG
miracle_shaw 回答时间:昨天 08:34

butterflyspring 发表于 2025-3-11 17:41
刚好有给G474的nucleo 板,按照您的信息测试了一下,还没有发现有速度明显变快的脉冲( ...

昨晚我看见您的回复以后,连夜又贴了两块板子。今早测试发现确实是MCU的问题。十分感谢您的测试,截图和回复🎉️

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版