While trying to configure the GPIOs using CMSIS on a NUCLEO-F103RB board, I couldn't seem to find in the reference manual how one is supposed to choose between internal pull-up and pull-down resistors.

Page 160 shows the configuration of the CNF and MODE bits and shows that the bits are the same for pull-up and pull-down. Searching the entire PDF file for "pull-up" and "pull-down" yields no results. The errata also has no mention of this.

Did ST seriously forget to put this information in the manual? If so, how come no one has noticed this? Or am I just being blind?

Anyway, looking at their standard peripheral library, it seems that writing a 1 to the corresponding bit in the GPIO BRR register activates the pull-down resistor, while writing a 1 to the BSRR actives the pull-up resistor:

    /* Reset the corresponding ODR bit */
    if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
      GPIOx->BRR = (((uint32_t)0x01) << pinpos);
      /* Set the corresponding ODR bit */
      if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
        GPIOx->BSRR = (((uint32_t)0x01) << pinpos);

This code can be found in the stm32f10x_gpio.c file.


2 Answers 2


The information you are looking for is in the manual, but not as obvious as it could be. The table you mentioned on page 160 contains more info:


As you can see, assuming the pin is configured as an input, the value in the ODR registers is the deciding factor as to whether the pin is pull-up or pull-down.

You can set and/or clear all these bits at once by writing a 16-bit value to the appropriate GPIOx_ODR register, or you can set/reset them individually by using the GPIOx_BRR and/or GPIOx_BSRR registers.

Interestingly, the same ODR register controls the pin state (high or low) when the pin is configured as an output.

I've found that I can sometimes learn more about the workings of the STM ARM controllers by reading through their Standard Peripheral Libraries than their reference manuals!

  • \$\begingroup\$ I like how it was right in front of my eyes and even though I looked at that table so many times I still couldn't see it. facepalm. Thank you. \$\endgroup\$
    – Chi
    Commented Jan 17, 2017 at 9:01
  • 1
    \$\begingroup\$ @Chi Ha! That happens to me more than I like to admit :) \$\endgroup\$
    – bitsmack
    Commented Jan 17, 2017 at 15:01

Hi the information from the pull-up input configured is here check this [![enter image description here][1]][1]
[1]: https://i.sstatic.net/CwAT3.png

enter image description here

The configuration could be:

#include "stm32f10x.h"              // Declaracion del Header
#define Clk_A   2

int main (){
RCC->APB2ENR|=(1<<Clk_A);       // Enable Clock to GPIOA
GPIOA->CRL=0x22220000;          // GPIO->A0:A3,Out A4:A7,in
GPIOA->CRL=0x22220000;          // GPIO->A7:A4,Out A3:A0,in
GPIOA->CRL|=0x8888;             // Pull-UP input A0:A3
GPIOA->ODR|=0x0F;               // Enable Pull UP A0:A3
while (1){
  • \$\begingroup\$ Hey Criss. I see you are new to the electrical engineering stack exchange, welcome :) Thank you for your answer but... this one has already been (correctly) answered almost 6 years ago. If you are unsure how stack exchange works, you can read the tour guide available here: electronics.stackexchange.com/tour \$\endgroup\$
    – Chi
    Commented Dec 7, 2022 at 7:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.