How to Create a C Structure of a Register Map of an STM32 Microcontroller

STM32F407G discovery board

In this article, we show how to create a C structure of a register map for a particular component in an STM32 board, so that we can reference various elements on the board.

There's different ways to reference elements of an STM32 board.

One way is you can directly reference everything by the address.

You can go to the datasheet of the STM32 microcontroller you are working with and look up the address for everything in the memory map section of the datasheet.

For example, in the STM32F407G discovery board, the base address of the GPIO port A is 0x4002 0000

If you then want to access the output speed register for GPIO port A, this has an address offset of 0x08

This means that the address to access the GPIO port output speed register is 0x4002 0008

You can then create a pointer variable such as *pGPIOA_output_speed_register and then initialize this variable to, 0x4002 0008

You can then set the value the value to initialize the speed of a particular pin of GPIO port A.

However, there is another way of doing it.

Instead of looking up the address of each register in order to reference it, you can create a C structure that contains all of the registers for a given port such as GPIO registers.

This is the best practice way of referencing elements of an STM32 board.

Below is the GPIO register map of the STM32F407G board.

GPIO register map of an STM32F407G board

So you can see it has quite a number of registers.

It, in fact, has 10 different registers, many of which we may have to reference in order to initialize for any various program that we write.

Instead of looking up all of the addresses for each of these registers and manually assigning these addresses to variables we create, we can instead create a C structure that contains all of the GPIO registers (all of the registers that belong to the GPIO ports).

We do this in the C code below.

What you want to do is you want to create a separate header file and it's good practice to name this file by the STM32 board you are working with. For example, if I am working with the STM32F407xx board, I can name this file, stm32f407xx.h

Inside of this file, I will put the C structure that contains all of the GPIO registers.

Below is the contents of the stm32f407xx.h file.

So let's now go over the code.

So first we create a number of C macros, which contain the address of various peripheral buses.

We then create more C macros, which contain the base address of all of the GPIO registers.

We then create our C structure, which represents all of the registers of the GPIO ports.

As best practice, you want all of these registers to be volatile, as they may be subject to frequent change within a program. All of these registers are 32-bit registers, so we initialize them with uint32_t.

As you can see, we follow the GPIO register map. You must put everything in order, as is displayed in the memory map.

The first register of the GPIO port registers is the Mode register. This has an address offset of 0x00. This register must come first or else the structure will be wrong.

The second register is the OTYPER register, or the Output Type register. This register has an address offset of 0x04. This register must come next, as order is vital for a C structure representing registers.

The third register is the OSPEEDR register, or the Output Speed register. This register has an address offset of 0x08.

Notice how each subsequent register increases by an address offset of 4. This is because each register is composed of 4 bytes (32-bit registers).

You can know which register is next by the increment of 0x04 in the address offset.

So this continues in our program all the way down to the register, AFRH.

We refer to this C structure as, GPIO_RegDef_t

This is a fitting name, because it forms the register definition for each of the GPIO ports.

As good practice, we then create more macros and initialize each of the GPIO ports.

(GPIO_RegDef_t*) represents the pointer to this general structure we created. We then have to initialize each of the ports with their respective base addresses.

Once we do this, we create pointer variables for each of the GPIO ports using the C structure we created. This is very important as these pointer variables is what we'll use in our main C program to reference each of the GPIO port pins.

We are now finished creating our C structure.

Now we can go to our main C program and now use this structure that we have created.

The code below is an example of this.

So one of the most important things is you must include the header file at the top of the C program. Otherwise, the C structure you created will not be tied in with your program.

If it states that the file is not found, then you must include the path for it, so that it can be found.

We then have our main function.

We now can reference any register of any GPIO port and set set any register equal to any value as we need to for our program to work.

So this is how to create a C structure that mimics registers of a particular port in an STM32 microcontroller board.

Related Resources

HTML Comment Box is loading comments...