问答

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

21ic问答首页 - 新唐的PWM产生波形,其实起始相位偏移点可以控制的

PWM 嵌入式 国产芯片

新唐的PWM产生波形,其实起始相位偏移点可以控制的

leadd@sina.com2022-04-19
本帖最后由 leadd@sina.com 于 2022-4-20 03:12 编辑

为了形成三相方波,相位差120度。PWM独立方式工作。一开始初始化时就使能了各个通道。然后造成3个一摸一样的波形。完全不是期望的模样。反复测试,在ch0里设计计数比较点为120度。仅使能ch0中断。然后,在PWM0P0里使能第二通道。同理在第二通道中断使能第三通道


void PWM1P0_IRQHandler(void)
{
        /* A相比较事件发生(120)*/
        PWM1->CNTEN |= PWM_CNTEN_CNTEN2_Msk;
        /*标志被硬件置1。软件写1到该位->清标志。*/
        <font color="#ff0000">PWM1->INTSTS0 |= PWM_INTSTS0_CMPUIF0_Msk;    --------<b>这一句,依TRM是写 1 清零的。原想判断哪个通道引起的事件,可这里就是句废话。。。行不通。有人能解释下吗?</b></font>
        
        NVIC_DisableIRQ(PWM1P0_IRQn);
}

void PWM1P1_IRQHandler(void)
{
        /* B相比较事件发生(120)*/
        PWM1->CNTEN |= PWM_CNTEN_CNTEN4_Msk;

        
        NVIC_DisableIRQ(PWM1P1_IRQn);
}

void PWM1P2_IRQHandler(void)
{
        /* c相比较事件发生(120)*/
        PWM_SET_CMR(PWM1, 0, 32726);   //恢复前两相的占空比50%
        PWM_SET_CMR(PWM1, 2, 32726);

        
        NVIC_DisableIRQ(PWM1P2_IRQn);
}


因为是周期波形,中断一次就够了。中断最后是全关闭了

初始化代码如下:

PWM_DISABLE_COMPLEMENTARY_MODE(PWM1);

    /*Set PWM Timer clock prescaler*/
    PWM_SET_PRESCALER(PWM1, 0, 21);
        PWM_SET_PRESCALER(PWM1, 2, 21);
        PWM_SET_PRESCALER(PWM1, 4, 21);
    /*Set PWM Timer duty = 120° */
    PWM_SET_CMR(PWM1, 0, 21817);
        PWM_SET_CMR(PWM1, 2, 21817);
        PWM_SET_CMR(PWM1, 4, 32726);
    /*Set PWM Timer period*/
    PWM_SET_CNR(PWM1, 0, 65453);
        PWM_SET_CNR(PWM1, 2, 65453);
        PWM_SET_CNR(PWM1, 4, 65453);

    /* Set waveform generation */
        /*PWM1 CH0\2\4 设置PRDPCTL0 = 0x01 => PWM周期点输出LOW        */
        PWM1->WGCTL0 = (PWM1->WGCTL0 & ~PWM_WGCTL0_PRDPCTL0_Msk) | (PWM_OUTPUT_NOTHING<<PWM_WGCTL0_PRDPCTL0_Pos);
        /*PWM1 CH0\2\4 设置CMPDCTL0 零点输出LOW*/
        PWM1->WGCTL0 = (PWM1->WGCTL0 & ~PWM_WGCTL0_ZPCTL0_Msk) | (PWM_OUTPUT_HIGH << PWM_WGCTL0_ZPCTL0_Pos);
        PWM1->WGCTL0 = (PWM1->WGCTL0 & ~PWM_WGCTL0_ZPCTL2_Msk) | (PWM_OUTPUT_HIGH << PWM_WGCTL0_ZPCTL2_Pos);
        PWM1->WGCTL0 = (PWM1->WGCTL0 & ~PWM_WGCTL0_ZPCTL4_Msk) | (PWM_OUTPUT_HIGH << PWM_WGCTL0_ZPCTL4_Pos);
        /*PWM1 CH0\2\4 设置CMPDCTL1 => PWM向上计数,比较点输出HIGH*/
        PWM1->WGCTL1 = (PWM1->WGCTL1 & ~PWM_WGCTL1_CMPUCTL0_Msk) | (PWM_OUTPUT_LOW<<PWM_WGCTL1_CMPUCTL0_Pos);
        PWM1->WGCTL1 = (PWM1->WGCTL1 & ~PWM_WGCTL1_CMPUCTL2_Msk) | (PWM_OUTPUT_LOW<<PWM_WGCTL1_CMPUCTL2_Pos);
        PWM1->WGCTL1 = (PWM1->WGCTL1 & ~PWM_WGCTL1_CMPUCTL4_Msk) | (PWM_OUTPUT_LOW<<PWM_WGCTL1_CMPUCTL4_Pos);
        
   // Enable output of all PWM1 channels
    PWM1->POEN |= PWM_POEN_POEN0_Msk | PWM_POEN_POEN2_Msk | PWM_POEN_POEN4_Msk;

    // Enable PWM1 channel 0\2\4 period interrupt.
    PWM1->INTEN0 = (PWM1->INTEN0 & ~PWM_INTEN0_CMPUIEN0_Msk) | PWM_INTEN0_CMPUIEN0_Msk;
        PWM1->INTEN0 = (PWM1->INTEN0 & ~PWM_INTEN0_CMPUIEN2_Msk) | PWM_INTEN0_CMPUIEN2_Msk;
        PWM1->INTEN0 = (PWM1->INTEN0 & ~PWM_INTEN0_CMPUIEN4_Msk) | PWM_INTEN0_CMPUIEN4_Msk;
    NVIC_EnableIRQ(PWM1P0_IRQn);
        NVIC_EnableIRQ(PWM1P1_IRQn);
        NVIC_EnableIRQ(PWM1P2_IRQn);

    // Start
        PWM1->CNTEN = 0x01u;


回答 +关注 14
669人浏览 2人回答问题 分享 举报
2 个回答

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