Skip to content

eylloztek/stm_projects

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

30 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

00_Hello_World - LED Blink Project

This project demonstrates how to toggle a green LED connected to a GPIO pin using STM32 HAL functions with the STM32CubeIDE development environment. The LED blinks with a 500 ms delay interval.

πŸ› οΈ Hardware

  • Development Board: STM32 Nucleo-F446RE
  • Microcontroller: STM32F446RE (ARM Cortex-M4)
  • LED Pin: Custom GPIO (e.g., green_led_Pin on GPIOA)
  • Power Supply: USB connection

πŸ’» Development Environment

  • IDE: STM32CubeIDE
  • Toolchain: STM32 HAL (Hardware Abstraction Layer)
  • Language: C

βš™οΈ Functionality

The LED is toggled on and off every 500 milliseconds in the main loop.

HAL_GPIO_WritePin(green_led_GPIO_Port, green_led_Pin, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(green_led_GPIO_Port, green_led_Pin, GPIO_PIN_RESET);
HAL_Delay(500);

πŸ”Œ GPIO Configuration

image

The pin is configured as:

GPIO_InitStruct.Pin = green_led_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(green_led_GPIO_Port, &GPIO_InitStruct);

01_Knight_Rider - LED Animation Project

This project demonstrates how to control multiple LEDs connected to GPIO pins on an STM32 Nucleo-F446RE board using STM32 HAL. The LEDs blink in a forward and backward sequence, creating a simple "running light" or "bouncing" LED animation.

πŸ› οΈ Hardware

  • Development Board: STM32 Nucleo-F446RE
  • LEDs: 4 LEDs connected to GPIOA (Red, Green, Yellow, Blue)
  • Power Supply: USB connection

πŸ’» Development Environment

  • IDE: STM32CubeIDE
  • Toolchain: STM32 HAL
  • Language: C

βš™οΈ Functionality

This code toggles 4 LEDs in the following sequence:

  • Forward: Yellow β†’ Blue β†’ Green β†’ Red
  • Backward: Green β†’ Blue

Each LED lights up for 200 milliseconds before turning off and moving to the next in the sequence. This creates a simple back-and-forth animation pattern.

πŸ” LED Sequence Logic

for (i = 0; i < 4; i++) {
    HAL_GPIO_WritePin(LED_PORT, leds[i], 1);
    HAL_Delay(200);
    HAL_GPIO_WritePin(LED_PORT, leds[i], 0);
}

for (i = 2; i > 0; i--) {
    HAL_GPIO_WritePin(LED_PORT, leds[i], 1);
    HAL_Delay(200);
    HAL_GPIO_WritePin(LED_PORT, leds[i], 0);
}

πŸ”Œ GPIO Configuration

image

LED Color Pin Macro Port
Red red_led_Pin GPIOA
Green green_led_Pin GPIOA
Yellow yellow_led_Pin GPIOA
Blue blue_led_Pin GPIOA

These pins are initialized as push-pull output without pull-up or pull-down resistors.

GPIO_InitStruct.Pin = red_led_Pin | green_led_Pin | yellow_led_Pin | blue_led_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

02_Button - Button-Controlled LED Counter

This STM32CubeIDE project demonstrates how to use a push button to increment a counter and control multiple LEDs connected to GPIO pins on the STM32 Nucleo-F446RE board. The number of active LEDs increases with each button press, cycling through four stages.

πŸ› οΈ Hardware

  • Board: STM32 Nucleo-F446RE
  • Microcontroller: STM32F446RE (ARM Cortex-M4)
  • Input: 1 Push Button (Pull-up enabled)
  • Output: 4 LEDs (connected to GPIOA pins PA6, PA7, PA9, PA8)
  • Status LED: green_led_Pin for button press indication

πŸ’» Development Environment

  • IDE: STM32CubeIDE
  • Toolchain: STM32 HAL (Hardware Abstraction Layer)
  • Language: C

βš™οΈ Functionality

  • The program monitors a button connected to a GPIO pin (button_Pin) with pull-up enabled.
  • When the button is pressed (logic low), a counter (buttonCounter) is incremented.
  • The green LED is turned ON while the button is pressed.
  • Based on the modulo of the counter (buttonCounter % 4), a set number of LEDs are turned ON:
    • 0 β†’ 1 LED ON (PA6)
    • 1 β†’ 2 LEDs ON (PA6, PA7)
    • 2 β†’ 3 LEDs ON (PA6, PA7, PA9)
    • 3 β†’ 4 LEDs ON (PA6, PA7, PA9, PA8)
  • After 4 presses, the counter resets to the beginning of the cycle.

πŸ” LED Sequence Logic (simplified)

if (buttonCounter % 4 == 0) {
  LED1 = ON
} else if (buttonCounter % 4 == 1) {
  LED1, LED2 = ON
} else if (buttonCounter % 4 == 2) {
  LED1, LED2, LED3 = ON
} else if (buttonCounter % 4 == 3) {
  LED1, LED2, LED3, LED4 = ON
}

πŸ”Œ Pin Configuration

image

Purpose GPIO Pin
Button Input button_Pin (with pull-up)
Status LED green_led_Pin (GPIOA)
Output LEDs PA6, PA7, PA9, PA8

These pins are configured as follows:

Input (button): GPIO_MODE_INPUT, GPIO_PULLUP

Output (LEDs): GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, MEDIUM speed

03_External_Interrupt - External Interrupt LED Blink

This STM32CubeIDE project demonstrates the use of external interrupts (EXTI) on the STM32 Nucleo-F446RE board. A user button triggers an interrupt that causes a faster LED blinking sequence in addition to the default blinking pattern.

πŸ› οΈ Hardware

  • Board: STM32 Nucleo-F446RE
  • Microcontroller: STM32F446RE (ARM Cortex-M4)
  • Input: Push Button connected to PC13 (default user button)
  • Output: LED connected to custom GPIO pin (led_Pin)

πŸ’» Development Environment

  • IDE: STM32CubeIDE
  • Toolchain: STM32 HAL
  • Language: C

βš™οΈ Functionality

  • The LED toggles every 500 ms by default.
  • When the user presses the button (attached to PC13), an external interrupt (EXTI) is triggered.
  • The interrupt sets a flag interruptFlag.
  • In the next loop cycle, the LED blinks rapidly 5 times (100 ms interval) as a response to the interrupt.

πŸ” LED Blink Logic

// Default blink every 500 ms
HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
HAL_Delay(500);

// On interrupt
if (interruptFlag) {
    interruptFlag = 0;
    for (int i = 0; i < 5; i++) {
        HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
        HAL_Delay(100);
    }
}

⏱️ External Interrupt Setup

Button Pin: buton_Pin mapped to PC13

Trigger: Rising edge (GPIO_MODE_IT_RISING)

Pull Configuration: Pull-up enabled (GPIO_PULLUP)

Interrupt Handler: HAL_GPIO_EXTI_Callback()

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == GPIO_PIN_13) {
        interruptFlag = 1;
    }
}

