cancel
Showing results for 
Search instead for 
Did you mean: 

Having recently started with STM32 I am keen to get into programming in closer detail. Where can I find the "h" file defining the register list structure and the bit names as defined in the reference manual for the STM32F401RE ? see PIC24F32KA304 example

Graham1904
Associate II

0693W000000UHAXQA4.png

1 ACCEPTED SOLUTION

Accepted Solutions
KnarfB
Principal III

I'm using a different chip, but that doesn't matter much.

When creating a plain new Blinky project in STM32CubeIDE, the following folder structure is generated:

├───Core
│   ├───Inc
│   ├───Src
│   └───Startup
└───Drivers
    ├───CMSIS
    │   ├───Device
    │   │   └───ST
    │   │       └───STM32F0xx
    │   │           ├───Include
    │   │           └───Source
    │   │               └───Templates
    │   └───Include
    └───STM32F0xx_HAL_Driver
        ├───Inc
        │   └───Legacy
        └───Src

Register definitions belong to the vendor+MCU specific part of ARM CMSIS: Drivers\CMSIS\Device\ST\STM32F0xx\Include\stm32f042x6.h

The path may be slightly different when using other IDEs or command line build tools.

The definitions look a bit different, because no bit fields are used. Lets take a LED connected to GPIO Port B pin 3 for example. At first, port GPIOB must be switched on (which is typical for ARM devices):

RCC->AHBENR = RCC->AHBENR | RCC_AHBENR_GPIOBEN;

RCC (root clock complex) is an instance of type RCC_TypeDef at a fixed address RCC_BASE:

#define RCC                 ((RCC_TypeDef *) RCC_BASE)

Register AHBENR is defined as member of struct RCC_TypeDef in stm32f042x6.h:

typedef struct
{
  __IO uint32_t CR;            /*!< RCC clock control register,                                   Address offset: 0x00 */
  __IO uint32_t CFGR;       /*!< RCC clock configuration register,                            Address offset: 0x04 */
  __IO uint32_t CIR;        /*!< RCC clock interrupt register,                                Address offset: 0x08 */
  __IO uint32_t APB2RSTR;   /*!< RCC APB2 peripheral reset register,                          Address offset: 0x0C */
  __IO uint32_t APB1RSTR;   /*!< RCC APB1 peripheral reset register,                          Address offset: 0x10 */
  __IO uint32_t AHBENR;     /*!< RCC AHB peripheral clock register,                           Address offset: 0x14 */
  __IO uint32_t APB2ENR;    /*!< RCC APB2 peripheral clock enable register,                   Address offset: 0x18 */
  __IO uint32_t APB1ENR;    /*!< RCC APB1 peripheral clock enable register,                   Address offset: 0x1C */
  __IO uint32_t BDCR;       /*!< RCC Backup domain control register,                          Address offset: 0x20 */
  __IO uint32_t CSR;        /*!< RCC clock control & status register,                         Address offset: 0x24 */
  __IO uint32_t AHBRSTR;    /*!< RCC AHB peripheral reset register,                           Address offset: 0x28 */
  __IO uint32_t CFGR2;      /*!< RCC clock configuration register 2,                          Address offset: 0x2C */
  __IO uint32_t CFGR3;      /*!< RCC clock configuration register 3,                          Address offset: 0x30 */
  __IO uint32_t CR2;        /*!< RCC clock control register 2,                                Address offset: 0x34 */
} RCC_TypeDef;

Further down you find definitions of the bit position

#define RCC_AHBENR_GPIOBEN                       RCC_AHBENR_GPIOBEN_Msk        /*!< GPIOB clock enable */
#define RCC_AHBENR_GPIOCEN_Pos                   (19U)                         
#define RCC_AHBENR_GPIOCEN_Msk                   (0x1UL << RCC_AHBENR_GPIOCEN_Pos) /*!< 0x00080000 */

Next, GPIOB pin 3 must be defined as push-pull output and finally the output must be set to high for switching the LED on. That part is left for you as an exercise 😎.

A solution can be found here https://gitlab.com/stm32mcu/blinky_register-level

The STM32F0xx_HAL_Driver contains a higher level layer HAL (hardware abstrction layer). Its pros and cons are highly debated here.

hth

KnarfB

View solution in original post

