How to Turn on an LED with an STM32F407G Discovery Board in C

STM32F407G discovery board



In this article, we go over how to turn on an LED with an STM32F407G discovery board in C.

The STM32F407G discovery board comes with a STM32F407VGT6 microcontroller featuring 32-bit ARM® Cortex®-M4 with FPU core, 1-Mbyte Flash memory, 192-Kbyte RAM in an LQFP100 package.

The STM32F407G is a great board to use to do embedded programming because it comes with all the hardware needed to execute code on the board, including an ST-LINK/V2-A embedded debug tool. Therefore, with this board, no external debugging tools are necessary; everything is already on the board.

Turning on an LED in embedded programming is quite an involved task.

It requires a good number of steps in order to know how to set everything up.

You must know how to identify the GPIO port pin which the LED will be connected to.

Then you must activate the GPIO peripheral, which is done by enabling its clock. Until you enable the clock fo a peripheral, the peripheral is dead and enither functions nor takes any configuration values set by you. Only once you activate the clock for a peripheral are you then able to set configuration values and give control-related commands or arguments.

Then you must configure the GPIO pin mode as output. A GPIO pin, which is a general-purpose pin can function as input or output. Since we are looking to turn on an LED, in this case, our it must be set as output.

Then you must write to the GPIO pin. A 1 gives it a HIGH voltage (3.3V) to turn on an LED. A 0 gives it a LOW voltage to turn off the LED (0V).

The first thing we are going to do is turn on the user LEDs on the discovery board, which are the LEDs on the board that the user can manipulate.

There are 4 LEDs on the board which can a user can turn on or turn off.

If you look at the schematic for the STM32F407G discovery board, these LEDs are shown.



STM32F4discovery user LEDs

You can see that GPIOD, or port D, has all the user LED connections.

GPIOD pin 12 has a connection to the board's green user LED.

GPIOD pin 13 has a connection to the board's orange user LED.

GPIOD pin 14 has a connection to the board's red user LED.

GPIOD pin 15 has a connection to the board's blue user LED.

The great thing about first turning on these LEDs is that you don't have to add any external components, including the LED and the resistor. All of this already exists on the board. All you have to do then to test it out is the software.

We will show how to turn these user LEDs on.

Afterward, we will then connect our own LED to a port pin and turn the LED on.

So let's show the code how to turn on each of these LEDs.



We now will explain the code.

Within our main function, we declare 3 32-bit variables.

These variables are crucial and form the foundation for our code.

So the first variable is for the clock control register, so that we can enable the peripheral clock register.

The RCC, the Reset and Clock Control, for the board handles clock control.

According to the memory map, the base address for the RCC is, 0x4002 3800

So RCC forms the basis for all clock control and above is the base address for RCC.

What we want to do is enable the peripheral clock register, specifically for GPIOD.

The following image below helps us to navigate this.

RCC AHB1 peripheral clock enable register STM32F407G

Looking at the RCC AHB1 peripheral clock register, we see that this register has an address offset of 0x30. What this means is that we have to add the base address of RCC to this address offset of 0x30. This gives us a result of, 0x4002 3800 + 0x30, is 0x4002 3830.

This address gives us the address for the RCC AHB1 peripheral clock register, which is the register that allows us to work with the GPIOD port.

The only other thing we must do is set the clock register specifically to work with GPIOD. To do this, we must set bit 3 (4th bit) of the RCC AHB1 peripheral clock register to a HIGH value.

We do this in the line, *pClkCtrlReg |= (1 << 3);

This sets bit 3 to HIGH, which enables the peripheral clock register for the GPIOD port.

Next, we need to configure the GPIO port mode register.

The diagram below helps us to navigate this.

GPIO port mode register STM32407G

This is where we can configure pins of the port as input or output.

The base address for the GPIOD port is, 0x4002 0C00

The GPIO port mode register has an address offset of 0x00.

In order to turn on pin 12, we see that this register is a 32-bit register, and bits 24 and 25 correspond to bit 12 of the GPIO port.

As can be see in the MODE configuration bits, 00 makes the pin an input, 01 makes the pin an output, 10 gives an alternate function mode, and 11 makes the pin analog.

In this case, since we want to turn on an LED, we want to make pin 12 an output, so we want to set the bits 24 and 25 to 01.

This is done in the line, *pPortDModeReg |= (1 << 24);

The last register we have to configure is the GPIO port output data register. This allows us to write to a pin, making the pin either a HIGH state or a LOW state. This allows us to turn on or off a component.

The diagram below helps us to navigate this.