πŸ”Œ Pin Configuration

image

Purpose Pin Mode
LED Output led_Pin GPIO_MODE_OUTPUT_PP
Button Input PC13 GPIO_MODE_IT_RISING

04_UART - UART Communication (Transmit & Receive)

This STM32CubeIDE project demonstrates basic UART communication using the STM32 Nucleo-F446RE board. The system waits for a 5-byte message over UART and responds with a predefined message once received.

πŸ”§ Hardware

  • Board: STM32 Nucleo-F446RE
  • Communication Interface: UART2 (TX/RX)
  • Optional Output: LED (status or activity indicator)

πŸ› οΈ Development Environment

  • IDE: STM32CubeIDE
  • Toolchain: STM32 HAL
  • Language: C

βš™οΈ Functionality

  • Initializes UART2 at 115200 baud rate.
  • Waits for a 5-byte message via UART (blocking mode).
  • Once the message is received, it transmits "Hello!\r\n" back over UART.

πŸ’¬ UART Operation

uint8_t messageTX[] = "Hello! \r\n";
uint8_t messageRX[5];

if (HAL_UART_Receive(&huart2, messageRX, sizeof(messageRX), HAL_MAX_DELAY) == HAL_OK) {
    HAL_UART_Transmit(&huart2, messageTX, sizeof(messageTX), HAL_MAX_DELAY);
}

