http://embedded-lab.com/blog/stm32-gpio-ports-insights/
http://hertaville.com/stm32f0-gpio-tutorial-part-1.html
The libmaple libraries, on which STM32duino is based, provides access to registers by the syntax:
GPIOA->regs->REG
( sorry I cant find the link to the thread at the moment as I am posting from my phone)
– individual bits of the peripheral registers
– bit fields in peripheral registers
http://www.stm32duino.com/viewtopic.php … ing#p15081
In the first case the parameters are the register name and bit number. In the second case, the parameters are
– register name
– first bit number
– number of bits
Note: the bit number can go over 32 to make it easier to address bit fields that are stored in multiple 32 bit register words.
This method is the fastest way to access (read and write) peripheral register content. In addition, it is multi thread safe, when the mask based read-modify-write sequence is not.
Cheers, Ollie
Thanks.
I should get into the habit of trying to remember something unique in those sorts of posts, so I stand a better chance of finding them again.
In this case it would be “bit banding”
void setup() {
GPIOA->regs->CRL = (GPIOA->regs->CRL & 0x33333333) ; //set PA0-PA7 output
//Set A0-A7 (HIGH)
GPIOA->regs->ODR |= 0b0000000011111111;
}how i can use witd direct registers and port manipulation
stm32f103 series
void setup()
{
RCC_BASE->APB2ENR |= 0x10; // enable GPIOC clock
GPIOC->regs->CRH = (GPIOC->regs->CRH & 0xFF0FFFFF) | 0x00100000; // PC13 output push/pull (max speed 10MHz)
GPIOC->regs->CRH = (GPIOC->regs->CRH & 0xFF0FFFFF) | 0x00200000; // PC13 output push/pull (max speed 2MHz)
GPIOC->regs->CRH = (GPIOC->regs->CRH & 0xFF0FFFFF) | 0x00300000; // PC13 output push/pull (max speed 50MHz)
}
void loop()
{
GPIOC->regs->BSRR = 0x00002000; //PC13 = 1 (leave others unchanged)
GPIOC->regs->BSRR = 0x20000000; //PC13 = 0 (leave others unchanged)
GPIOC->regs->BSRR = 0x20002000; //PC13 = 1 (leave others unchanged - lower bits (set) have precedence over higher (clear))
GPIOC->regs->BRR = 0x00002000; //PC13 = 0 (leave others unchanged)
GPIOC->regs->ODR = 0x00002000; //PC13 = 1 (all others set to 0)
GPIOC->regs->ODR |= 0x00002000; //PC13 = 1 (leave others unchanged)
GPIOC->regs->ODR = 0x00000000; //PC13 = 0 (all others set to 0 too)
GPIOC->regs->ODR &= ~0x00002000; //PC13 = 0 (leave others unchanged)
}
int state = DDRC & B00000011;
and write
DDRC = state | (bx<<5) | (by<<2);
int state = DDRC & B00000011;
and write
DDRC = state | (bx<<5) | (by<<2);
The monotonic pin manipulations can be done with macros
#define gpio_clear(GpioPort, GpioPins) GpioPort->BSRR = ((GpioPins) << 16)
#define gpio_set(GpioPort, GpioPins) GpioPort->BSRR = (GpioPins)
These are the fastest way to do GPIO pin updates.
unsigned long time = micros();
for (uint32_t i = 0; i < 1000000; i++) {
GPIOA->regs->BSRR = 0b0000000000000001;
GPIOA->regs->BRR = 0b0000000000000001;
}
time = micros() - time;
the two measurements you got should be identical. the variation you saw is likely due to other factors and may go away if you run multiple trials.
edit:
as a test, I ran the following, to flip a pin using BSRR/BRR and tested speed for 1 million flips on a 48Mhz F103.
int main(void) {
int i;
mcu_init(); //reset the mcu
//systick_init();
coretick_init(); //reset coretick
//initialize the pins to outout
IO_OUT(LED_PORT, LED1 | LED2); //led1/2 as output @ 10Mhz
GPIO_DDR(LED_PORT, LED1 | LED2, 0x03); //led1/2 as output @ 50Mhz
IO_CLR(LED_PORT, LED1 | LED2);
ei(); //enable global interrupts
while (1) {
time0 = coreticks(); //time stamp
for (tmp=0; tmp < 1000000ul; tmp++) {FIO_SET(LED_PORT, LED2); FIO_CLR(LED_PORT, LED2);}
time0 = coreticks() - time0;
NOP();
};
}

![[SOLVED] Discovery STM32F100RB — Trouble with timers and library structure](https://sparklogic.ru/wp-content/uploads/2019/11/st-stm32vl-discovery-90x90.jpg)
