STM32 Nucleo-F411RE

Support for the STM32 Nucleo-F411RE.

Overview

The Nucleo-F411 is a board from ST’s Nucleo family supporting a ARM Cortex-M4 STM32F411RE microcontroller with 128Kb of SRAM and 512Kb of ROM Flash.

Hardware

MCU

MCU STM32F411RE
Family ARM Cortex-M4
Vendor ST Microelectronics
RAM 128Kb
Flash 512Kb
Frequency up to 100MHz
FPU yes
Timers 11 (2x watchdog, 1 SysTick, 6x 16-bit, 2x 32-bit [TIM2])
ADCs 1x 12-bit
UARTs 3
SPIs 5
I2Cs 3
RTC 1
Vcc 2.0V - 3.6V
| Datasheet | Datasheet | | Reference Manual | Reference Manual | | Programming Manual | Programming Manual | | Board Manual | Board Manual|

MCU

MCU STM32F411RE
Family ARM Cortex-M4
Vendor ST Microelectronics
RAM 128Kb
Flash 512Kb
Frequency up to 100MHz
FPU yes
Timers 11 (2x watchdog, 1 SysTick, 6x 16-bit, 2x 32-bit [TIM2])
ADCs 1x 12-bit
UARTs 3
SPIs 5
I2Cs 3
RTC 1
Vcc 2.0V - 3.6V
| Datasheet | Datasheet | | Reference Manual | Reference Manual | | Programming Manual | Programming Manual | | Board Manual | Board Manual|

Implementation Status

Device ID Supported Comments
MCU STM32F411RE partly Energy saving modes not fully utilized
Low-level driver GPIO yes
PWM yes (7 pins available))
UART 3 UARTs USART2 via STLink/USB or D0(RX)/D1(TX), USART1 on PA10(RX)/PA9(TX) and USART6 on PA12(RX)/PA11(TX)
I2C 1 I2C
SPI 1 SPI
USB no
Timer 1 32 bit timer (TIM5)

Flashing the device

The ST Nucleo-F411RE board includes an on-board ST-LINK V2-1 programmer. The easiest way to program the board is to use OpenOCD. Once you have installed OpenOCD (look here for installation instructions), you can flash the board simply by typing

1
make BOARD=nucleo-f411 flash
and debug via GDB by simply typing
1
make BOARD=nucleo-f411 debug

Supported Toolchains

For using the ST Nucleo-F411 board we strongly recommend the usage of the GNU Tools for ARM Embedded Processors toolchain.