🧠 UART2 Configuration

Parameter Value
Baud Rate 115200
Word Length 8 bits
Stop Bits 1
Parity None
Flow Control None
Mode TX/RX

πŸ”Œ Pin Configuration

image

UART Function STM32 Pin Nucleo Pin Header
TX (USART2) PA2 D1
RX (USART2) PA3 D0

πŸ§ͺ How to Test

Open a terminal tool (like PuTTY, TeraTerm, or STM32CubeMonitor).

Connect to the Nucleo board's virtual COM port at 115200 8N1.

Send any 5-byte string (e.g., 12345).

You will receive Hello! as a response over UART.

05_UART_Interrupt - UART Command-Controlled LED

This STM32 project demonstrates UART-based LED control on the STM32 Nucleo-F446RE board. It allows you to send textual commands (on, off, or blink <time>) to control an onboard LED through a serial terminal.

πŸ”§ Hardware

  • Board: STM32 Nucleo-F446RE
  • Peripheral Used: UART2 (TX/RX), GPIO (LED Control)

πŸ› οΈ Development Environment

  • IDE: STM32CubeIDE
  • Library: STM32 HAL (Hardware Abstraction Layer)
  • Language: C

πŸš€ Features

  • Non-blocking UART Reception (Interrupt-based)
  • Command Parsing
  • LED Control
  • Dynamic LED Blink Duration

πŸ“‘ UART Commands

Command Description
on Turns the LED on
off Turns the LED off
blink <time> Turns on the LED for <time> seconds

Example: Sending blink 3 via serial will turn the LED on for 3 seconds.

βš™οΈ Code Explanation

  • UART receive is configured in interrupt mode using HAL_UART_Receive_IT.
  • Incoming characters are accumulated into a buffer until a recognizable command is detected.
  • Upon recognizing:
    • "on": LED is turned on
    • "off": LED is turned off
    • "blink <time>": LED turns on for <time> seconds, then off
// Example: Handling "blink 2"
if (strncmp(messageBuffer, "blink ", 6) == 0) {
    blinkTime = atoi(&messageBuffer[6]);  // parse "2"
    interruptFlag = 1;
}

The blinking is handled in the main loop using:

if(interruptFlag){
    HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, 1);
    HAL_Delay(blinkTime * 1000);
    HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, 0);
    interruptFlag = 0;
}

πŸ”Œ Pin Configuration

image

Function STM32 Pin Nucleo Pin
TX PA2 D1
RX PA3 D0

πŸ§ͺ How to Use

  1. Flash the code to your STM32 Nucleo-F446RE.
  2. Open a serial terminal (e.g., PuTTY, Tera Term).
  3. Set Baud rate to 115200.
  4. Send the following commands:
  • on
  • off
  • blink 5

The LED will behave accordingly.

πŸ“Œ Notes

Input buffer size is 10 bytes.

All commands must fit within the buffer.

The program resets the buffer after each recognized command.

Uses string.h and stdlib.h for parsing and comparison.

06_Bluetooth_Module - HM-10 Bluetooth UART Communication

This project demonstrates Bluetooth communication between an STM32F4 microcontroller and a smartphone using the HM-10 Bluetooth module over USART1. The STM32 receives data sent from the phone and immediately echoes it back, enabling two-way Bluetooth-based serial communication.

πŸ”§ Hardware Requirements

  • πŸ“Ά Bluetooth Module: HM-10 (BLE)
  • πŸŽ› Board: STM32 Nucleo-F446RE
  • πŸ“‘ Communication: UART (USART1)
  • 🧠 Library: STM32 HAL (Hardware Abstraction Layer)
  • πŸ“² Phone App: Any Bluetooth serial terminal (e.g., Serial Bluetooth Terminal on Android, BLESerial tiny on iOS)

