STM32F103C6 — UART Communication, ADC Reading & Command Protocol FSM
| Student | Dang Thai Khang — 2352464 |
| Course | C03010 — CC02 |
| Institution | Ho Chi Minh University of Technology (HCMUT) |
| Lecturer | Phan Van Sy |
| Semester | 2025 |
This lab implements a UART-based command-response protocol on the STM32F103C6. The MCU reads an ADC sensor value and communicates it over UART using a structured message format. The system uses two FSMs: one for parsing incoming commands and one for managing the communication flow (with retry/timeout logic).
- MCU: STM32F103C6 (ARM Cortex-M3)
- IDE: STM32CubeIDE (HAL Library)
- Simulation: Proteus 8
- Language: C
- Peripherals: USART2 (9600 baud), ADC1 (Channel 0), GPIO
VXL_VDK_Lab_5_2352464/
└── FULL_EXERCISE/
├── Lab_5.c # Main program (UART ISR, ADC init, main loop)
├── Lab_5.hex # Compiled firmware for Proteus
├── Lab_5.pdsprj # Proteus schematic & simulation
└── Core/
├── Inc/
│ ├── command_parser_fsm.h # Command parser header
│ └── uart_communication_fsm.h # UART comm FSM header
└── Src/
├── command_parser_fsm.c # Parses "!RST#" and "!OK#" commands
└── uart_communication_fsm.c # UART state machine with retry logic
The system uses a simple request-response protocol over UART:
PC → STM32: "!RST#" (Request ADC reading)
STM32 → PC: "!ADC=<value>#" (Respond with ADC value)
PC → STM32: "!OK#" (Acknowledge receipt)
- All messages start with
!and end with# - Commands:
!RST#(request),!OK#(acknowledge) - Response:
!ADC=XXXX#where XXXX is the raw 12-bit ADC value (0–4095)
Incoming buffer
├── contains "!RST#" → command_flag = 1 (request)
└── contains "!OK#" → command_flag = 2 (acknowledge)
State 0: IDLE
│ command_flag == 1 (RST received)
│ → Read ADC, send "!ADC=value#", start timeout
▼
State 1: WAIT_ACK
├── command_flag == 2 (OK received) → back to State 0
└── timeout (3 seconds) → retransmit same ADC value, reset timeout
HAL_UART_RxCpltCallback()
→ Append byte to buffer
→ If byte == '#' → set buffer_flag = 1
→ Re-enable interrupt for next byte
- Initializes UART2 (9600/8N1), ADC1 (Channel 0, continuous), GPIO
- UART RX interrupt fills a 30-byte circular buffer
- Main loop: LED heartbeat (500ms), command parsing, UART FSM
- Uses
strstr()to detect!RST#and!OK#in the receive buffer - Sets
command_flagfor the communication FSM to act on
- State 0 (IDLE): Waits for RST command, then reads ADC and sends response
- State 1 (WAIT_ACK): Waits for OK acknowledgment, retransmits after 3s timeout
- Open
FULL_EXERCISE/Lab_5.pdsprjin Proteus 8+ - Load
Lab_5.hexinto the STM32 component - Click Run — use the Virtual Terminal to send
!RST#and!OK#
- Create STM32F103C6 project in STM32CubeIDE
- Enable USART2 (9600 baud, TX/RX), ADC1 (Channel 0), GPIO PA5 output
- Copy source files and build
- Connect via USB-UART adapter, open serial terminal at 9600 baud
| Parameter | Value |
|---|---|
| Baud Rate | 9600 |
| Word Length | 8 bits |
| Stop Bits | 1 |
| Parity | None |
| Flow Control | None |
| Mode | TX + RX (interrupt-driven RX) |
The full lab report (PDF) with schematics, protocol diagrams, and source code explanations is available in the course submission.
This project is developed for educational purposes as part of the Microprocessors & Microcontrollers course at HCMUT.