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);
}
}
}