问答

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

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

PWM 嵌入式 国产芯片

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

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

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


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

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

  14.         
  15.         NVIC_DisableIRQ(PWM1P1_IRQn);
  16. }

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

  22.         
  23.         NVIC_DisableIRQ(PWM1P2_IRQn);
  24. }


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

初始化代码如下:

  1. PWM_DISABLE_COMPLEMENTARY_MODE(PWM1);

  2.     /*Set PWM Timer clock prescaler*/
  3.     PWM_SET_PRESCALER(PWM1, 0, 21);
  4.         PWM_SET_PRESCALER(PWM1, 2, 21);
  5.         PWM_SET_PRESCALER(PWM1, 4, 21);
  6.     /*Set PWM Timer duty = 120° */
  7.     PWM_SET_CMR(PWM1, 0, 21817);
  8.         PWM_SET_CMR(PWM1, 2, 21817);
  9.         PWM_SET_CMR(PWM1, 4, 32726);
  10.     /*Set PWM Timer period*/
  11.     PWM_SET_CNR(PWM1, 0, 65453);
  12.         PWM_SET_CNR(PWM1, 2, 65453);
  13.         PWM_SET_CNR(PWM1, 4, 65453);

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

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

  35.     // Start
  36.         PWM1->CNTEN = 0x01u;


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

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