GPIO port output data register STM32F407G

The GPIO port output data register has an address offset of 0x14.

The base of the GPIOD port is, 0x4002 0C00

Adding 14 to 0x4002 0C00 gives us, 0x4002 0C14/

In order to write a HIGH state to pin 12, we use the line, *pPortDOutReg |= (1 << 12);

This writes a HIGH value to pin 12 of the GPIOD port. This turns on the user LED on the discovery board on pin PD12.

The last statement we have in our code is a while loop, which loops forever. This allows the LED to stay on. This will be the case unless the program is terminated.

And this is how we can turn on a digital device such as LED using the STM32F407G discovery board.

So again, in summary, you have to enable the peripheral clock register for the GPIOD port. First, you find the base address of RCC, which controls the clocks for the discovery board. You then find the RCC AHB1 peripheral clock register, which is the bus that the GPIO ports are connected to. You then add the address offset to the base RCC address to get the final address. To enable the peripheral clock register specifically for GPIOD, a 1 must be written to bit 3 (4th bit of the peripheral clock register).

Next, we must configure the GPIO port mode register. This allows us to select whether a pin (or pins) within the GPIO register will be an input or an output pin and whether the pin will be analog or not. You must note and use the base address of this GPIOD port. As there is no address offset, this base address serves as the address for the GPIO port mode register. Next, you just have to write 01 to pin 12 to make it an output pin.

Lastly, we must configure the GPIO port output data register, which allows us to write a HIGH or LOW value to a previously configured pin. We again use the base address for the GPIOD port. We must then add the address offset of the GPIO port output data register to this base address. We then need to write a 1 to the specific pin of the port, which in this case is bit 12.

A while loop simply keeps the LED on indefinitely.

We can repeat this for any other pin of the GPIOD port, as long as the configuration is set correctly.

Below we turn on LED 13, which lights an orange LED on the STM32F407G discovery board.



So we have similar code, except the code for *pPortDModeReg pointer and the *pPortDOutReg pointer.

Looking at the GPIO port mode register, pin 13 corresponds to the bits 26 and 27. Writing a 01 to these bits sets pin 13 as output.

Looking at the GPIO port output data register, pin 13 corresponds to bit 13, so we left shift a 1 to bit 13 to write a HIGH value to this bit. This will turn on the orange LED on the board.

Below we have the code to turn on pin 14, which turns on the red LED on the discovery board.



So we have similar code, except the code for *pPortDModeReg pointer and the *pPortDOutReg pointer.

Looking at the GPIO port mode register, pin 14 corresponds to the bits 28 and 29. Writing a 01 to these bits sets pin 14 as output.

Looking at the GPIO port output data register, pin 14 corresponds to bit 14, so we left shift a 1 to bit 13 to write a HIGH value to this bit. This will turn on the red LED on the board.

Below we have the code to turn on pin 15, which turns on the blue LED on the discovery board.



So we have similar code, except the code for *pPortDModeReg pointer and the *pPortDOutReg pointer.

Looking at the GPIO port mode register, pin 15 corresponds to the bits 30 and 31. Writing a 01 to these bits sets pin 15 as output.

Looking at the GPIO port output data register, pin 15 corresponds to bit 15, so we left shift a 1 to bit 15 to write a HIGH value to this bit. This will turn on the blue LED on the board.

Next we have code that turns on all 4 user LEDs. This is shown below.



Even though we could set all these pins as outputs in a single statement, it's probably easier to do it separately as combining pins leads you to spend time calculating values. To bypass this, it's probably easier just to set each pin as output separately, as well as write a HIGH value to each pin separately.

With the code above, all 4 user LEDs on the board turns on and stays on.

How to Turn On a Custom LED

So we've shown how to turn on LEDs on the STM32F407G discovery board .

Now we want to take it to the next level and be able to connect our own LED to the board and turn that on.

We will use the same GPIOD port.

But we will use a pin that isn't connected to an onboard LED, which is any pin other than pin 12, 13, 14, and 15. In this case, we will use pin 0 of GPIOD.

Below is the schematic diagram for the custom LED.

Custom LED circuit for a STM32F407G discovery board

The code to turn on this LED is shown below.



Since this is PD0, pin 0 of the GPIOD port, we set bit 0 as output and then write a 1 to bit 0.

This turns on the LED at PD0.

And this is how to turn on an LED with a STM32F407G discovery board in C.

Related Resources

How to Set Bits of a Number in C

How to Clear Bits of a Number in C



HTML Comment Box is loading comments...