GPIO Introduction: How to Read the Pins of a Microcontroller (MCX A153) and Control an LED (Japanese Blog) table of contents
Introduction
Understanding the pin configuration of the MCX A153 microcontroller
Settings for using GPIO
Check the relationship between the pins and the board (FRDM-MCXA153).
Demonstration: Perform GPIO settings and experience LED control.
Bonus: Understanding the "on/off" of LEDs
Bonus – What happens if you connect two LEDs in parallel?
Introduction
As a beginner in embedded systems development, I began learning about GPIO after receiving a request to write an article about it. This article is a record of what I learned and the insights I gained through trial and error while trying to light up a single LED.
This article explains how to use GPIO (General Purpose Input/Output), one of the most basic peripherals in microcontroller development.
GPIO is the foundation of embedded systems for connecting microcontrollers to external circuits, enabling functions such as turning on LEDs, reading the state of switches, and receiving signals from sensors.
On the other hand, in actual microcontroller development, "using GPIO" doesn't simply mean writing a program. Microcontrollers have numerous pins, and each pin is assigned functions other than GPIO, such as timers and communication interfaces.
Therefore,
To use GPIO, you need to understand the pin assignments and functions from the datasheet.
PinMUX (pin multiplex) settings for assigning GPIO to pins
Input/Output Direction Settings
This needs to be done properly.
This time, using the FRDM-MCXA153 as an example, we will examine the pin configuration of the MCX A153 and the mechanism of PinMUX, configure GPIO settings using Pins Tool, and finally demonstrate blinking LEDs connected to a breadboard.
Understanding the pin configuration of the MCX A153 microcontroller
The FRDM-MCXA153 is equipped with a microcontroller with the model number MCXA153VLH. This microcontroller uses an LQFP 64 package and has a total of 64 pins. Of these, 52 are available as GPIOs. The remaining pins consist of power terminals (VDD/VSS), USB terminals, and analog-only terminals, which cannot be used as GPIOs.
However, even though it has "52 GPIOs," this doesn't mean that 52 pins are dedicated to GPIO. Many of the pins available for GPIO use are shared with peripheral functions such as UART, SPI, I²C, and timers. Therefore, to actually use them as GPIOs, you need to use the PinMUX function to configure those pins to function as GPIOs. Let's check the pin configuration of the MCX A153 from the datasheet . A list of functions that can be assigned to each pin is provided starting on page 54.
For example, looking at the "Pinmux Assignment" for Pin Name: P1_8, there are six possible functions. GPIO is assigned to "ALT0 - P1_8". Other assignments include "ALT2 - LPUART1_RXD" which means it will be used as the UART receive terminal (RXD), and "ALT3 - LPI2C0_SDA" which means it will be used as the I²C data line (SDA).
As you can see, a single pin can be assigned to multiple functions, including not only GPIO but also UART, I²C, and timers.
Settings for using GPIO
1. Select pin function (PinMUX)
As confirmed in the previous section, P1_8 has several potential functions, including GPIO, UART, and I²C. However, the same pin cannot be used as both GPIO and UART simultaneously.
Therefore, typical microcontrollers are equipped with a mechanism called PinMUX.
PinMUX is like a toggle switch for connecting a single physical pin to an internal peripheral.
For example, P1_8 had six potential connection destinations. By selecting GPIO using PinMUX, P1_8 becomes available for use as a GPIO pin.
2. Set the electrical characteristics of the pins.
Pins can be configured not only for their function but also for their electrical behavior. Typical settings include:
• Pull-up
• Pull-down
Drive Strength
Open Drain
These are some examples. For instance, pull-up resistors are often enabled for switch inputs, and the drive strength may be adjusted when driving LEDs or high-speed signals. Even when used as GPIO, it is important to make appropriate electrical settings according to the application.
This article will omit a detailed explanation of these electrical characteristics.
3. Set the input/output direction of the GPIO.
The final step is determining the direction in which the signal flows. GPIO has two main operating modes.
• Input – Receives signals from the outside • Output – Sends signals to the outside
What exactly is happening inside the microcontroller when it comes to Input and Output?
The MCX A153 is a microcontroller that operates at 3.3V. Therefore, the GPIO pins basically handle two states: Low (approximately 0V) and High (approximately 3.3V).The A153 has an operating voltage range of 1.71V to 3.6V, and 3.3V is used for the FRDM board.
GPIO output values
Pin voltage
Low (0)
Approximately 0V
High (1)
Approximately 3.3V
For example, if you set a specific GPIO pin to Output and connect an external LED, setting it to High (approximately 3.3V) creates a potential difference between the GPIO and GND, allowing current to flow through the LED. Setting it to Low (approximately 0V) eliminates the potential difference with GND, so no current flows. In other words, the "blinking" of the LED is caused by repeatedly switching the voltage of the GPIO pin between High (1) and Low (0), alternating between blinking and being off. On the other hand, in Input mode, the microcontroller monitors the state of the GPIO pins. For example, if approximately 3.3V is input from an external circuit, it is recognized as High (1), and if approximately 0V is input, it is recognized as Low (0).
The pin function selection, electrical characteristic settings, and input/output settings described above can all be configured via a GUI using the Pins Tool (which is included in NXP's free Config Tools).
Check the relationship between the pins and the board (FRDM-MCXA153).
So far, we've learned that in order to use GPIO, you need to configure PinMUX settings and input/output direction settings.
Next, let's confirm where the MCU pins are connected on the FRDM-MCXA153 board, keeping in mind the demonstration we'll be performing.
Check the schematics and confirm where pin "P1_8", which was used as an example in the previous chapter, is routed.
Looking at page 8 of the circuit diagram, we can see that P1_8 is connected to D18 of Arduino header J2 on the FRDM-MCXA153.
FRDM-MCXA153 Schematics
So, where is D18 on the Arduino header J2?
Next, let's check the Board User Manual.
FRDM-MCXA153 Board User Manual
Page 6 contains a diagram of the connectors mounted on the board, which allowed me to identify the location of D18 on the Arduino header J2.
For this learning exercise, we will connect an external LED via a breadboard using the D18 pin. However, if you do not have a breadboard or LED, you can use the RGB LED mounted on the FRDM-MCXA153 board.
However, there is one point to note. When using the RGB LED on the board, the anode (+) of the LED is connected to VDD_BOARD (3.3V), and the cathode (-) is connected to GPIO. Therefore, unlike the externally connected LED mentioned earlier, setting GPIO to High (1) will also bring the GPIO voltage to approximately 3.3V, and the potential difference across the LED will almost disappear, causing the LED to turn off. On the other hand, setting GPIO to Low (0) creates a potential difference across the LED, causing current to flow and the LED to light up.
When you check each pin in the circuit diagram...
P3_12 is a red LED
P3_13 is a green LED
P3_0 is a blue LED
It supports these features. By configuring these PinMUX settings and input/output settings, you can also verify the operation using the LEDs on the board.
In this way, you can use the circuit diagram and the Board User Manual to check where the physical pins inside the microcontroller are connected on the board.
Demonstration: Perform GPIO settings and experience LED control.
In this chapter, we will use the Pins Tool in MCUXpresso Config Tools to configure GPIO and control an externally connected LED on a breadboard.
Equipment used in the demonstration: FRDM-MCXA153 Breadboard LED • Resistors and jumper wires
This demonstration will assume that you have already installed the MCUXpresso SDK and Config Tools in your VS Code environment.
*If you have not yet installed the MCUXpresso SDK and Config Tools, please refer to this blog post.
MCUXpresso Config Tools: How to Use the Pins Tool (Japanese Blog)
Note: While the blog post describes installing the SDK for FRDM-MCXN947, please install the SDK for FRDM-MCXA153 in this article.
I had a red LED and a green LED on hand, but I didn't know the part numbers, so I'll start by trying to light up the red LED. I had a 390Ω resistor. The forward voltage (Vf) of a red LED is generally 1.8~2.2V, so I'll assume it's 2.0V and calculate the current flowing through the LED.
The microcontroller's operating voltage is 3.3V. VfUsing 2.0V and a 390Ω resistor, the current value can be calculated using Ohm's law as follows. Note that LEDs have a specified maximum forward current (Ifmax), which is said to be 20mA for many general-purpose LEDs. Be careful with the resistance value, as currents exceeding 20mA may cause damage.
Furthermore, GPIO pins also have limitations on the current they can output. According to the datasheet, the MCX A153's electrical characteristics during normal operation are specified based on 4mA (6mA for High Drive pins). Therefore, when directly lighting an LED using a GPIO pin, you need to select a resistor value that takes into account not only the LED's current limit but also the GPIO's current limit.
Board and breadboard wiring
First, we'll do the wiring.
On the FRDM board, we will use "D18" and "14 GND" on the Arduino header J2 that we identified earlier .
The following diagram is based on the Board User Manual.
FRDM-MCXA153 Board User Manual
Please refer to the following video for wiring instructions.
(function() { var wrapper = document.getElementById('lia-vid-6405195304112w960h540r888'); var videoEl = wrapper ? wrapper.querySelector('video-js') : null; if (videoEl) { if (window.videojs) { window.videojs(videoEl).ready(function() { this.on('loadedmetadata', function() { this.el().querySelectorAll('.vjs-load-progress div[data-start]').forEach(function(bar) { bar.setAttribute('role', 'presentation'); bar.setAttribute('aria-hidden', 'true'); }); }); }); } }})(); (Show My Videos)
Importing sample code
Next, we will proceed to import the sample code from the FRDM-MCXA153 SDK.
Click "Import Example From Repository" in the panel on the left.
In the tabs displayed on the right, select the imported FRDM-MCXA153 SDK under "Repository" and select FRDM-MCXA153 under "Board". The template used is "driver_examples/gpio/gpio_led_output".
Select your desired Toolchain and click "Import".
Once the import is complete, it will be added to the Projects section in the left-hand panel.
Check the source code gpio_led_output.c.
This time, we want to configure GPIO input/output settings using Pins Tool, so we will remove the GPIO output setting code enclosed in the red box from the source code.
Configure GPIO settings using Pins Tool.
Next, open Config Tools. Right-click on the Project and select "Open with MCUXpresso Config Tools". After a short wait, Config Tools will launch.
Once Config Tools opens, first select Pins from Overview in the right-hand panel.
The Pins Tool is now open.
Enable pin P1_8.
Clicking on P1_8 will open another window as shown in the image below. Find "GPIO1:GPIO,8(P1_8)" in this window and check the box next to it.
When you check the box, the following window will appear, but you can close it by clicking No.
Once you've completed these steps, P1_8 will be added to the Routing Details at the bottom of the Pins Tool.
Next, change the GPIO input/output settings as follows.
Connect pin #38 (P3_12) from Output to Not Specified, and pin #2 (P1_8) from Not Specified to Output.
An error will occur in the GPIO initial state of #38, so please change it from Logical 0 to n/a.
Once you've completed these steps, you can rewrite the sample code. First, click Update Code in the upper left corner of the Config Tools screen.
A window will then appear. Here you can review the code changes as needed. Files that have been modified will have "change" written next to them.
When you return to VS Code, you will see three checkboxes at the top of the screen. Make sure they are checked and click OK.
After a short while, the changes to the source code will be completed.
Next, we will change the target of GPIO control in the source code gpio_led_output.c.
When you open gpio_led_output.c,
The following is stated:
while (1)
{
delay();
GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
}
Modify the contents of GPIO_PinInit() and GPIO_PortToggle() as follows:
Here, P1_8 is specified as the control target, and each time the function is called, the state of P1_8 switches between High (1) and Low (0).
while (1)
{
delay();
GPIO_PortToggle(GPIO1, 1u << 8);
}
Further details: GPIO pins are represented in the format Px_y, where x is the GPIO port number and y represents the bit position within that port. For example, P1_8 means "bit 8 of GPIO port 1".
In the code
GPIO_PortToggle(GPIO1, 1U << 8);
In,
GPIO1 1U << 8 represents GPIO port 1, is a bitmask where only the 8th bit is set to 1.
1U << 8
↓
0000 0001 0000 0000 (2進数)
This allows you to invert (switch between High and Low) only the 8th bit in GPIO port 1.
Connect the PC to the FRDM-MCXA153.
Debugging (build, write, and run the application).
Once the debugging process is complete, the program will have stopped at the breakpoint, so click the "|▶" icon at the top of the screen.
The LED will start blinking.
(function() { var wrapper = document.getElementById('lia-vid-6404528566112w304h540r105'); var videoEl = wrapper ? wrapper.querySelector('video-js') : null; if (videoEl) { if (window.videojs) { window.videojs(videoEl).ready(function() { this.on('loadedmetadata', function() { this.el().querySelectorAll('.vjs-load-progress div[data-start]').forEach(function(bar) { bar.setAttribute('role', 'presentation'); bar.setAttribute('aria-hidden', 'true'); }); }); }); } }})(); (Show My Videos)
Bonus – Understanding LED "on/off"
By the way, when does this LED light up, based on whether the GPIO outputs High (1) or Low (0)? Earlier I mentioned that it lights up when High (1) is output, but let's verify if that's true.
The following is the code we used earlier. The `while(1)` statement implies an infinite loop, repeatedly executing the code within the curly braces {}.
Additionally, delay() is a function for waiting for a certain period of time. GPIO_PortToggle() is a GPIO control function, so it inverts High (1) and Low (0).
while (1)
{
delay();
GPIO_PortToggle(GPIO1, 1u<<8); }
}
However, this code doesn't tell us whether the LED is lit when it's High (1) or Low (0).
Therefore, we use a different function, GPIO_PinWrite(), to explicitly control the state of the GPIO.
Specifically, the code will be changed to wait for one delay() call while in a High (1) state, and then wait for five delay() calls while in a Low (0) state. This should make the LED stay off for a longer period of time.
while (1)
{
GPIO_PinWrite (GPIO1,8U ,1);
delay();
GPIO_PinWrite(GPIO1,8U ,0);
delay();
delay();
delay();
delay();
delay();
}
Run the debug and click the "|▶" icon at the top of the screen.
(function() { var wrapper = document.getElementById('lia-vid-6404528052112w304h540r114'); var videoEl = wrapper ? wrapper.querySelector('video-js') : null; if (videoEl) { if (window.videojs) { window.videojs(videoEl).ready(function() { this.on('loadedmetadata', function() { this.el().querySelectorAll('.vjs-load-progress div[data-start]').forEach(function(bar) { bar.setAttribute('role', 'presentation'); bar.setAttribute('aria-hidden', 'true'); }); }); }); } }})(); (Show My Videos)
As intended, the LEDs were turned off for a longer period. This allowed us to verify that the LED outputs High (1) when it is lit and Low (0) when it is off.
To recap, when the GPIO goes high (1), the voltage at P1_8, which is set as the GPIO pin, becomes approximately 3.3V. A potential difference is created between this voltage and GND, causing current to flow through the resistor and the LED. At this time, a forward voltage (approximately 2.0V) is applied across the LED, and the remaining approximately 1.3V is applied across the resistor. As a result, the LED lights up.
On the other hand, when GPIO goes low (0), the voltage at P1_8 becomes approximately 0V. Since there is no potential difference between the GPIO pin and GND, no current flows, and the LED turns off.
If you think having a lot of `delay()` functions looks ugly, you can also use loop functions.
while (1)
{
GPIO_PinWrite(GPIO1, 8U, 1);
delay();
GPIO_PinWrite(GPIO1, 8U, 0);
for (int i = 0; i < 5; i++)
{ delay(); }
}
Bonus – What happens if you connect two LEDs in parallel?
I tried connecting a green LED I had on hand in parallel with a red LED.
Since the forward voltage (Vf) of a green LED is generally 2.0 to 2.2V, I assumed it to be 2.0V, similar to the red LED, and built the following circuit.
Since there was no need to change the pin settings, I debugged using the same code as before, and the red LED blinked, but the green LED did not. Why is that?
(function() { var wrapper = document.getElementById('lia-vid-6404530194112w304h540r514'); var videoEl = wrapper ? wrapper.querySelector('video-js') : null; if (videoEl) { if (window.videojs) { window.videojs(videoEl).ready(function() { this.on('loadedmetadata', function() { this.el().querySelectorAll('.vjs-load-progress div[data-start]').forEach(function(bar) { bar.setAttribute('role', 'presentation'); bar.setAttribute('aria-hidden', 'true'); }); }); }); } }})(); (Show My Videos)
LEDs have the characteristic that current starts flowing rapidly when the forward voltage (Vf) is exceeded. Therefore, if a red LED and a green LED are simply connected in parallel, the current will concentrate on the LED with the lower Vf, and the other LED may hardly light up at all. In this case, the Vf of the red LED is lower than that of the green LED, so the current is concentrated on the red LED.
When I actually measured the voltage across the LEDs with a tester, the red LED was 1.765V and the green LED was 1.766V.
At this voltage, the red LED can light up, but the green LED does not receive enough voltage to generate sufficient current. As a result, the red LED lights up, but the green LED does not light up because almost no current flows through it.
As shown above, simply connecting different types of LEDs in parallel can cause significant bias in current flow due to even small differences in forward voltage (Vf). Therefore, when connecting LEDs in parallel, it is common practice to install a current-limiting resistor for each LED. When adding resistors, you need to consider the GPIO current limit. If you simply add one more 390Ω resistor as we've been using and calculate the current, the calculated current applied to the GPIO will exceed 6mA. Therefore, to ensure the total current does not exceed 4mA, we connected two 680Ω resistors and built the following circuit.
When I debugged the same code again, both the red and green LEDs lit up.
(function() { var wrapper = document.getElementById('lia-vid-6405719291112w304h540r698'); var videoEl = wrapper ? wrapper.querySelector('video-js') : null; if (videoEl) { if (window.videojs) { window.videojs(videoEl).ready(function() { this.on('loadedmetadata', function() { this.el().querySelectorAll('.vjs-load-progress div[data-start]').forEach(function(bar) { bar.setAttribute('role', 'presentation'); bar.setAttribute('aria-hidden', 'true'); }); }); }); } }})(); (Show My Videos)
When the voltage across the LEDs was measured, the red LED was 1.750V and the green LED was 1.906V. By adding a resistor to each LED, the appropriate current was able to flow through each LED.
In this article, we've explained the "problems" and "stumbling blocks" encountered by a beginner in embedded development, from how to interpret various documents and use Config Tools to the operating principles of LEDs. We hope this will be helpful for those attempting to blink an LED for the first time using an NXP microcontroller.
=========================
We are currently unable to respond to comments left in the " Comment " section of this post . We apologize for the inconvenience, but please refer to " Technical Questions to NXP - How to Contact Us ( Japanese Blog ) " when making inquiries . (If you are already an NXP distributor or have a relationship with NXP , you may ask your representative directly.)
This article explains how to use GPIO (General Purpose Input/Output), one of the most basic peripherals in microcontroller development, using the blinking of an LED as an example.
GPIO is one of the first peripherals that many microcontroller developers learn about. Many people want to use GPIO to light up an LED, but they may not know how to read the datasheet or how to configure the pins. This article explains the basics of GPIO using the FRDM-MCXA153, aimed at beginners in microcontroller development. We will learn to read pin information from the datasheet and circuit diagram, configure settings using Pins Tool, and finally experience controlling an external LED.
(Estimated time: 15 minutes) *Assuming the development environment is already installed. MCUXpresso MCUXpresso Configuration Tools MCUXpresso IDE MCUXpresso SDK MCX Japanese Blog
View full article