cancel
Showing results for 
Search instead for 
Did you mean: 

where can I find the register addresses for STM32L476RG?

MFaun.1
Associate II

Hi,

I have a STM32L476RG board and I try to execute the following program, obtained from this web http://www.microdigitaled.com/ARM/STM_ARM/Code/Ver1/Chapter02/Program2-1.txt which is for a different Nucleo 64 board (STM32F446RE)

/* p2_5.c Toggle Green LED (LD2) on STM32F446RE Nucleo64 board at 1 Hz
 *
 * This program toggles LD2 for 0.5 second ON and 0.5 second OFF.
 * It is identical to Program 2-2 but was written without using
 * the header file. The registers are defined locally in the file.
 *
 * This program was tested with Keil uVision v5.24a with DFP v2.11.0
 */
 
#define RCC_AHB1ENR (*((volatile unsigned int*)0x40023830))
#define GPIOA_MODER (*((volatile unsigned int*)0x40020000))
#define GPIOA_BSRR  (*((volatile unsigned int*)0x40020018))
 
void delayMs(int n);
 
int main(void) {
    RCC_AHB1ENR |=  1;              /* enable GPIOA clock */
    
    GPIOA_MODER &= ~0x00000C00;     /* clear pin mode */
    GPIOA_MODER |=  0x00000400;     /* set pin to output mode */
    
    while(1) {
        GPIOA_BSRR = 0x00000020;    /* turn on LED */
        delayMs(500);
        GPIOA_BSRR = 0x00200000;    /* turn off LED */
        delayMs(500);
    }
}
 
/* 16 MHz SYSCLK */
void delayMs(int n) {
    int i;
    for (; n > 0; n--)
        for (i = 0; i < 3195; i++) ;
}

I can compile and load the file to the board but it does not turn on green led, and it doesn't matter if I press the switch,

I guess that the problem is that both boards have different memory sizes and adddresses for registers (lines 10-12) or maybe led and switch is connected to different port and pin in my board, but: I do not know where to find the addresses and pins where onboard led and switch are connected

Where can I find this info?

thanks in advance

Marcos

1 ACCEPTED SOLUTION

Accepted Solutions

> which pin and port are connected the user led and switch?

Yes the Nucleo UM is not the example of well-executed document,. but generally the schematics for the STM32 devboards are quite well usable. (Maybe that's why ST does put them into the new devboards' UMs...)

0693W000000UR5mQAG.png

JW

View solution in original post

14 REPLIES 14
berendi
Principal

This is not recommended practice. Specifying register addresses manually is very prone to errors, and makes it harder for the compiler to optimize code.

If you still want to do it, search for "register boundary addresses" in the reference manual for the base address of each peripheral, and the "register map" section at the end of each chapter for the register offsets from the base address.

Generally a combination of Data Sheet and Reference Manual. Can also dig out from the include files, or printf of pointer addresses.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

hi,

first of all, thanks for your answer.

IMHO if you want to work with different fabricant boards, which is not good practice is to use CubeMX, because:

  1. I guess that strategy makes you fully lost when dealing with other fabricants.
  2. the software is updated from time to time. For instance, the version that I downloaded is quite different from the version you see in the STM MOOC videos.
  3. And last but not least, these register addresses are only required to know in your first project. You can re-use them for ever and ever in your future projects without problems.

Anyway, I still need to know the port and pin where onboard switch and led are connected. The sheet included in the package is not very informative, and the info in STM, again, is not easy-to-find.

The reference manual and the datasheet cover the microcontroller only. You can find the register addresses, pinouts, but whatever the board makes has put on the board is outside the scope of these documents.

Boards made by ST have a product page on the website, where you can access the board user manual under resources / technical documentation, and there should be a board schematics either included in the user manual, or provided as separate document on the same page.

Boards made by third parties might or might not come with schematics, contact the distributor or the manufacturer if you can't find it.

hi, yes, I agree, as a general rule, it doesn't matter the fabricant or the model there are manuals and info should be there. Even if you buy a microwave oven or a FM radio. But now I am interested in my specific case, not the general receipt. I cannot find the info. This is my board, which is official https://www.st.com/en/evaluation-tools/nucleo-l476rg.html#

but the documentation is a mesh of specific parts related to my precise model as well as general info, and so far, I was unable to find this simple info: in which pin and port are connected the user led and switch?

> which pin and port are connected the user led and switch?

Yes the Nucleo UM is not the example of well-executed document,. but generally the schematics for the STM32 devboards are quite well usable. (Maybe that's why ST does put them into the new devboards' UMs...)

0693W000000UR5mQAG.png

JW

MFaun.1
Associate II

Hi,

finally I succeed thanks to this nice page with addresses for different microcontrollers http://libopencm3.org/docs/latest/stm32l4/html/modules.html

The difference of my board (STM32L476RG)  with the other board (STM32F446RE) is that clock activation is with RCC_AHB2ENR and not with RCC_AHB1ENR

this is my code with direct register definition (more definitions than required for future extensions)

