2021-08-03 07:31 AM
I'm trying to align an input 15 kHz signal with a 20% duty cycle with an output 15 kHz signal with a 50% duty cycle. To do this I'm hooking up the input signal to a direct capture interrupt and Timer 1 Channel 4 and using the HAL_TIM_IC_CaptureCallback function to begin my PWM timer. In doing this I notice a significant delay of 6ms as shown in the picture below. I need the delay to be on the order of 1-2µs not 6ms. Is this possible using the STM32 L476RG operating at 80 MHz? Otherwise, what are some common solutions to meeting these kinds of timing requirements?
Here is my ISR for reference:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
if (num_pulses == 0) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, state);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
++num_pulses;
}
else if (num_pulses == 50) {
if (state = 0) {
state = 1;
}
else {
state = 0;
}
num_pulses = 0;
}
else {
++num_pulses;
}
}
}
Here is the delay on the logic analyzer:
Thank you!
Solved! Go to Solution.
2021-08-03 08:15 AM
There has to be something else going on. The IRQ delay isn't 6ms even with HAL overhead.
Are you sure the timer IC is ready at the time you start the other PWM signal?
Another way to do this would be to trigger the TIM2_CH1 to start when the other signal goes high. Look at the trigger slave mode for how to do this. You will still have some small fixed delay which you could eliminate by adjusting the starting CNT value.
2021-08-03 08:15 AM
There has to be something else going on. The IRQ delay isn't 6ms even with HAL overhead.
Are you sure the timer IC is ready at the time you start the other PWM signal?
Another way to do this would be to trigger the TIM2_CH1 to start when the other signal goes high. Look at the trigger slave mode for how to do this. You will still have some small fixed delay which you could eliminate by adjusting the starting CNT value.
2021-08-03 08:34 AM
How can I make sure the timer IC is ready? The only line of code I have outside of the default and ISR is HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_4) which I call in the main function before the loop. Here are my timer 1 settings:
The trigger slave mode seems like a solution but the only problem is I also have to set a GPIO pin high/low at the same time so I believe I need an ISR.
2021-08-03 08:41 AM
> How can I make sure the timer IC is ready?
Call HAL_TIM_IC_Start_IT before you start the PWM.
You can set a pin high using another channel of the timer using trigger slave mode.
2021-08-03 08:45 AM
I'm already doing that in the main function. Am I supposed to call it more than once?
2021-08-03 08:58 AM
2021-08-03 10:21 AM
Maybe your num_pulses isnt initialised to 0 , when for example 1 ...
2021-08-03 10:51 AM
Using the slave mode path, what type of Trigger Output (TRGO) should be used for an input capture timer? The only options are output capture ones.
2021-08-03 12:28 PM
It looks like "Compare Pulse (OC1)" is the correct selection here, but is only available on channel 1, at least on the chip I have up currently.
2021-08-03 12:39 PM
> Using the slave mode path, what type of Trigger Output (TRGO) should be used for an input capture timer? The only options are output capture ones.
Use "Compare Pulse" (0b11 in TIMx_CR2.MMS). It's incredibly badly named, but it sets TRGO to output a pulse whenever CC1IF is set, whether it's because of Input Capture or Output Compare. Only CH1 can be used for this purpose.
But you don't need to do that. As TDK said above, set up the timer for the PWM output but don't enable it in TIMx_CR1.CEN and connect the input signal to a channel which can trigger the Slave-mode controller set to Trigger mode (again, only CH1 and CH2 can be used). Set a third channel to Output Compare, Active on Match, and that will serve you as the pin which you want to set when the edge is detected.
JW