Using SWD (Serial Wire Debug) for debugging [STM32](https://www.ampheo.com/search/STM32) [microcontrollers](https://www.ampheo.com/c/microcontrollers) is a powerful way to monitor and control code execution, inspect registers, and analyze faults. Here’s a step-by-step guide to set up and use SWD effectively:

**1. Hardware Setup**
**Required Components:**
STM32 Board (e.g., [STM32F4](https://www.ampheo.com/search/STM32F4) Discovery, Nucleo, or custom PCB).
Debug Probe:
* ST-Link (built-in on Nucleo boards) or J-Link (faster, more features).
* CMSIS-DAP (open-source alternative).
Connections:
4-Wire SWD:

Note: Some boards omit VCC if powered separately.
**Wiring Example:**
```
ST-Link (V2) → STM32
SWDIO → PA13
SWCLK → PA14
GND → GND
3.3V (optional) → VDD
```
**2. Software Configuration**
**IDE Setup (STM32CubeIDE/Keil/IAR):**
1. Install Drivers:
* ST-Link drivers (from ST’s website).
* J-Link drivers (if using Segger).
2. Project Configuration:
In STM32CubeIDE:
* Right-click project → Debug As → STM32 Cortex-M C/C++ Application.
* Select ST-Link (SWD) as the debug probe.
In Keil/IAR:
Set debugger to ST-Link and interface to SWD in project options.
3. Enable Debug in Code:
* Ensure debug pins (PA13/PA14) are not accidentally configured as GPIOs in HAL_Init().
* Use __HAL_AFIO_REMAP_SWJ_DISABLE() only if SWD is needed without JTAG.
**3. Basic Debugging Features**
**A. Breakpoints & Step Execution**
* Set breakpoints by clicking the gutter in your IDE.
* Use Step Into (F5), Step Over (F6), and Resume (F8) to control flow.
**B. Register/Memory Inspection**
* View peripheral registers (e.g., GPIOA->ODR) in Register View.
* Monitor variables in Live Watch or Expressions tab.
**C. Peripheral Debugging**
Use STM32CubeMonitor to visualize ADC, PWM, or UART data in real-time.
**4. Advanced Techniques**
**A. Serial Wire Viewer (SWV) for printf Debugging**
1. Enable ITM (Instrumentation Trace Macrocell) in STM32CubeMX:
Enable Trace Asynchronous Sw under System Core > SYS.
2. Add this code to redirect printf:
```
c
#include <stdio.h>
int _write(int fd, char *ptr, int len) {
ITM_SendChar(*ptr); // Send via SWO
return len;
}
```
3. View output in:
* STM32CubeIDE: Window → SWV → SWV ITM Data Console.
* Teraterm: Configure SWO viewer with correct baud rate.
**B. Fault Analysis**
HardFault Debugging:
* Check SCB->CFSR (Configurable Fault Status Register) for fault cause (e.g., IMPRECISERR = bus access error).
* Use STM32CubeIDE’s Fault Analyzer to decode the call stack.
**C. RTOS Debugging (FreeRTOS/ThreadX)**
Enable RTOS-aware debugging in IDE:
View task states, queues, and stacks in System Viewer.
**5. Common Issues & Fixes**

**6. Tools & Alternatives**
OpenOCD: Open-source debugging (useful with ST-Link/V2).
```
bash
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
```
J-Link Commander: Advanced memory access (Segger tools).
Black Magic Probe: SWD over USB-UART.
**Example Workflow**
1. Connect ST-Link to STM32 via SWD.
2. Load firmware and start debugging.
3. Set breakpoints in critical code (e.g., ISRs).
4. Inspect variables and peripherals.
5. Use SWV for real-time logging.
Pro Tip: Combine SWD with logic analyzers (Saleae) to debug timing-sensitive protocols (SPI/I2C) simultaneously.