CLOCK_CORECLOCK
1
(96000000U)
CLOCK_HSE
1
(8000000U)
CLOCK_LSE
1
(1)
CLOCK_AHB_DIV
1
RCC_CFGR_HPRE_DIV1
CLOCK_AHB
1
(CLOCK_CORECLOCK / 1)
CLOCK_APB1_DIV
1
RCC_CFGR_PPRE1_DIV2     /* max 50MHz */
CLOCK_APB1
1
(CLOCK_CORECLOCK / 2)
CLOCK_APB2_DIV
1
RCC_CFGR_PPRE2_DIV1     /* max 100MHz */
CLOCK_APB2
1
(CLOCK_CORECLOCK / 1)
CLOCK_PLL_M
1
(4)
CLOCK_PLL_N
1
(192)
CLOCK_PLL_P
1
(4)
CLOCK_PLL_Q
1
(8)
const timer_conf_t timer_config()
1
2
3
4
5
6
7
8
9
= {
    {
        .dev      = TIM5,
        .max      = 0xffffffff,
        .rcc_mask = RCC_APB1ENR_TIM5EN,
        .bus      = APB1,
        .irqn     = TIM5_IRQn
    }
}
TIMER_0_ISR
1
isr_tim5
TIMER_1_ISR
1
isr_tim4
TIMER_NUMOF
1
(sizeof(timer_config) / sizeof(timer_config[0]))
const uart_conf_t uart_config()
UART_0_ISR
1
isr_usart2
UART_0_DMA_ISR
1
isr_dma1_stream6
UART_1_ISR
1
isr_usart1
UART_1_DMA_ISR
1
isr_dma1_stream6
UART_2_ISR
1
isr_usart6
UART_2_DMA_ISR
1
isr_dma1_stream6
UART_NUMOF
1
(sizeof(uart_config) / sizeof(uart_config[0]))
const pwm_conf_t pwm_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
= {
    {
        .dev      = TIM2,
        .rcc_mask = RCC_APB1ENR_TIM2EN,
        .chan     = { { .pin = GPIO_PIN(PORT_A, 15)         , .cc_chan = 0 },
                      { .pin = GPIO_PIN(PORT_B, 3)  , .cc_chan = 1 },
                      { .pin = GPIO_PIN(PORT_B, 10) , .cc_chan = 2 },
                      { .pin = GPIO_UNDEF,                    .cc_chan = 0 } },
        .af       = GPIO_AF1,
        .bus      = APB1
    },
    {
        .dev      = TIM3,
        .rcc_mask = RCC_APB1ENR_TIM3EN,
        .chan     = { { .pin = GPIO_PIN(PORT_B, 4) , .cc_chan = 0 },
                      { .pin = GPIO_PIN(PORT_C, 7) , .cc_chan = 1 },
                      { .pin = GPIO_PIN(PORT_C, 8),          .cc_chan = 2 },
                      { .pin = GPIO_PIN(PORT_C, 9),          .cc_chan = 3 } },
        .af       = GPIO_AF2,
        .bus      = APB1
    },
}
PWM_NUMOF
1
(sizeof(pwm_config) / sizeof(pwm_config[0]))
const uint8_t spi_divtable()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
= {
    {       
        7,  
        6,  
        5,  
        2,  
        1   
    },
    {       
        7,  
        7,  
        6,  
        3,  
        2   
    }
}
const spi_conf_t spi_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
= {
    {
        .dev      = SPI1,
        .mosi_pin = GPIO_PIN(PORT_A, 7),
        .miso_pin = GPIO_PIN(PORT_A, 6),
        .sclk_pin = GPIO_PIN(PORT_A, 5),
        .cs_pin   = GPIO_PIN(PORT_A, 4),
        .af       = GPIO_AF5,
        .rccmask  = RCC_APB2ENR_SPI1EN,
        .apbbus   = APB2
    }
}
SPI_NUMOF
1
(sizeof(spi_config) / sizeof(spi_config[0]))
const i2c_conf_t i2c_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
= {
    {
        .dev            = I2C1,
        .speed          = I2C_SPEED_NORMAL,
        .scl_pin        = GPIO_PIN(PORT_B, 8),
        .sda_pin        = GPIO_PIN(PORT_B, 9),
        .scl_af         = GPIO_AF4,
        .sda_af         = GPIO_AF4,
        .bus            = APB1,
        .rcc_mask       = RCC_APB1ENR_I2C1EN,
        .clk            = CLOCK_APB1,
        .irqn           = I2C1_EV_IRQn
    }
}
I2C_0_ISR
1
isr_i2c1_ev
I2C_NUMOF
1
(sizeof(i2c_config) / sizeof(i2c_config[0]))
ADC_NUMOF
1
(6U)
ADC_CONFIG
1
2
3
4
5
6
7
8
{             \
    {GPIO_PIN(PORT_A, 0), 0, 0}, \
    {GPIO_PIN(PORT_A, 1), 0, 1}, \
    {GPIO_PIN(PORT_A, 4), 0, 4}, \
    {GPIO_PIN(PORT_B, 0), 0, 8}, \
    {GPIO_PIN(PORT_C, 1), 0, 11}, \
    {GPIO_PIN(PORT_C, 0), 0, 10}, \
}