C Structure Code of thes SYSCFG Register Map of an STM32F407xx Microcontroller Board

STM32F407G discovery board



In this article, we show the C structure code of the SYSCFG register map of an STM32F407xx microcontroller board, so that we can reference each of the SYSCFG registers.

We then will be able to do things such as select specific GPIO port pins as sources of external interrupts.

This code can go into the device specific header file.

Instead of looking up the address of each of the SYSCFG registers in order to reference them, you can create a C structure that contains all of the SYSCFG registers.

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

Below is the SYSCFG register map of the STM32F407xx board.


SYSCFG register map of an STM32F407xx microcontroller board


So you can see it has quite a number of registers, many of which we may have to reference in order to initialize values for any of the various programs 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 SYSCFG registers.

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 SYSCFG registers.

Below is the contents of the stm32f407xx.h file.





So let's now go over the code.

So first we create a C macro, which contain the base address of the SYSCFG registers.

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 SYSCFG register map. You must put everything in order, as is displayed in the memory map.

The first register of the SYSCFG port registers is the MEMRMP register, or the SYSCFG memory remap 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 PMC register, or the SYSCFG peripheral mode configuration 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 EXTICR1 register, or the SYSCFG external interrupt configuration register 1. 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.

In a register map, every subsequent register should be 4 bytes apart from the previous register. This is because each register is 32 bits (4 bytes) in size. Notice that the register, EXTICR4, is at the address, 0x14. And then you notice the next register, CMPCR, is at the address 0x20.

0x14 is 20 in decimal

0x20 is 32 in decimal

So in between register EXTICR4 and register CMPCR are 2 reserved registers (at addresses 0x18 and 0x1C).

Therefore, we must put these reserve registers in the code. If you don't, the address representing the location of the register, CMPCR, will be incorrect.

We create an array called RESERVED1[2], representing that there are 2 reserve registers.

So when examining a register map for a 32-bit register MCU, you should always check to see there is a subsequent displacement of 4 bytes in between registers. If not, you must put reserve register(s) in between.

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

We refer to this C structure as, SYSCFG_RegDef_t

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

(SYSCFG_RegDef_t*) represents the pointer to this general structure we created. We then have to initialize this definition to the base address of the SYSCFG registers.

This is done through the following line, SYSCFG_RegDef_t *pSYSCFG= ((SYSCFG_RegDef_t*)SYSCFG_BASEADDR);

Now we can use this pSYSCFG pointer variable in our C program to be able to reference any of the SYSCFG registers.

Next we have the line, #define SYSCFG ((SYSCFG_RegDef_t*)SYSCFG_BASEADDR)

This just allows us to have a macro version of the SYSCFG pointer variable.

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 of the SYSCFG registers and set set any register equal to any value as we need to for our program to work.

In this code in this example, we set pin 0 of GPIO Port A as the source of an external interrupt, along with pin 13 of GPIO Port D.

So this is the C structure code of the SYSCFG register map of an STM32F407xx microcontroller board.



Related Resources





HTML Comment Box is loading comments...