πŸ”Œ Pin Configuration

HM-10 Pin Connects To STM32
VCC 3.3V
GND GND
TXD RX (e.g., PA10 - USART1 RX)
RXD TX (e.g., PA9 - USART1 TX)

⚠️ Note: HM-10 uses 3.3V logic. Do not connect to 5V TX lines directly without a voltage divider or level shifter.

image

πŸ’‘ How It Works

  • The HM-10 module is paired with a smartphone.
  • Data sent from the phone is received by STM32 via USART1.
  • The microcontroller echoes the data back to the phone.
  • This forms a simple Bluetooth serial communication loop.

UART Settings

Parameter Value
Baud Rate 9600
Data Bits 8
Stop Bits 1
Parity None
Flow Control None

πŸ“Ÿ Code Behavior

uint8_t message[10];
HAL_UART_Receive(&huart1, message, 10, 1000);  // Receive 10 bytes from HM-10
HAL_UART_Transmit(&huart1, message, 10, 1000); // Echo it back to the phone

07_ADC_Internal_Temp_Sensor - Internal Temperature Sensor Reading via ADC

This project demonstrates how to measure the internal temperature of the STM32 Nucleo-F446RE board using its built-in temperature sensor via ADC1. The temperature is read, converted to degrees Celsius, and sent over USART2 to a serial terminal.

πŸ”§ Hardware Used

  • πŸ’» Microcontroller Board: STM32 Nucleo-F446RE
  • 🌑 Sensor: Internal temperature sensor of STM32F446RE
  • πŸ“  Communication Interface: UART (USART2)

πŸ“ How It Works

  1. The internal temperature sensor provides a voltage (VSENSE) proportional to the chip's temperature.

  2. This voltage is read using the ADC (Analog-to-Digital Converter).

  3. The value is converted to Celsius using the formula provided in the STM32 reference manual:

    T(Β°C) = ((VSENSE - V25) / Avg_Slope) + 25

    Where:

Parameter Description Value / Formula
VSENSE Voltage corresponding to ADC reading ADC_Value * VSTEP
V25 Voltage at 25Β°C (factory-calibrated) 0.76 V
Avg_Slope Average slope of the temperature sensor 2.5 mV/Β°C or 0.0025 V/Β°C
VSTEP Reference voltage used by ADC 3.3 / 4096

πŸ“Ÿ UART Output

The converted temperature is sent every second over UART using HAL_UART_Transmit().

Example output seen in a serial terminal:

image

πŸ” Main Loop Behavior

while (1) {
    temperature = readTemperature(&adcValue);
    sprintf(buffer, "Temperature: %.2f Β°C\r\n", temperature);
    HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
    HAL_Delay(1000);
}

βš™οΈ Configuration

Peripheral Parameter Value
ADC1 Channel ADC_CHANNEL_TEMPSENSOR
Resolution 12-bit
Sample Time 112 cycles
Conversion Mode Single conversion
Trigger Software start
Continuous Mode Enabled
Data Alignment Right
VREF 3.3V
USART2 Baud Rate 115200
Word Length 8 bits
Stop Bits 1
Parity None
Mode TX/RX
Hardware Flow Ctrl None

Register_Level_1 - Bare-Metal LED Blink

This project demonstrates how to toggle an LED using STM32F4 microcontroller registers directly without relying on the HAL (Hardware Abstraction Layer) or CMSIS drivers. The LED connected to PA5 (typically the onboard LED on STM32F4 Discovery/Nucleo boards) is toggled with a simple software delay.

πŸ› οΈ Hardware Requirements

  • Board: STM32 Nucleo-F446RE
  • LED Connection: Onboard LED at GPIOA Pin 5

πŸ’» Software Requirements

  • IDE: STM32CubeIDE
  • No HAL or CMSIS functions used
  • Pure register-level programming

πŸš€ What This Code Does

  1. Enables the clock for GPIOA.
  2. Configures PA5 as:
    • Output mode
    • Push-pull type
    • High-speed
    • No pull-up/pull-down
  3. Enters an infinite loop:
    • Sets PA5 high (turn LED on)
    • Waits using a crude software delay loop
    • Sets PA5 low (turn LED off)
    • Waits again

