RT-Thread论坛
直播中

费加罗

9年用户 898经验值
私信 关注
[问答]

N32G435配PWM没有反应是为什么?

我把所有的drv_pwm.c都添加了  设备驱动也添加了BSP的宏定义也添加了,还和457的例程对比了,还和其他的一切相关的比对了 取长补短后,还是不行

回帖(1)

敷衍作笑谈

2025-10-20 17:06:21

针对N32G435配置PWM无输出的问题,结合您的排查步骤,以下是系统化的解决方案:




关键排查步骤




  1. 时钟配置验证


    // 确保定时器时钟使能(以TIM3为例)
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE);
    // 检查APB1时钟频率(PWM周期依赖此时钟)
    SystemCoreClockUpdate();
    rt_kprintf("APB1 clock: %d Hzn", SystemCoreClock / (RCC->CFG_B.APB1PSC + 1));



  2. GPIO复用功能确认



    • 使用官方引脚复用表格(如《N32G435数据手册》)核对PWM引脚

    • 示例代码(TIM3_CH1在PB4):
      GPIO_InitType GPIO_InitStruct;
      GPIO_InitStruct.Pin        = GPIO_PIN_4;
      GPIO_InitStruct.GPIO_Mode  = GPIO_MODE_AF_PP; // 复用推挽输出
      GPIO_InitStruct.GPIO_Speed = GPIO_SPEED_HIGH;
      GPIO_InitStruct.GPIO_Pull  = GPIO_NOPULL;
      GPIO_InitPeripheral(GPIOB, &GPIO_InitStruct);
      GPIO_ConfigPinRemap(GPIO_REMAP_TIM3, ENABLE); // 关键!检查是否需要重映射




  3. 定时器基础配置


    TIM_TimeBaseInitType TIM_TimeBaseStruct;
    TIM_TimeBaseStruct.Period    = 999;       // ARR值,决定周期
    TIM_TimeBaseStruct.Prescaler = 71;         // PSC值,分频后时钟=72MHz/(71+1)=1MHz
    TIM_TimeBaseStruct.ClkDiv    = 0;
    TIM_TimeBaseStruct.CntMode   = TIM_CNT_MODE_UP;
    TIM_InitTimeBase(TIM3, &TIM_TimeBaseStruct);



  4. PWM通道配置


    TIM_OCInitType TIM_OCInitStruct;
    TIM_OCInitStruct.OCMode       = TIM_OCMODE_PWM1; // PWM模式1
    TIM_OCInitStruct.OCPolarity   = TIM_OC_POLARITY_HIGH; // 有效电平
    TIM_OCInitStruct.OCFast       = TIM_OC_FAST_DISABLE;
    TIM_OCInitStruct.Pulse        = 500; // 占空比脉冲值 (500/1000=50%)
    TIM_InitOc1(TIM3, &TIM_OCInitStruct);
    TIM_EnableOcChannel(TIM3, TIM_CHANNEL_1); // 使能通道1



  5. 高级定时器特殊处理(如TIM1)


    // 仅TIM1/TIM8需要
    TIM_EnablePrimaryOutput(TIM1, ENABLE);
    TIM_ConfigBreakDeadTime(TIM1, 0x7F, 0x0F); // 死区时间配置(根据需求调整)



  6. 启动定时器


    TIM_Enable(TIM3, ENABLE); // 启动计数器





RT-Thread驱动层排查




  1. 确认驱动匹配



    • 检查 drv_pwm.c 是否适配N32G435(而非仅G457)

    • 重点函数:stm32_pwm_control() 中的寄存器操作逻辑




  2. 设备树配置检查



    • board.h 中确保启用PWM:
      #define RT_USING_PWM
      #define RT_USING_PWM3 // 示例:启用TIM3
      #define BSP_USING_PWM3_CH1 // 启用通道1




  3. 调试驱动代码
    rt_pwm_enable() 函数中添加调试输出:


    rt_kprintf("Enabling PWM: TIM%d_CH%dn", timer, channel);
    // 在关键寄存器操作后打印寄存器值
    rt_kprintf("TIM%d->CCER = 0x%04Xn", timer, TIMX->CCER);





硬件级验证




  1. 示波器检查



    • 直接测量MCU引脚(不接外部电路),排除外部负载影响




  2. 引脚冲突排查



    • 检查原理图:确认引脚未用于其他功能(如JTAG/SWD)

    • 启动阶段禁用SWD(测试用):
      GPIO_ConfigPinRemap(REMAP_SWJ_NONJTRST, ENABLE); // 释放PB4




  3. 最小化测试代码
    裸机环境下测试PWM(不依赖RT-Thread):


    void PWM_Test(void) {
       // 时钟、GPIO、TIM配置(如上文)
       while(1); // 保持运行
    }





常见陷阱解决方案




  • 问题1:时钟分频错误

    APB1分频系数影响实际定时器时钟。若 RCC->CFG_B.APB1PSC ≥4,定时器时钟会×2。
    修正:动态计算实际频率:


    uint32_t timer_clk = SystemCoreClock;
    if (RCC->CFG_B.APB1PSC >= 4) timer_clk *= 2;



  • 问题2:重映射未启用

    部分PWM引脚需重映射(如TIM3_CH1默认PA6,PB4需重映射):


    GPIO_ConfigPinRemap(GPIO_REMAP_TIM3, ENABLE); // 启用TIM3部分重映射



  • 问题3:寄存器保护锁

    修改配置前解锁:


    TIM_ConfigLock(TIM3, TIM_LOCK_NONE); // 解锁寄存器
    // ... 配置代码 ...
    TIM_ConfigLock(TIM3, TIM_LOCK_LOCK); // 重新锁住





最终验证步骤



  1. 使用示波器测量PB4(或目标引脚)  

  2. 逐步执行:

    • 时钟配置 → 测量OSC_IN是否有振荡

    • GPIO配置 → 测量引脚是否变为复用模式

    • 定时器启动 → 检查计数器是否运行(读 TIMx->CNT

    • PWM输出 → 检查CCER寄存器的CC1E位是否置位



通过以上系统性排查,可定位到PWM无输出的根本原因。重点聚焦在 时钟配置、重映射、RT-Thread驱动适配 三个核心环节。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分