# GPIO Output Registers on the STM32

Hi I'm currently attempting to write a simple program using the STM32 Nucleo development board, based around the STM32F334R8. The application sets up the GPIO ports A and C and reads the state of the button. If the button is pressed, it turns on the LED. If not, it turns it off.

From ST's documentation (STM Nucleo 64) I've verified that the button is wired to Pin C13 and LED2 is wired to Pin A5.

From the datasheet, I've been reading through the registers for the GPIO (Long STM32F334 Datasheet) and see there are three that seem to be related to the output; ODR, BSRR, and BRR.

When implementing the application mentioned above, my first thought was to write the GPIO pin state for the output LED using ODR, like so:

SET_BIT(GPIOA->ODR, GPIO_ODR_5);
CLEAR_BIT(GPIOA->ODR, GPIO_ODR_5);


This did not appear to work. My button presses were detected, as I could verify this in the debugger by seeing it follow different paths. Here's my setup code for the GPIO:

// set one to input
CLEAR_BIT(GPIOC->MODER, GPIO_MODER_MODER13_0);
CLEAR_BIT(GPIOC->MODER, GPIO_MODER_MODER13_1);
// set another to output
SET_BIT(GPIOA->MODER, GPIO_MODER_MODER5_0);
CLEAR_BIT(GPIOA->MODER, GPIO_MODER_MODER5_1);
// set output to push-pull
CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_5);
// set input with pull-up
SET_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPDR13_1);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPDR13_0);

// enable GPIOA and GPIOC clock
SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);
SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOCEN);


I also saw a piece of example code that worked on my board that uses the BSRR and BRR bits, like so:

// set output high
SET_BIT(GPIOA->BSRR, GPIO_BSRR_BS_5);
// set output low
SET_BIT(GPIOA->BRR, GPIO_BRR_BR_5);


... But this didn't work.

I'm not sure I understand the difference between the three registers and their functions.

What are the use cases for each? Which one is suited to my application?

• @BertVano: Even if you wants to write multiple bits, BSRR is the way to go unless you want to write all of them. If e.g. you want to write bits 4-6, and newValue has no bits set other than those, thePort->BSRR = 0x00700000 | newValue;.will atomically update those bits without affecting any others. I wish chip vendors would settle on ways of supporting atomic bit manipulations of I/O registers that are shared among different functions, since providing such support globally at the hardware level costs very little. Instead of having each register latch the state of the input when... Jul 9, 2020 at 15:50