πŸ”§ Register Configuration Breakdown

RCC->AHB1ENR |= (1<<0);           // Enable clock to GPIOA
GPIOA->MODER &= ~(3<<(5*2));      // Clear mode bits for PA5
GPIOA->MODER |= (1<<(5*2));       // Set PA5 as output (01)
GPIOA->OTYPER &= ~(1<<5);         // Push-pull output
GPIOA->OSPEEDR |= (3<<(5*2));     // High speed
GPIOA->PUPDR &= ~(3<<(5*2));      // No pull-up/pull-down

πŸ’‘ LED Blinking Loop

GPIOA->ODR |= (1<<5);             // LED ON
for (int i = 0; i < 1000000; ++i); // Delay
GPIOA->ODR &= ~(1<<5);            // LED OFF
for (int i = 0; i < 1000000; ++i); // Delay

⚠️ Notes

  • This code uses bare-metal programming: no HAL, no interrupts, no external libraries.
  • The LED blinking is based on an inaccurate software delay β€” use hardware timers for better control.
  • PA5 is typically connected to the onboard LED on most STM32F4 boards, but verify your board’s pinout.

βœ… Benefits of Register-Level Programming

  • Smaller binary size
  • Maximum control over hardware
  • Useful for bootloaders or performance-critical code

❌ Limitations

  • No abstraction: less portable
  • More error-prone
  • No safety checks

Register_Level_2 - Button Controlled LED (Bare-Metal GPIO)

This project demonstrates how to control an LED connected to GPIOA Pin 5 using a button connected to GPIOC Pin 13, implemented at the register level (bare-metal) without using the HAL or CMSIS abstraction layers.

πŸ› οΈ Hardware Requirements

  • Development Board: STM32 Nucleo-F446RE
  • Button: Connected to PC13 (typically the blue push button on Nucleo boards)
  • LED: Connected to PA5 (typically the onboard LED)

πŸ’» Software Requirements

  • IDE: STM32CubeIDE
  • No HAL/CMSIS functions used
  • Pure register-level code

πŸš€ Project Functionality

  1. Configures PC13 as a digital input with pull-up resistor.
  2. Configures PA5 as a digital output.
  3. Continuously reads the state of the button:
    • If the button is pressed (PC13 pulled LOW), the LED on PA5 is turned on.
    • If the button is not pressed (PC13 HIGH), the LED is turned off.

πŸ”§ Register Configuration Summary

Button (PC13) Configuration

RCC->AHB1ENR |= (1 << 2);               // Enable clock for GPIOC
GPIOC->MODER &= ~(3 << (13 * 2));       // Set PC13 as input
GPIOC->PUPDR &= ~(3 << (13 * 2));       // Clear pull-up/down bits
GPIOC->PUPDR |= (1 << (13 * 2));        // Enable pull-up

LED (PA5) Configuration

RCC->AHB1ENR |= (1 << 0);               // Enable clock for GPIOA
GPIOA->MODER &= ~(3 << (5 * 2));        // Clear PA5 mode bits
GPIOA->MODER |= (1 << (5 * 2));         // Set PA5 as output
GPIOA->OTYPER &= ~(1 << 5);             // Push-pull
GPIOA->OSPEEDR |= (3 << (5 * 2));       // High speed
GPIOA->PUPDR &= ~(3 << (5 * 2));        // No pull-up/pull-down

πŸ”„ Main Loop Logic

while (1) {
    if (!(GPIOC->IDR & (1 << 13))) {
        GPIOA->ODR |= (1 << 5);  // Turn LED on
    } else {
        GPIOA->ODR &= ~(1 << 5); // Turn LED off
    }
}

⚠️ Notes

  • PC13 is connected to the user button on many Nucleo boards.
  • No debouncing is implemented β€” for real-world use, software or hardware debouncing may be required.
  • You can easily adapt this example to other pins or external buttons/LEDs.

About

Things I tried while learning the STM Nucleo-F446RE

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages