In this short video, I will explain how to light up a LED by programming GPIO output
in the C language.
The STM32L4 reference manual and the schematic of STM32L4 discovery kit are two very helpful
documents for this tutorial.
The reference manual is long.
It has over 1600 pages.
However, the good thing is that you do not have to read it chapter by chapter.
Embedded system engineers need to learn how to navigate the reference manual to quickly
identify the relevant information.
This is the STM32L4 discovery kit.
Software can control two LEDs on board, including one red LED and one green LED.
The red LED is connected to the microprocessor pin PB2 via a resistor.
The green LED is connected to the pin PE8 via another resistor.
In this tutorial, we only focus on lighting up the red LED.
The process of lighting up the green LED is very similar.
To turn on the red LED, software has to set the pin PB2 to high.
To turn off the red LED, software has to set the pin PB 2 to low.
In this tutorial, I will show you how to set pin PB2 to high.
Each STM32L4 chip has eight GPIO ports, including port A, B, C, et cetera.
Each GPIO port can have up to 16 pins.
All pins in a GPIO port are controlled as a group.
Each pin can be configured by software at runtime to perform various functions.
The ARM Cortex-M4 processor core is connected to the other components via three buses, include
the data bus, the instruction bus, and the system bus.
These buses are connected to the Advanced high performance bus (AHB) matrix.
AHB is the backbone bus.
It is used for high-performance, high clock frequency system modules, such as on-chip
flash, on-chip SRAM, as well as GPIO modules.
The chip also has a bridge that connects AHB to Advanced Peripheral Bus (APB).
APB is for low bandwidth peripherals.
APB connects most of the peripheral devices in the system, such as UART, SPI, and timer.
Here is the basic structure of a GPIO module.
I will explain the details of this module in the next slide.
Most GPIO ports have 16 pins.
This diagram shows the standard structure of one GPIO pin.
It includes the basic structure for both digital input, and digital output.
In this lecture, I will only focus on the digital output part.
We will discuss the digital input in a separate lecture.
Here is the basic structure that is designed for digital output on one GPIO pin.
There are four important registers related to output, including the output data register,
the mode register, the data output type register, and the pull-up pull-down register.
In this slide, I only give a short overview of each registers.
Detailed discussion will be presented in the next few slides.
We can use the mode register to configure the pin as output.
The output type register sets the output pin as, either push-pull or open-drain.
The pull-up pull-down register specifies whether the pin is pulled up to a high voltage by
a resister, or the pin is pulled down to the ground via another resister.
When the pin is configured as output, the value written to the output data register
is output on the GPIO pin.
However, whether the pin has a high voltage output, a low voltage output, or a high impedance
output, depends on the configuration of the output type register, and the pull-up pull-down
register.
To improve energy-efficiency, the clock of most peripherals is turned off.
As presented previously, the red LED is connected to the pin 2 of port B. First of all, we need
to enable the clock of GPIO Port B.
The clock can be turned on or off by configuring the reset and clock control module (RCC).
Specifically, the clock of port B is controlled by the AHB2 peripheral clock enable register
(AHB2ENR).
We need to set bit 1, that is, GPIO B Enable Bit, of this register to 1.
When GPIO B Enable bit is 1, the clock signal can pass through this logic AND gate to drive
the port B. On the other hand, if GPIO B Enable bit is zero, the output of the logic AND gate
is always zero.
Accordingly, the port B has no clock input.
Software can set GPIO B Enable bit to 1 by using bitwise OR.
In order to make the code more readable, we use this macro to define this constant.
In fact, this macro has already been defined in the device header file.
Software can program each GPIO pin as one of the following four different functions.
First, digital input, which detects whether an external voltage signal is higher or lower
than a predetermined threshold.
Second, digital output, which controls the voltage on the pin.
Third, analog functions, which perform digital-to-analog, or analog-to-digital conversion.
Last, other complex functions, such as SPI data pin, and timer PWM output.
We call the last category of functions as alternative functions.
The function of a pin is controlled by the MODE register of this port.
Each mode register has 32 bits.
Port B has a total of 16 pins.
The function of each pin is determined by two bits of the mode register.
For example, bit 5 and bit 4 control the function of pin 2.
When these two bits are zero zero, the pin is set as digital input.
When these bits are zero one, this pin is used for digital output.
When they are one zero, the pin has alternative function.
Specific alternative function will be determined by the alternative function register of this
port.
When these two bits are one one, the pin will be used for analog-to-digital conversion (ADC),
or digital-to-analog conversion (DAC).
In this example, pin PB 2 will be used as output to turn on the red LED.
Therefore, we need to set bit 5 and bit 4 to zero and one, respectively.
Here is the C code.
First, we clear bit 4 and 5.
Then, we set bit 4 by using bitwise OR.
Next, we need to set the output of mode of Pin 2 as push-pull, instead of open drain.
Therefore, software has to clear bit 2 of the output type register.
In the following few slides, I will explain what is the difference between push-pull,
and open-drain.
A push-pull output consists of a pair of complementary transistors, as shown in this slide.
Only one of them is turned on at any time.
When the pin outputs logic one, the transistor connected to the power supply is turned on.
The other transistor is turned off.
It provides an electric current to the external circuit connected to the output pin, as shown
in the right figure.
When logic zero is outputted, the transistor connected to the ground is turned on.
The output pin can sink an electric current from the external circuit, as shown in the
right figure.
For the open drain, when software outputs a logic zero, the open-drain circuit can sink
an electric current from the external load connected to the GPIO pin.
However, when software outputs a logic one, it cannot supply any electric current to the
external load.
This is because the output pin is floating, connected to neither the power supply, nor
the ground, as shown in the right figure.
This table summarizes the difference between push-pull and open-drain.
Their difference is that, in the push-pull output, when the output data bit is one, the
output pin has a high voltage.
However, in the open-drain output, when the output data bit is one, the output pin is
floating, or has high impedance.
In this example, we need to provide a high voltage on the output pin in order to turn
on the LED.
Therefore, we have select the push-pull output, instead of the open-drain output.
The output data register is easy to understand.
This register has the upper 16 bits reserved.
It has 16 data bits, with one bit for each pin.
Because the red LED is connected to pin 2 to turn on the LED, we need to set bit 2 of
the output data register to 1.
This slide summarizes the software code, which can turn on the red LED.
The red LED is connected to pin 2 of port B.
The software involves four steps.
First, we turn on the clock to enable port B. Then, we set the mode of pin 2 of port
B as digital output.
Next, we select push-pull output, instead of open-drain output.
Finally, we set, bit 2, of the output data register to light up the red LED.
Please visit the book website for more examples and tutorials.