Can I measure PWM duty cycle using DMA?
I am on STM32F401 and I want to measure PWM duty cycle (PWM input) with timer 3 and a DMA channel. I'd like to have the DMA to do several measurements and then calculate the average over it. My configuration is like this:
My DMA config is like this:
My capture callback interrupt handler is:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
uint8_t cnt;
static volatile uint32_t PWM_ticks[PWM_input_buffer_size];
static volatile uint32_t tick_value;
// Get ticks differences
for(cnt = PWM_input_buffer_size-1; cnt >= 1; cnt--)
{
if(PWM_input_buffer[cnt] > PWM_input_buffer[cnt-1])
{
PWM_ticks[cnt] = PWM_input_buffer[cnt] - PWM_input_buffer[cnt-1];
}
else // counter roll-over occurred
{
PWM_ticks[cnt] = PWM_input_buffer[cnt] + (htim3.Init.Period - PWM_input_buffer[cnt-1]);
}
}
// Start PWM input via DMA - kick off next cycle
if(HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_2, PWM_input_buffer, PWM_input_buffer_size) != HAL_OK)
{
Error_Handler();
}
}
When I put a breakpoint in that routine I see this in the watch window:
To the timer 3 channel 2 I have connected a 100Hz PWM signal with 30% duty cycle as a test signal. I use a clock of 84MHz and have set the clock divider to 84-1 so that one tick is 1us. In the watch window the signal is reflected by the ~7000 (low time) and ~3000 (high time) counts, this is because I've set the polarity selection to 'both edges'.
I am interested in the high time only (duty cycle %) but if I set polarity selection to Falling edge I get only numbers around 10000 which is the full period (100Hz) and I don't understand this. I would expect numbers around 3000 (high time of the signal).
I expect the trigger to start the measurement but obviously it does not work like that. Can anyone explain how it works and if it is possible at all to measure only duty cycle in this way? (i.e. which changes are needed)
On the internet I can find a lot about PWM generation using DMA but not so much on PWM input.. :(