Sinusoidal PWM

Hello,

I'm tyring to program a STM32F4 (with ARM F4) board to generate a sinusoidal PWM, that is a sequence of pulses with variable width that, once filtered by a LPF, gives a sinusoid.

I was told the best way to get it is by generating a sequence of single pulses synchronized to timer by interrupts.

I've tried several solutions but I'm not good at managing interrupts.

Do you have any idea how to achieve this goal?
Can you attach a piece of code where it's explained how to do it?

Thanks in advance! ;)

Mara

Parents
  • You can't manage them, or you don't understand the concept? Can your teachers/instructors not take responsibility for adequately explaining things?

    Yes, you can use PWM mode, you can create a table of values to program into the CCRx for the channel you're using at each Update interrupt of the timer.

    If the value of the Period is 10000-1, then the sine table you create will need to be 5000 + 5000*sin(angle), a table with 10 degree increments would consist of 36 entries. At each interrupt you'd output the next value, incrementing a counter, and wrapping it based on the size of the table.

    ie

    void TIMx_IRQHandler(void) // Adapt for timer and channel under consideration
    {
      static int index = 0;
    
      if (TIM_GetITStatus(TIMx, TIM_IT_Update) != RESET)
      {
        TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
    
        TIMx->CCRx = sinetbl[index];
        index = (index + 1) % 36;
      }
    }
    

Reply
  • You can't manage them, or you don't understand the concept? Can your teachers/instructors not take responsibility for adequately explaining things?

    Yes, you can use PWM mode, you can create a table of values to program into the CCRx for the channel you're using at each Update interrupt of the timer.

    If the value of the Period is 10000-1, then the sine table you create will need to be 5000 + 5000*sin(angle), a table with 10 degree increments would consist of 36 entries. At each interrupt you'd output the next value, incrementing a counter, and wrapping it based on the size of the table.

    ie

    void TIMx_IRQHandler(void) // Adapt for timer and channel under consideration
    {
      static int index = 0;
    
      if (TIM_GetITStatus(TIMx, TIM_IT_Update) != RESET)
      {
        TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
    
        TIMx->CCRx = sinetbl[index];
        index = (index + 1) % 36;
      }
    }
    

Children
More questions in this forum