Hey,
I thought I will make in a short time a function that calculates the PWM duty cycle of a fixed PWM signal.
The following steps I made to implement this:
-Start an interrupt for the right port and pin
-If rising edge occurs start a LPTMR timer and set the interrupt to falling edge
-If falling edge stop the timer and calculate the duty cycle
My problem is that I use whole PORTA as interrupt. Therefore I tried "PORT_SetPinInterruptConfig" and "FGPIO_PortGetInterruptFlags" to read out the right pin. This code beneath doesn't work at all. It will not enter the IRQ. In "fsl_GPIO" you have functions with PORT and functions with PINS that is really confusing. When do you use what?
My setup is:
-NXP MKE14F512
-FreeRTOS operating system
-MCUXpresso 10.1.1
The used code is below and I also added some output data as attached file.
The function "Read_Pump" is called every 5 seconds
//Read in the PWM duty cycle of the pump and give back the duty cycle in %
/*-Set the interrupt of the pump pin to rising edge
*-Enable the interrupt of port A
*-In interrupt handler save timer value
*-If pulse was not started start timer and set pin interrupt to falling edge, remember timer has started
*-If pulse was started calculate duty cycle and store value
*/
void Read_Pump(void)
{
//Set the pump port pin to interrupt rising edge
PORT_SetPinInterruptConfig(GPIOA, 37U, kPORT_InterruptRisingEdge);
//Enable the interrupt
EnableIRQ(PORTA_IRQn);
}
void IRQ_HANDLER_PORT_A(void)
{
//uint32_t Interrept_Flags_A = FGPIO_PortGetInterruptFlags(PORTA_BASE_ADDRESS);
uint32_t Timer_Value = LPTMR_GetCurrentTimerCount(DEMO_LPTMR_BASE);
uint32_t flags = GPIO_GetPinsInterruptFlags(GPIOA);
DisableIRQ(PORTA_IRQn);
/* Clear external interrupt flag. */
GPIO_ClearPinsInterruptFlags(GPIOA, 37U << 7U);
if(Pulse_Started)
{
//Stop the timer
LPTMR_StopTimer(DEMO_LPTMR_BASE); //Stop the time
//Calculate the PWM duty cycle in %
Timer_Value = Timer_Value * 78125; //LPO clock is 128Khz 1/128Khz = 7,8125 us
Timer_Value = Timer_Value/1333333; //75Hz period time 1/75 = 13333,33 us
SUS_Data.Pump_In_Duty = Timer_Value; //Store PWM duty to local variable
Pulse_Started = false;
}
else
{
//start the timer and switch the interrupt flag to failing edge and make Pulse_Started True
LPTMR_StartTimer(DEMO_LPTMR_BASE); //Start the timer
PORT_SetPinInterruptConfig(GPIOA, 37U, kPORT_InterruptFallingEdge);
Pulse_Started = true;
EnableIRQ(PORTA_IRQn);
}
}
Hi
See chapter 7 of the following for methods of measuring PWM http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF
An optional technique using port DMA (possible on the KE14F) is also shown which achieves very high precision measurements of high frequency signals with no CPU overhead.
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
Kinetis KE1xF:
- http://www.utasker.com/kinetis/FRDM-KE15Z.html
- http://www.utasker.com/kinetis/TWR-KE18F.html
Free Open Source solution: https://github.com/uTasker/uTasker-Kinetis
Working project in 15 minutes video: https://youtu.be/K8ScSgpgQ6M
For better, faster, cheaper product developments consider the uTasker developer's version, professional Kinetis support, one-on-one training and complete fast-track project solutions to set you apart from the herd (with turn-key MCUXpresso/FreeRTOS solution) : http://www.utasker.com/support.html