2 REPLIES 2
KnarfB
Principal III

I'm using a different chip, but that doesn't matter much.

When creating a plain new Blinky project in STM32CubeIDE, the following folder structure is generated:

├───Core
│   ├───Inc
│   ├───Src
│   └───Startup
└───Drivers
    ├───CMSIS
    │   ├───Device
    │   │   └───ST
    │   │       └───STM32F0xx
    │   │           ├───Include
    │   │           └───Source
    │   │               └───Templates
    │   └───Include
    └───STM32F0xx_HAL_Driver
        ├───Inc
        │   └───Legacy
        └───Src

Register definitions belong to the vendor+MCU specific part of ARM CMSIS: Drivers\CMSIS\Device\ST\STM32F0xx\Include\stm32f042x6.h

The path may be slightly different when using other IDEs or command line build tools.

The definitions look a bit different, because no bit fields are used. Lets take a LED connected to GPIO Port B pin 3 for example. At first, port GPIOB must be switched on (which is typical for ARM devices):

RCC->AHBENR = RCC->AHBENR | RCC_AHBENR_GPIOBEN;

RCC (root clock complex) is an instance of type RCC_TypeDef at a fixed address RCC_BASE:

#define RCC                 ((RCC_TypeDef *) RCC_BASE)

Register AHBENR is defined as member of struct RCC_TypeDef in stm32f042x6.h:

typedef struct
{
  __IO uint32_t CR;            /*!< RCC clock control register,                                   Address offset: 0x00 */
  __IO uint32_t CFGR;       /*!< RCC clock configuration register,                            Address offset: 0x04 */
  __IO uint32_t CIR;        /*!< RCC clock interrupt register,                                Address offset: 0x08 */
  __IO uint32_t APB2RSTR;   /*!< RCC APB2 peripheral reset register,                          Address offset: 0x0C */
  __IO uint32_t APB1RSTR;   /*!< RCC APB1 peripheral reset register,                          Address offset: 0x10 */
  __IO uint32_t AHBENR;     /*!< RCC AHB peripheral clock register,                           Address offset: 0x14 */
  __IO uint32_t APB2ENR;    /*!< RCC APB2 peripheral clock enable register,                   Address offset: 0x18 */
  __IO uint32_t APB1ENR;    /*!< RCC APB1 peripheral clock enable register,                   Address offset: 0x1C */
  __IO uint32_t BDCR;       /*!< RCC Backup domain control register,                          Address offset: 0x20 */
  __IO uint32_t CSR;        /*!< RCC clock control & status register,                         Address offset: 0x24 */
  __IO uint32_t AHBRSTR;    /*!< RCC AHB peripheral reset register,                           Address offset: 0x28 */
  __IO uint32_t CFGR2;      /*!< RCC clock configuration register 2,                          Address offset: 0x2C */
  __IO uint32_t CFGR3;      /*!< RCC clock configuration register 3,                          Address offset: 0x30 */
  __IO uint32_t CR2;        /*!< RCC clock control register 2,                                Address offset: 0x34 */
} RCC_TypeDef;

Further down you find definitions of the bit position

#define RCC_AHBENR_GPIOBEN                       RCC_AHBENR_GPIOBEN_Msk        /*!< GPIOB clock enable */
#define RCC_AHBENR_GPIOCEN_Pos                   (19U)                         
#define RCC_AHBENR_GPIOCEN_Msk                   (0x1UL << RCC_AHBENR_GPIOCEN_Pos) /*!< 0x00080000 */

Next, GPIOB pin 3 must be defined as push-pull output and finally the output must be set to high for switching the LED on. That part is left for you as an exercise 😎.

A solution can be found here https://gitlab.com/stm32mcu/blinky_register-level

The STM32F0xx_HAL_Driver contains a higher level layer HAL (hardware abstrction layer). Its pros and cons are highly debated here.

hth

KnarfB

Graham1904
Associate II

Absolutely fantastic. Thank you so much for your answer and the detail you have gone to the explain the solution. I found my file as being STM32F401xE.h 🙂

Using the on-chip temperature sensor I couldn't understand why the compiler kept complaining about TSVREFE not being previously defined, now i know why as it is ADC_CCR_TSVREFE 🙂

I have learnt so much from your answer. Thanks again.