Firstly, apologies if this is in the wrong section. I could work out which seciton QN9080 questions should be in (Kinetis/Automotive/LPC/Wireless?)!
I am using the QN9080Dk development board and have been trying to set up a PWM with both varying frequency and period. I am trying to flash the LEDs on the board with the PWM, with a fixed on-time of 10 ms, but a frequency that varies with the angle measured from the on-board accelerometer (MMA8652). This is updated at 10 Hz.
I have tried several ways of doing this, but in every case (if I can get it to work at all), it works for a few seconds and then seems to "lock" either on or off. Whether the LED is left on or off seems random, but it doesn't recover.
All the parts I am using have come from the QN9080DK SDK. The program I working with is the lpc_i2c_read_accel_value_transfer demo project, with GPIO parts taken from gpio_led_output and the timer parts from simple_pwm.
I was initially using the CTIMER_SetupPwm function, but I wasn't clear whether I had to stop and start the PWM to use this. Stopping and starting the PWM didn't help the problem, so I took the CTIMER_UpdatePwmDutycycle function, copied it and modified it to update the duty cycle AND the period. I called this function CTIMER_UpdatePwm and it is below:
static void CTIMER_UpdatePwm(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent, uint32_t pwmFreq_Hz, uint32_t srcClock_Hz)
{
uint32_t pulsePeriod = 0, period;
uint32_t timerClock = srcClock_Hz / (base->PR + 1);/* Match channel 3 defines the PWM period */
period = base->MR[kCTIMER_Match_3];/* Calculate PWM period match value */
period = (timerClock / pwmFreq_Hz) - 1;/* Calculate pulse width match value */
pulsePeriod = (period * dutyCyclePercent) / 100;/* For 0% dutycyle, make pulse period greater than period so the event will never occur */
if (dutyCyclePercent == 0)
{
pulsePeriod = period + 1;
}
else
{
pulsePeriod = (period * (100 - dutyCyclePercent)) / 100;
}/* Update period */
base->MR[kCTIMER_Match_3] = period;
/* Update dutycycle */
base->MR[matchChannel] = pulsePeriod;
}
This works in the same way - i.e. it seems to work perfectly to start with and then freezes after a few seconds.
If I set the PWM going and don't try changing it, everything seems to work fine. It has been running on my desk for the last 45 minutes with no problem. Unfortunately I need it to change!
I assum I am doing something silly, but I can't find any information on the best way to update the PWM details on the fly and am tearing my hair out!
Thanks,
Andrew
Hi Andrew,
Sorry for the late reply.
By any chance, did you check the sctimer_update_dutycycle SDK example?
The process to update the duty cycle is the following:
-Disable SCTIMER interrupts.
-Update PWM with SCTIMER_UpdatePwmDutycycle function.
-Delay
-Enable SCTIMER interrupts.
I hope this helps.
Best regards,
Felipe
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Felipe, Thank you your response, I'm sorry i didn't come back sooner, I completely missed the notification of your response!
I will try what you suggest and see how it goes!
Thanks,
Andrew
I forgot to say, if required I can upload the enitre project.