STM32 Nucleo-F446RE

Support for the STM32 Nucleo-F446RE.

Overview

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

Hardware

MCU

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

MCU

MCU STM32F446RE
Family ARM Cortex-M4
Vendor ST Microelectronics
RAM 128Kb
Flash 512Kb
Frequency up to 180MHz
FPU yes
Timers 11 (2x watchdog, 1 SysTick, 12x 16-bit, 2x 32-bit [TIM2])
ADCs 3x 12-bit
UARTs 4
SPIs 4
I2Cs 4
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 STM32F446RE partly Energy saving modes not fully utilized
Low-level driver GPIO yes
PWM yes (9 pins available)
UART 3 UARTs USART2 via STLink/USB or D0(RX)/D1(TX), USART3 on PC11(RX)/PC10(TX) and USART1 on PA10(RX)/PA9(TX)
I2C one I2C
SPI one SPI
USB no
Timer one 32 bit timer

Flashing the device

The ST Nucleo-F446RE board includes an on-board ST-LINK V2 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-f446 flash
and debug via GDB by simply typing
1
make BOARD=nucleo-f446 debug

Supported Toolchains

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

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_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_stream4)
UART_2_ISR
1
(isr_usart3)
UART_2_DMA_ISR
1
(isr_dma1_stream5)
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_PIN(PORT_B,  2), .cc_chan = 3} },
        .af       = GPIO_AF1,
        .bus      = APB1
    },
    {
        .dev      = TIM8,
        .rcc_mask = RCC_APB2ENR_TIM8EN,
        .chan     = { { .pin = GPIO_PIN(PORT_C, 6), .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_AF3,
        .bus      = APB2
    },
}
PWM_NUMOF
1
(sizeof(pwm_config) / sizeof(pwm_config[0]))
const qdec_conf_t qdec_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
= {
    {
        .dev      = TIM3,
        .max      = 0xffffffff,
        .rcc_mask = RCC_APB1ENR_TIM3EN,
        .chan     = { { .pin = GPIO_PIN(PORT_A, 6), .cc_chan = 0 },
                      { .pin = GPIO_PIN(PORT_A, 7), .cc_chan = 1 } },
        .af       = GPIO_AF2,
        .bus      = APB1,
        .irqn     = TIM3_IRQn
    },
    {
        .dev      = TIM4,
        .max      = 0xffffffff,
        .rcc_mask = RCC_APB1ENR_TIM4EN,
        .chan     = { { .pin = GPIO_PIN(PORT_B, 6), .cc_chan = 0 },
                      { .pin = GPIO_PIN(PORT_B, 7), .cc_chan = 1 } },
        .af       = GPIO_AF2,
        .bus      = APB1,
        .irqn     = TIM4_IRQn
    },
}
QDEC_0_ISR
1
isr_tim3
QDEC_1_ISR
1
isr_tim4
QDEC_NUMOF
1
(sizeof(qdec_config) / sizeof(qdec_config[0]))
const spi_conf_t spi_config()
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}, \
}