Calculate PWM duty and period time with FTM timer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Calculate PWM duty and period time with FTM timer

1,676 Views
rudycoppens
Contributor III

Hardware:

- MKE14F16

 

Software:

MCUXpresso IDE 10.1.1

I know that this is very simple with the dual capture mode on the chip with the FTM module, but I routed unfortunately the PWM input not on a FTM channel pin... But I thought you can just use a timer and the gpio controller to do the same with a simple counter/timer. 

I did the following:

- Start a FTM counter that will start from a rising edge on the pin and set the input to a falling edge trigger

- When falling edge read counter value and store it for the duty cycle and set input trigger on rising edge

- When rising edge read counter value again and store this value for the period time

- duty cycle / period time and you will have the duty cycle in percent what I want to have. 

My problem is that the counter reading is not constant. the duty cycle time is always very close to the period time and I have always a duty cycle reading higher than 90% even with an input pwm signal of 10%. The counter values are always different.... 

The input signal is 75Hz so that would not be an issue. In the program only Read_Pump() is called every 5 seconds with another timer. 

void Read_Pump(void)
{
   //Set the pump port pin to interrupt rising edge
   PORT_SetPinInterruptConfig(PORTA, 7U, kPORT_InterruptRisingEdge);
   //Enable the interrupt
   EnableIRQ(PORTA_IRQn);
}


void IRQ_HANDLER_PORT_A(void)
{
   uint32_t Interrupt_Flags_A = GPIO_PortGetInterruptFlags(GPIOA);

   if((Interrupt_Flags_A >> 7U) & 1)
   {
      GPIO_PortClearInterruptFlags(GPIOA, 1U << 7U);
      //Duty Cycle is over, store timer value in duty cycle
      if(Pulse_Started)
      {

         //Calculate the PWM duty cycle in %
         Duty_Time = FTM_GetCurrentTimerCount(FTM3);
         //Set the interrupt to rising edge to find the period time
         PORT_SetPinInterruptConfig(PORTA, 7U, kPORT_InterruptRisingEdge);
         Period_Over = true; //After a rising edge the period is over
         Pulse_Started = false;
         EnableIRQ(PORTA_IRQn);
      }
      else
      {
         //start the timer and switch the interrupt flag to failing edge and make Pulse_Started True
         FTM_StartTimer(FTM3, kFTM_SystemClock); //Start the timer
         PORT_SetPinInterruptConfig(PORTA, 7U, kPORT_InterruptFallingEdge);
         Pulse_Started = true;
         EnableIRQ(PORTA_IRQn);
       }
      if(Period_Over)
      {
         Period_Time = FTM_GetCurrentTimerCount(FTM3);
         FTM_StopTimer(FTM3); //Stop the timer
         float period = (float)Period_Time;
         float duty = (float)Duty_Time;
         float percentage = duty/period; //Calculate the percentage on of the period
         percentage = percentage*100;
         Period_Over = false;
         SUS_Data.Pump_In_Duty = percentage; //Store PWM duty to local variable
         DisableIRQ(PORTA_IRQn);
        }

   }

}

Labels (1)
0 Kudos
1 Reply

1,035 Views
mjbcswitzerland
Specialist V

Hi Rudy

See page 9 of the following http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF to see how any peripheral timer on the KE14 can be used to achieve extremely high PWM measurement accuracy (even for high frequency signals) using port DMA.

Regards

Mark


Kinetis: http://www.utasker.com/kinetis.html
Kinetis KE:
- http://www.utasker.com/kinetis/FRDM-KE02Z.html
- http://www.utasker.com/kinetis/FRDM-KE02Z40M.html
- http://www.utasker.com/kinetis/FRDM-KE04Z.html
- http://www.utasker.com/kinetis/FRDM-KE06Z.html
- http://www.utasker.com/kinetis/FRDM-KE15Z.html

0 Kudos