问答

汇集网友智慧,解决技术难题

21ic问答首页 - E503R,根据捕获的PWMA产生PWMB,发现AB相位差过大

PWM 单片机 相位差 mb AB ma

E503R,根据捕获的PWMA产生PWMB,发现AB相位差过大 赏1000家园币

郭鑫洋2025-07-23
使用的是GD32E503R,PB10引脚对应timer1_CH2,用于捕获外部PWM信号A的上升沿和下降沿;待捕获信号是50%占空比的200KHZ的PWM信号A;PA8,对应的SHRTIMER_ST0CH0,用于产生PWM信号B;。目标是PB10捕获到上升沿、下降沿,PA8产生的PWM信号翻转一次电平。现在B不能准确跟随A,相位差过大。PA8的PWM.C配置是   outcfg_para.set_request      = SHRTIMER_CHANNEL_SET_NONE   ;
                               outcfg_para.reset_request    = SHRTIMER_CHANNEL_RESET_NONE;
PB10的CAP.C,中断函数中,      if   ( fanzhuan==0  )
                        {
                            shrtimer_slavetimer_waveform_channel_software_request (SHRTIMER0,SHRTIMER_SLAVE_TIMER0, SHRTIMER_ST0_CH0,SHRTIMER_CHANNEL_SOFTWARE_SET);
                                  fanzhuan=1;
                        }
                        else
                        {
                            shrtimer_slavetimer_waveform_channel_software_request (SHRTIMER0,SHRTIMER_SLAVE_TIMER0, SHRTIMER_ST0_CH0,SHRTIMER_CHANNEL_SOFTWARE_RESET);
                            fanzhuan=0;
                        };                                                 Q420471259
回答 +关注 3
8897人浏览 1人回答问题 分享 举报
1 个回答
  • 从您的描述来看,相位差过大的主要原因是软件中断处理延迟。在捕获中断中通过软件请求来翻转PWM会产生明显的延迟。
    问题分析
    1. 中断响应延迟:从捕获事件发生到进入中断函数需要时间
    2. 软件处理延迟:中断函数中的判断和函数调用需要时间
    3. SHRTIMER响应延迟:软件请求到实际输出翻转需要时间
    解决方案
    方案1:使用硬件自动翻转

    // 配置SHRTIMER使用外部事件自动翻转
    outcfg_para.set_request      = SHRTIMER_CHANNEL_SET_EVENT0;   // 使用事件0触发SET
    outcfg_para.reset_request    = SHRTIMER_CHANNEL_RESET_EVENT0; // 使用事件0触发RESET

    // 配置事件系统,将TIMER1的捕获事件连接到SHRTIMER
    shrtimer_event_trigger_config(SHRTIMER0, SHRTIMER_EVENT0,
                                 SHRTIMER_EVENT_TRG_TIMER1_CH2);
    shrtimer_event_config(SHRTIMER0, SHRTIMER_EVENT0,
                         SHRTIMER_EVENT_RISING_EDGE | SHRTIMER_EVENT_FALLING_EDGE,
                         SHRTIMER_EVENT_SRC_TIMER1);

    方案2:优化软件方式
    如果必须使用软件方式,减少中断处理时间:

    // 在中断中直接操作寄存器,避免函数调用
    void TIMER1_IRQHandler(void)
    {
        if(timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH2)) {
            timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH2);
            
            static uint8_t fanzhuan = 0;
            
            // 直接操作SHRTIMER输出寄存器,减少延迟
            if(fanzhuan == 0) {
                SHRTIMER_SWEVT0 |= SHRTIMER_SWEVT_ST0CH0S;
                fanzhuan = 1;
            } else {
                SHRTIMER_SWEVT0 |= SHRTIMER_SWEVT_ST0CH0R;  
                fanzhuan = 0;
            }
        }
    }

    方案3:提高系统时钟和中断优先级

    // 提高TIMER1中断优先级
    nvic_irq_enable(TIMER1_IRQn, 0, 0);  // 最高优先级

    // 确保系统时钟配置正确
    rcu_system_clock_config(); // 根据实际需要配置最高时钟频率



    建议
    1. 优先使用方案1的硬件方式,可以几乎消除延迟
    2. 如果必须用软件方式,使用方案2的直接寄存器操作
    3. 对于200kHz信号(周期5μs),软件方式可能仍有几百ns的延迟
    4. 测试时可以使用示波器同时测量输入和输出信号,验证改进效果


您需要登录后才可以回复 登录 | 注册