/* p2_5.c Toggle Green LED (LD2) on STM32F446RE Nucleo64 board at 1 Hz
 *
 * This program toggles LD2 for 0.5 second ON and 0.5 second OFF.
 * It is identical to Program 2-2 but was written without using
 * the header file. The registers are defined locally in the file.
 *
 * This program was tested with Keil uVision v5.24a with DFP v2.11.0
 */
 
 
/* --- STM32 specific peripheral definitions ------------------------------- */
 
/* Memory map for all busses */
#define PERIPH_BASE                     (0x40000000U)
#define FMC1_BANK_BASE                  (0x60000000U)
#define FMC3_BANK_BASE                  (0x80000000U)
#define QUADSPI_BANK_BASE               (0x90000000U)
#define FMC_QUADSPI_BASE                (0xA0000000U)
#define INFO_BASE                       (0x1fff0000U)
#define PERIPH_BASE_APB1                (PERIPH_BASE + 0x00000)
#define PERIPH_BASE_APB2                (PERIPH_BASE + 0x10000)
#define PERIPH_BASE_AHB1                (PERIPH_BASE + 0x20000)
#define PERIPH_BASE_AHB2                (0x48000000U)
 
/* AHB2 */
#define GPIO_PORT_A_BASE                (PERIPH_BASE_AHB2 + 0x0000)
#define GPIO_PORT_B_BASE                (PERIPH_BASE_AHB2 + 0x0400)
#define GPIO_PORT_C_BASE                (PERIPH_BASE_AHB2 + 0x0800)
#define GPIO_PORT_D_BASE                (PERIPH_BASE_AHB2 + 0x0c00)
#define GPIO_PORT_E_BASE                (PERIPH_BASE_AHB2 + 0x1000)
#define GPIO_PORT_F_BASE                (PERIPH_BASE_AHB2 + 0x1400)
#define GPIO_PORT_G_BASE                (PERIPH_BASE_AHB2 + 0x1800)
#define GPIO_PORT_H_BASE                (PERIPH_BASE_AHB2 + 0x1c00)
 
#define GPIOA                           GPIO_PORT_A_BASE
#define GPIOB                           GPIO_PORT_B_BASE
#define GPIOC                           GPIO_PORT_C_BASE
#define GPIOD                           GPIO_PORT_D_BASE
#define GPIOE                           GPIO_PORT_E_BASE
#define GPIOF                           GPIO_PORT_F_BASE
 
#define MMIO32(addr) (*(volatile unsigned int*)(addr))
	
#define RCC_AHB1ENR_OFFSET 0x48
#define RCC_AHB2ENR_OFFSET 0x4C
#define RCC_BASE  (PERIPH_BASE_AHB1 + 0x1000)
#define RCC_AHB1ENR  MMIO32(RCC_BASE + RCC_AHB1ENR_OFFSET)
#define RCC_AHB2ENR  MMIO32(RCC_BASE + RCC_AHB2ENR_OFFSET)
 
/* --- GPIO registers for STM32F2, STM32F3 and STM32F4 --------------------- */
  
/* Port mode register (GPIOx_MODER) */
#define GPIO_MODER(port)                MMIO32((port) + 0x00)
#define GPIOA_MODER                     GPIO_MODER(GPIOA)
#define GPIOB_MODER                     GPIO_MODER(GPIOB)
#define GPIOC_MODER                     GPIO_MODER(GPIOC)
#define GPIOD_MODER                     GPIO_MODER(GPIOD)
#define GPIOE_MODER                     GPIO_MODER(GPIOE)
#define GPIOF_MODER                     GPIO_MODER(GPIOF)
  
/* Port output type register (GPIOx_OTYPER) */
#define GPIO_OTYPER(port)               MMIO32((port) + 0x04)
#define GPIOA_OTYPER                    GPIO_OTYPER(GPIOA)
#define GPIOB_OTYPER                    GPIO_OTYPER(GPIOB)
#define GPIOC_OTYPER                    GPIO_OTYPER(GPIOC)
#define GPIOD_OTYPER                    GPIO_OTYPER(GPIOD)
#define GPIOE_OTYPER                    GPIO_OTYPER(GPIOE)
#define GPIOF_OTYPER                    GPIO_OTYPER(GPIOF)
  
/* Port output speed register (GPIOx_OSPEEDR) */
#define GPIO_OSPEEDR(port)              MMIO32((port) + 0x08)
#define GPIOA_OSPEEDR                   GPIO_OSPEEDR(GPIOA)
#define GPIOB_OSPEEDR                   GPIO_OSPEEDR(GPIOB)
#define GPIOC_OSPEEDR                   GPIO_OSPEEDR(GPIOC)
#define GPIOD_OSPEEDR                   GPIO_OSPEEDR(GPIOD)
#define GPIOE_OSPEEDR                   GPIO_OSPEEDR(GPIOE)
#define GPIOF_OSPEEDR                   GPIO_OSPEEDR(GPIOF)
  
