STM32 Nucleo-F103RB

Support for the STM32 Nucleo-F103RB.

Overview

The Nucleo-F103 is a board from ST’s Nucleo family supporting a ARM Cortex-M3 STM32F103RB microcontroller with 20Kb of SRAM and 128Kb of ROM Flash.

Hardware

MCU

MCU STM32F103RB
Family ARM Cortex-M3
Vendor ST Microelectronics
RAM 20Kb
Flash 128Kb
Frequency up to 72MHz
FPU yes
Timers 7 (2x watchdog, 1 SysTick, 4x 16-bit)
ADCs 1x 12-bit
UARTs 3
SPIs 2
I2Cs 2
RTC 1
Vcc 2.0V - 3.6V
Datasheet Datasheet
Reference Manual Reference Manual
Programming Manual Programming Manual
Board Manual Board Manual

MCU

MCU STM32F103RB
Family ARM Cortex-M3
Vendor ST Microelectronics
RAM 20Kb
Flash 128Kb
Frequency up to 72MHz
FPU yes
Timers 7 (2x watchdog, 1 SysTick, 4x 16-bit)
ADCs 1x 12-bit
UARTs 3
SPIs 2
I2Cs 2
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 STM32F103RB partly Energy saving modes not fully utilized
Low-level driver GPIO yes
PWM yes (4 pins available)
UART 2 UARTs USART2 via STLink/USB or D0(RX)/D1(TX), USART1 on PA10(RX)/PA09(TX) and USART3 on PB11(RX)/PB10(TX)
ADC no
I2C yes (I2C1 and I2C2)
SPI yes (SPI1 and SPI2)
USB no
Timer 2 16 bit timers (TIM2 and TIM3)

Flashing the device

The ST Nucleo-F103 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-f103 flash
and debug via GDB by simply typing
1
make BOARD=nucleo-f103 debug

Supported Toolchains

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

CLOCK_CORECLOCK
1
(72000000U)
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 36MHz */
CLOCK_APB1
1
(CLOCK_CORECLOCK / 2)
CLOCK_APB2_DIV
1
RCC_CFGR_PPRE2_DIV1     /* max 72MHz */
CLOCK_APB2
1
(CLOCK_CORECLOCK / 1)
CLOCK_PLL_PREDIV
1
(1)
CLOCK_PLL_MUL
1
(9)
ADC_NUMOF
1
(0)
const timer_conf_t timer_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
= {
    {
        .dev      = TIM2,
        .max      = 0x0000ffff,
        .rcc_mask = RCC_APB1ENR_TIM2EN,
        .bus      = APB1,
        .irqn     = TIM2_IRQn
    },
    {
        .dev      = TIM3,
        .max      = 0x0000ffff,
        .rcc_mask = RCC_APB1ENR_TIM3EN,
        .bus      = APB1,
        .irqn     = TIM3_IRQn
    }
}
TIMER_0_ISR
1
isr_tim2
TIMER_1_ISR
1
isr_tim3
TIMER_NUMOF
1
(sizeof(timer_config) / sizeof(timer_config[0]))
const uart_conf_t uart_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
= {
    {
        .dev        = USART2,
        .rcc_mask   = RCC_APB1ENR_USART2EN,
        .rx_pin     = GPIO_PIN(PORT_A, 3),
        .tx_pin     = GPIO_PIN(PORT_A, 2),
        .bus        = APB1,
        .irqn       = USART2_IRQn
    },
    {
        .dev        = USART1,
        .rcc_mask   = RCC_APB2ENR_USART1EN,
        .rx_pin     = GPIO_PIN(PORT_A, 10),
        .tx_pin     = GPIO_PIN(PORT_A, 9),
        .bus        = APB2,
        .irqn       = USART1_IRQn
    },
    {
        .dev        = USART3,
        .rcc_mask   = RCC_APB1ENR_USART3EN,
        .rx_pin     = GPIO_PIN(PORT_B, 11),
        .tx_pin     = GPIO_PIN(PORT_B, 10),
        .bus        = APB1,
        .irqn       = USART3_IRQn
    }
}
UART_0_ISR
1
(isr_usart2)
UART_1_ISR
1
(isr_usart1)
UART_2_ISR
1
(isr_usart3)
UART_NUMOF
1
(sizeof(uart_config) / sizeof(uart_config[0]))
RTT_NUMOF
1
(1U)
RTT_IRQ_PRIO
1
1
RTT_DEV
1
RTC
RTT_IRQ
1
RTC_IRQn
RTT_ISR
1
isr_rtc
RTT_MAX_VALUE
1
(0xffffffff)
RTT_FREQUENCY
1
(16384)      /* in Hz */
RTT_PRESCALER
1
(0x1)        /* run with ~16 kHz Hz */
const i2c_conf_t i2c_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
= {
    {
        .dev            = I2C1,
        .speed          = I2C_SPEED_NORMAL,
        .scl_pin        = GPIO_PIN(PORT_B, 8),
        .sda_pin        = GPIO_PIN(PORT_B, 9),
        .bus            = APB1,
        .rcc_mask       = RCC_APB1ENR_I2C1EN,
        .clk            = CLOCK_APB1,
        .irqn           = I2C1_EV_IRQn
    },
    {
        .dev            = I2C2,
        .speed          = I2C_SPEED_NORMAL,
        .scl_pin        = GPIO_PIN(PORT_B, 10),
        .sda_pin        = GPIO_PIN(PORT_B, 11),
        .bus            = APB1,
        .rcc_mask       = RCC_APB1ENR_I2C2EN,
        .clk            = CLOCK_APB1,
        .irqn           = I2C2_EV_IRQn
    }
}
I2C_0_ISR
1
isr_i2c1_ev
I2C_1_ISR
1
isr_i2c2_ev
I2C_NUMOF
1
(sizeof(i2c_config) / sizeof(i2c_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,  
        4,  
        2,  
        1   
    },
    {       
        7,  
        7,  
        5,  
        3,  
        2   
    }
}
const spi_conf_t spi_config()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
= {
    {
        .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_UNDEF,
        .rccmask  = RCC_APB2ENR_SPI1EN,
        .apbbus   = APB2
    },
    {
        .dev      = SPI2,
        .mosi_pin = GPIO_PIN(PORT_B, 15),
        .miso_pin = GPIO_PIN(PORT_B, 14),
        .sclk_pin = GPIO_PIN(PORT_B, 13),
        .cs_pin   = GPIO_UNDEF,
        .rccmask  = RCC_APB1ENR_SPI2EN,
        .apbbus   = APB1
    }
}
SPI_NUMOF
1
(sizeof(spi_config) / sizeof(spi_config[0]))