There sure is! The STM32 is capable of ~18MHz GPIO toggle speeds. Check out my "High-Speed GPIO Access?" thread where we discuss it in much more detail. The short answer would be:
Access the GPIO's registers directly instead of going through the overhead created by the digitalWrite
function:
// D24 corresponds to PB9.
uint16_t bit9 = BIT(9);
GPIOB->regs->BSRR = bit9; // Set PB9
GPIOB->regs->BRR = bit9; // Clear PB9
It may be difficult to memorize the registers so libmaple has a built in lower-level gpio function:
gpio_write_bit(GPIOB, 9, 1); // Set PB9
gpio_write_bit(GPIOB, 9, 0); // Clear PB9
The only overhead of the gpio_write_bit
function is a single if-statement and a BIT
calculation. I created the following macros for my needs to remove the if-statement overhead:
#define sbit(port, pin) port->regs->BSRR = BIT(pin)
#define cbit(port, pin) port->regs->BRR = BIT(pin)
You can remove the BIT
.. bit, and pre-calculate the values ahead of time for slightly better performance.
Note that you won't get 18MHz out of the GPIO, but get very close to it. There are some quirks related to how fast you can toggle. If you do two GPIO accesses in a row you'll get lower performance than just doing a single one.. and a bunch of other little things. If you need to get faster performance you can unroll loops:
uint16_t bit9 = BIT(9);
for(int i = 0; i < 4; i++)
{
GPIOB->regs->BSRR = bit9; // Set PB9
GPIOB->regs->BRR = bit9; // Clear PB9
}
can be written as:
uint16_t bit9 = BIT(9);
GPIOB->regs->BSRR = bit9; // Set PB9
GPIOB->regs->BRR = bit9; // Clear PB9
GPIOB->regs->BSRR = bit9; // Set PB9
GPIOB->regs->BRR = bit9; // Clear PB9
GPIOB->regs->BSRR = bit9; // Set PB9
GPIOB->regs->BRR = bit9; // Clear PB9
GPIOB->regs->BSRR = bit9; // Set PB9
GPIOB->regs->BRR = bit9; // Clear PB9
removing the small "overhead" of executing the for-loop.
-robodude666