/* Port pull-up/pull-down register (GPIOx_PUPDR) */
#define GPIO_PUPDR(port)                MMIO32((port) + 0x0c)
#define GPIOA_PUPDR                     GPIO_PUPDR(GPIOA)
#define GPIOB_PUPDR                     GPIO_PUPDR(GPIOB)
#define GPIOC_PUPDR                     GPIO_PUPDR(GPIOC)
#define GPIOD_PUPDR                     GPIO_PUPDR(GPIOD)
#define GPIOE_PUPDR                     GPIO_PUPDR(GPIOE)
#define GPIOF_PUPDR                     GPIO_PUPDR(GPIOF)
  
/* Port input data register (GPIOx_IDR) */
#define GPIO_IDR(port)                  MMIO32((port) + 0x10)
#define GPIOA_IDR                       GPIO_IDR(GPIOA)
#define GPIOB_IDR                       GPIO_IDR(GPIOB)
#define GPIOC_IDR                       GPIO_IDR(GPIOC)
#define GPIOD_IDR                       GPIO_IDR(GPIOD)
#define GPIOE_IDR                       GPIO_IDR(GPIOE)
#define GPIOF_IDR                       GPIO_IDR(GPIOF)
  
/* Port output data register (GPIOx_ODR) */
#define GPIO_ODR(port)                  MMIO32((port) + 0x14)
#define GPIOA_ODR                       GPIO_ODR(GPIOA)
#define GPIOB_ODR                       GPIO_ODR(GPIOB)
#define GPIOC_ODR                       GPIO_ODR(GPIOC)
#define GPIOD_ODR                       GPIO_ODR(GPIOD)
#define GPIOE_ODR                       GPIO_ODR(GPIOE)
#define GPIOF_ODR                       GPIO_ODR(GPIOF)
  
/* Port bit set/reset register (GPIOx_BSRR) */
#define GPIO_BSRR(port)                 MMIO32((port) + 0x18)
#define GPIOA_BSRR                      GPIO_BSRR(GPIOA)
#define GPIOB_BSRR                      GPIO_BSRR(GPIOB)
#define GPIOC_BSRR                      GPIO_BSRR(GPIOC)
#define GPIOD_BSRR                      GPIO_BSRR(GPIOD)
#define GPIOE_BSRR                      GPIO_BSRR(GPIOE)
#define GPIOF_BSRR                      GPIO_BSRR(GPIOF)
 
/* Port configuration lock register (GPIOx_LCKR) */
#define GPIO_LCKR(port)                 MMIO32((port) + 0x1c)
#define GPIOA_LCKR                      GPIO_LCKR(GPIOA)
#define GPIOB_LCKR                      GPIO_LCKR(GPIOB)
#define GPIOC_LCKR                      GPIO_LCKR(GPIOC)
#define GPIOD_LCKR                      GPIO_LCKR(GPIOD)
#define GPIOE_LCKR                      GPIO_LCKR(GPIOE)
#define GPIOF_LCKR                      GPIO_LCKR(GPIOF)
 
/* Alternate function low register (GPIOx_AFRL) */
#define GPIO_AFRL(port)                 MMIO32((port) + 0x20)
#define GPIOA_AFRL                      GPIO_AFRL(GPIOA)
#define GPIOB_AFRL                      GPIO_AFRL(GPIOB)
#define GPIOC_AFRL                      GPIO_AFRL(GPIOC)
#define GPIOD_AFRL                      GPIO_AFRL(GPIOD)
#define GPIOE_AFRL                      GPIO_AFRL(GPIOE)
#define GPIOF_AFRL                      GPIO_AFRL(GPIOF)
  
 /* Alternate function high register (GPIOx_AFRH) */
#define GPIO_AFRH(port)                 MMIO32((port) + 0x24)
#define GPIOA_AFRH                      GPIO_AFRH(GPIOA)
#define GPIOB_AFRH                      GPIO_AFRH(GPIOB)
#define GPIOC_AFRH                      GPIO_AFRH(GPIOC)
#define GPIOD_AFRH                      GPIO_AFRH(GPIOD)
#define GPIOE_AFRH                      GPIO_AFRH(GPIOE)
#define GPIOF_AFRH                      GPIO_AFRH(GPIOF)
   
void delayMs(int n);
 
int main(void) {
    //RCC_AHB1ENR |=  1;              /* enable GPIOA clock */
	  RCC_AHB2ENR |=  1;              /* enable GPIOA clock */
    
    GPIOA_MODER &= ~0x00000C00;     /* clear pin mode */
    GPIOA_MODER |=  0x00000400;     /* set pin to output mode */
    
    while(1) {
       GPIOA_BSRR = 0x00000020;    /* turn on LED */
        delayMs(500);
       GPIOA_BSRR = 0x00200000;    /* turn off LED */
        delayMs(500);
    }
}
 
/* 16 MHz SYSCLK */
void delayMs(int n) {
    int i;
    for (; n > 0; n--)
        for (i = 0; i < 3195; i++) ;
}

> clock activation is with RCC_AHB2ENR and not with RCC_AHB1ENR

Oh, did I mention that it is very prone to errors?

Using CMSIS definitions from the MCU header, it would have been immediately apparent at compile time that RCC_AHB1ENR_GPIOAEN is not defined, but RCC_AHB2ENR_GPIOAEN is.

I have an empty CMSIS section. Which option do you suggest?

0693W000000USF4QAO.jpg