GPIO - theory version

Contains lots of ELEC 3300 materials that you might not understand yet

Authors

Joseph Lam, Binay Gurung, Anshuman Medhi (Grand grand seniors)

Modified by: Alex Chan, Leo Wong, Christopher Kwan

What is GPIO?

A general-purpose input/output (GPIO) is an digital signal pin on an integrated circuit or electronic circuit board whose behavior — including whether it acts as an input or output — is controllable by the user at run time.

In short, GPIO is for outputting and reading HIGH [1] and LOW [0] values. (Sometimes we will use GPIO for analogue values but don't worry about that for now)

GPIO Configuration

  • Every pin on the MCU can be used as GPIO, they are divided into a blocks of 16 pins due to internal structure

    • Each block is named by letters: GPIOA, GPIOB, GPIOC...

      • Each pin within the block is numbered from 0: GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2...

  • So every pin is referred to by a pair of values: the port and the pin: GPIOE, GPIO_PIN_3 or when humans are talking we say PE3

Macros for GPIO

We will often use #define to give more meaningful names to the ports and pins, for ease of use:

/* main.h */
#define UP_BTN_GPIO_Port     GPIOE
#define UP_BTN_Pin           GPIO_PIN_3
#define LED1_GPIO_Port       GPIOE
#define LED1_Pin             GPIO_PIN_4
#define LED2_GPIO_Port       GPIOE
#define LED2_PIN             GPIO_PIN_5
#define LED3_GPIO_Port       GPIOE
#define LED3_PIN             GPIO_PIN_6
  • These defines are generated when you generate the HAL library from STM32CubeMX. You may change it at anytime to suit your need.

Initialization of GPIO (HAL Library Style)

Any hardware that you want to use must be first initialized. This is basically setting it up so it can work they way you want it to.

  • HAL library help you initialize the GPIO when the code is generated from STM32CudeMX. Inside the function MX_GPIO_Init

* Various GPIO Mode and GPIO Pull options

  • It seems there are various modes and pulls in the initialization, right? In Gerneal, you actually only need to know 4 of them - GPIO_MODE_INPUT, GPIO_MODE_OUTPUT_PP, GPIO_PULLUP, GPIO_PULLDOWN.

Input : GPIO_MODE_INPUT

  • GPIO_PULLUP and GPIO_PULLDOWN- The GPIO Pin can be used to read the logical value of the pin

    • The point is to deal with the secret 3rd state of binary digital signals: floating pins.

    • What happens when a pin is connected to nothing at all?

      • Noise will cause you to read a mostly random value

      • Therefore, The pull-up or pull-down gives a "weak" connection from the pin to either a high or low voltage. It gives a defined value to a floating pin while being weak enough to be easily overridden by any external signal.

Pull-up & Pull-down

when the GPIO is connected to a pull up resistor] when the GPIO is connected to a pull down resistor

One of the two set-ups here will read a high voltage when the button is on and low voltage when the button is off, while the other one is the opposite, can you tell which is which and why?

  • keywords : short circuit, potential divider

Output : GPIO_MODE_OUPUT_OD and GPIO_MODE_OUTPUT_PP

  • GPIO_MODE_OUPUT_OD and GPIO_MODE_OUTPUT_PP - The GPIO Pin can be used to output a digital signal using a pair of switches (see figure below)

    • Push-pull(PP) uses the 2 switches to connect the pin to either high voltage or low voltage, it pushes or pulls the voltage to the level assigned

    • Open-drain(OD) is similar but does not use the upper switch, thus it outputs a low voltage or completely disconnects the pin

  • GPIO_MODE_AF_PP & OD are the same but are for when the pin output is to be controlled by another bit of hardware, don't worry about it for now

Inside the MCU lives a pair of switches, ie.transistors:

Reading GPIO Input in the Program

The HAL_GPIO_ReadPin function reads the GPIO input.

  • The HAL_GPIO_ReadPin functions returns 1 or 0 of that respective pin of the parameter.

Readability:

  • Writing HAL_GPIO_ReadPin(XXX_GPIO_Port, XXX_Pin) every time may seem tidious. However with the help of magical c prepocessor, we can make it easier

Writing GPIO Output in the Program

The following macros can be found in main.h

  • The gpio_set(gpio) macro sets the GPIO pin to be 1.

  • The gpio_reset(gpio) macro resets the GPIO pin to 0.

  • The gpio_toggle(gpio) macro toggles the GPIO pin. (i.e. changes the GPIO pin state to 1 if it was originally 0 and vice versa)

Examples:

Full Example (Flickering the LED1 for every 500 ticks)

Even More Readability:

Writing gpio_set(LED1) is still not very readable because you don't know if it is turning on/off the LED1.

Writing gpio_read(BTN1) is also not very readable because you don't know if gpio_read(BTN1) == 1 is pressed or gpio_read(BTN1) == 0is pressed.

So, we defined some more macro functions in main.h for more readability:

If one day your hardware groupmate accidentally swapped the wires of all LEDs or buttons, you can simply change the defines above. You don't need to read through your hundreds/thousands of lines of code and change every gpio_set() gpio_reset() you wrote.

Simplest uses for GPIO

  • There are 3 LEDs and 2 Buttons on the board.

LEDs
Buttons

Thinking Time:

What should the GPIO Mode and Pull be for each of the above and why?

There are few step before using GPIO pins in your program:

  1. Find which GPIO you want to use in main.h (if you can't find one, define it yourself)

  2. Initialize the GPIO Pin once in gpio.h. Remember which mode and pull you need for the pin

  3. Use the GPIO Functions to read or write the digital signals

Button Example

Last updated