Hi,
In the GPIO configuration of the CubeMX output pins, you must set Maximum output speed: Very High,
when you want to get small switching times of the pins.
That's the first thing I did.
Have you thought about one-pulse mode of timer? Of course, if it can fit into rest of concept your app.
I did. The problem is that this particular processor doesn't seem to support it.
Your software controlled approach will be subject to the usual program timings such as clock rate, interrupt and branch overhead and optimisation level. You should be able to achieve timing to your clock resolution by setting up a timer and some comparators that are configured to switch GPIO directly.
Yes that's the first thing I tried but it seems that there is a lag somewhere else towards output pin registers.
Hi,
Why not use the hardware PWM modes for pulse generation ? You can set the frequency once & adjust duty cycles as you require.
Minimal software intervention & precise pulse widths.
You can route the PLLed SYSCLK to timer as its clock. Check the clocks config page in CubeMX .
AFAIK, you can also combine 2 16-BIT timers to form a 32-BIT timer, giving you more resolution.
CubeMX will also most probably enable High Speed Output drivers on PWM pins to reduce Rise/Fall times.
sam_des
HW PWM is not an option because I have to drive 3 bridges and there is only a single PWM which I use in different part of circuit for bucking converter.
Combining 2 timers might be a good idea I have to check that out.
Posted on: October 16, 2024, 08:22:45 20:22 - Automerged
In the meantime, this code seems to work somewhat better when I address directly the BSSR registers.
There is less variation between pulses but still in the range of a few hundred ns (the adjustment resolution is better though).
while(1) {
__asm volatile (
"LDR R0, =0x48000418 \n" // Load address of GPIOB->BSRR
"MOVS R1, #0x8000 \n" // Set bit for PB15 (0x8000)
"STR R1, [R0] \n" // Set PB15
"MOVS R1, #0x80000000 \n" // Reset bit for PB15 (0x80000000)
"STR R1, [R0] \n" // Reset PB15
);
}
I also tried running it from RAM with pretty much the same results.
attribute((section(".data"))) void Toggle_Pins_RAM(void) {
while(1) {
GPIOB->BSRR = GPIO_BSRR_BS15; // Set PB15
GPIOB->BSRR = GPIO_BSRR_BR15; // Reset PB15
}
What I failed to mention is that because I'm driving 3 full bridges I have to address 12 pins.
That said, the problem appears also when running just 2 pins for tests.
I got additional advice to turn on cache and prefetch but I'm yet to try this (I'm a bit sceptical but will see what happens).