This chapter will be about G
eneral P
urpose I
nput O
utput (GPIO
).
GPIO
module provides the ability to directly control the physical pins of the integrated circuit.
It provides a direct way of interfacing with the physical world.
We will be using the following terms:
PIN
: Is a single-bit input/output value mapped to a specific physical connection. Pins are defined by their port and number.PORT
: Most commonly Pins are divided into groups - PORTS. Pins in ports can share their configuration and are accessible from a single register. Pins within a single port might share possible configurations (e.g. interrupt configuration). Ports are labeled by an alphabetic character in your case.A PIN
can be fully identified by its port and number. For example, A5
where A
is port A
and 5
means the fifth pin of port A
.
GPIO
Pins can have only two different values
.
It is either a logical zero or a logical one. Logical 0
/1
is usually represented by a LOW
/HIGH
value on the signal pin (more in Preliminaries).
We strongly distinguish between the logical value of the GPIO
and the real signal value, as they are commonly configured to be inverted.
It is normal for GPIO
value to be changed over time, do not think about it as a constant.
GPIO
can serve as output from the MCU to the world, but can also work as input from the world to the MCU.
This means that it can be input
or output
, but commonly not both at the same time.
We call the direction of the signal mode
, most commonly this is configured by us during the initialization of the MCU and does not change.
There are exceptions to this, that is we can have bi-directional pins and change the configuration at runtime, but that is advanced usage.
Typically GPIO
is used to control simple devices: LEDs, a relay, or a simple motor.
Anything that can be controlled with binary information: ON
/OFF
.
When controlling LED, we commonly imagine that when a pin is in logical 1
the LED is ON
and when the pin is in a logical 0
the LED is off.
In input mode
, the pin tells us whenever a device is ON
or OFF
: a button or switch.
When working with a button, we can design it in a way that when a button is pressed, the value of the pin is 1
, when the button is released, the value of the pin is 0
.
FRDM K66F
uses inverted logic to control LEDs and buttons.
There is a rationale for this, and it comes from the way the real world operates, and the limitations of our MCU.
Our board uses pull-up/pull-down resistors to set the default states of the signal wires (more in Preliminaries). The most simple approach for this has the effect that the logical levels for LEDs and buttons became inverted.
There are multiple ways of connecting the LEDs, we are only interested in the approach used on our developer board.
The idea is that the VCC
of a LED is connected to the power rail and we use MCUs GPIO
to connect the LED to the GND of the board.
That has the following implications:
1
on GPIO, the GND of the LED is not connected to the GND of the board and the LED is not shining.0
on GPIO, the GND of the LED is connected to the GND of the board and the LED is shining.Buttons just connect a circuit when the button is pressed. We have to use that to design a reliable way to read whenever the button was pressed in the MCU.
What is done in our case is that there is a pull-up between the MCU and the button, and GND
is connected to the other pin of the button.
When the button is not pressed, the pul-up is the cause of a HIGH
value on the signal wire.
When the button is pressed, the value becomes LOW as it is directly connected to the GND
.
That directly translates into logical 1 when not pressed and logical 0 when pressed.
Motivation for that can be seen by comparing with an alternative.
Instead of a pull-up, one could just connect the pin of the MCU to the button and connect the button itself to VCC
.
If the button is not pressed, VCC
would be disconnected from the pin, if the button is pressed, VCC
would be connected to the pin.
The problem with that is that the signal wire is actually in an undefined state in case the button is not pressed.
There is no element that would tie the state of the signal wire to either low or high.
That can cause the wire to randomly charge itself to a HIGH
value due to electromagnetic fields around it.
A pull-up resistor prevents that effect by constantly charging the signal wire between the pin and the button to a HIGH
value - a fully defined state.
Buttons are mechanical devices by nature, and if you model them correctly you are working with something that looks like a metal spring. When the button is pressed, the circuit is not closed instantly, but rather we observe a bouncing effect: For an extremely small amount of time the circuit closes, then opens, then closes … until it stabilizes on being closed.
Problem is that the MCU is fast enough to notice these temporal states. From the perspective of the MCU, the bouncing of the circuit may seem like multiple really fast presses of the button in a row.
Some of our proposed solutions could be used to solve this problem:
25.10.2022 - Changed signal rail
to signal wire