Home

STM32F411 Black Pill

Pinout

Feature Specs
CPU Cortex-M4 100MHz
RAM 128kB
Flash 512kB
GPIO 32
ADC 12 bit
USB 1.1 Host/Device
UART 3
I2C 3
SPI 5
I2S 2
Current consumption 26mA
32-bit FPU Use floats instead of doubles

#include "stm32f4xx_hal.h"

GPIO

GPIO allows the software to turn on and off a pin and read high or low from a pin.

PWM

PWM approzimates an analog voltage by quickly switching between a fixed high voltage and ground so the average over time is the desired analogy voltage.

Microcontrollers use a timer that counts up to a set value, then resets to 0. This is one PWM cycle, consisting of a high phase and a low phase. When the timer count exceeds a compare vlaue, the output switches from high to low. Changing this compare value changes the duty cycle. Chaning the maximum count value changes the resolution. The frequency depends on the clock frequency and the resoltion, where high resoltion lowers the frequency.

Ex: Given a system clock cycle of 72MHz and 8-bit(0-255) resolution, what’s teh frequency of the PWM?

$\frac{72,000,000 \text{ counts}}{1 \text{ sec}} * \frac{1 \text{ cycle}}{256 \text{ counts}} = 218,250 \text{ cycles per second}$

UART

I2C

SPI

I2S

Timers

Watchdog

Power mods

ADC and DAC

Interrupts

TIM2_IRQHandler - is a special function name that matches the entry in the STM32 interrupt vector table for TIM2. - So when TIM2 throws an interupt event, this function is automatically called.

USB

Serial output via USB-C

// In my_main.h
#include "usbd_cdc_if.h"
#include <stdio.h>

// Wrapped in extern c
int _write(int file, char *ptr, int len);

// In my_main.cpp wrapped in extern c
int _write(int file, char *ptr, int len) {
	CDC_Transmit_FS((uint8_t*)ptr, len);
	return len;
}

// Usage example
printf("Hello world!\r\n"); // You need \r
# Create an executable object type
add_executable(${CMAKE_PROJECT_NAME})
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES LINK_FLAGS "-u _printf_float")

DMA

Direct memory access.

Set up

  1. Install: CubeMX and STM32CubeIDE for Visual Studio Code(stmicroelectronics.stm32-vscode-extension).
  2. Generate starter code for CubeMX
    1. File -> New Project
    2. Type in your Commercial part number: STM32F411CEU6
    3. Start project in the top right
    4. Pinout & Configuration
    5. Project manager
      • Project Name
      • Project Location
      • Toolchain/IDE: CMake
    6. GENERATE CODE in the top right
  3. Wire ST-Link
ST-Link Pin Board Pin
GND GND
3.3v 3.3v
SWDIO DIO
SWCLK SCLK
  1. If it’s your first time using your ST-Link device, you’ll need to upgrade its firmware.
  2. Setup your code
    1. Create My_Code folder at the root level of your project.

In my_main.h

#include "stm32f4xx_hal.h"

#ifdef __cplusplus
extern "C" {
#endif

// Example of a variable that's declared in main.c
extern TIM_HandleTypeDef htim2;

void myCode();

#ifdef __cplusplus
}
#endif

In my_main.cpp

#include "my_main.h"

#ifdef __cplusplus
extern "C" {
#endif

void myCode(){
	while(true) {}
}

#ifdef __cplusplus
}
#endif
  1. In Core/Src/main.c
/* USER CODE BEGIN Includes */
#include "../../My_Code/my_main.h"
/* USER CODE END Includes */

// ...

/* USER CODE BEGIN WHILE */
myCode();
/* USER CODE END WHILE */
  1. In CMakeLists.txt
file(GLOB MY_CODE_SOURCES My_Code/*.cpp)
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
	# Add user sources here
	${MY_CODE_SOURCES}
)
  1. Compiling, Flashing, and Debugging

Other

Memory layout

Memory Description
.isr_vector Stores interrupt vectors and reset handler addresses.
.text Your code
.rodata Read only constants and literals.
.data Initialized global and static variables.
.bss Uninitialized global and static variables.

Libraries