Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Development Boards & SBCs

STM32 USB CDC Virtual COM Port: PC Communication Tutorial

STM32 USB CDC Virtual COM Port: PC Communication Tutorial

March 11, 2026 /Posted byJayesh Jain / 0

Setting up STM32 USB CDC (Communications Device Class) allows your STM32 microcontroller to communicate with a PC over USB, appearing as a Virtual COM Port (VCP). No USB-to-UART bridge chip is needed — the STM32’s built-in USB peripheral handles it all. This is ideal for logging data, configuration interfaces, and firmware update without extra hardware. This tutorial covers complete USB CDC Virtual COM Port setup on STM32 using STM32CubeMX and HAL library.

Table of Contents

  • What is USB CDC Virtual COM Port?
  • Supported STM32 Devices
  • STM32CubeMX USB CDC Setup
  • Transmitting Data to PC
  • Receiving Data from PC
  • Redirecting printf to USB CDC
  • Troubleshooting and Tips
  • Frequently Asked Questions

What is USB CDC Virtual COM Port?

USB CDC (Communications Device Class) is a USB standard that makes a USB device appear as a serial COM port to the operating system. When you plug in a STM32 with USB CDC firmware, Windows/Linux/macOS installs a driver that creates a virtual COM port (COMx on Windows, /dev/ttyACMx on Linux).

Benefits over UART + USB-Serial bridge:

  • No extra hardware: Eliminates CH340G, CP2102, or FTDI USB-serial converter
  • Higher speed: USB 1.1 full-speed supports 12 Mbps vs UART’s typical 115200 bps
  • Cost savings: Remove USB-serial bridge IC from PCB design
  • Device power: Can power STM32 from USB bus (up to 500mA from USB 2.0)

Supported STM32 Devices

USB CDC requires STM32 with built-in USB Full-Speed peripheral. Key supported series:

  • STM32F1xx: F103 series (very common in India, used in Blue Pill boards)
  • STM32F4xx: F407, F429, F446 — all support USB FS (and some have USB HS)
  • STM32F2xx, F3xx, L4xx, G0xx: Most variants with USB peripheral
  • STM32 Blue Pill (F103C8T6): Very popular in India, has USB D+ (PA12) and D- (PA11) pins

Check your STM32 reference manual for “USB full-speed” in the feature list. STM32 without USB (like some F0 variants) cannot implement CDC.

Recommended: Arduino UNO R3 CH340G Development Board — Understand USB-to-serial communication on Arduino before implementing native USB CDC on STM32.

STM32CubeMX USB CDC Setup

  1. Open your .ioc file in STM32CubeIDE
  2. Go to Connectivity → USB → Enable USB peripheral (Device FS)
  3. Go to Middleware → USB Device → Select Class: Communication Device Class (CDC)
  4. Configure USB clock (must be exactly 48 MHz):
    • STM32F4: In Clock Configuration, set USB/SDIO clock to 48 MHz from PLL
    • STM32F1: HSE or PLL must produce 48 MHz for USB clock
  5. Generate Code

CubeMX generates USB_DEVICE/App/usbd_cdc_if.c — this is where you implement TX and RX.

Transmitting Data to PC

/* usbd_cdc_if.c is generated by CubeMX */
/* To send data, use CDC_Transmit_FS() */

#include "usbd_cdc_if.h"
#include <stdio.h>
#include <string.h>

/* Send a simple string */
void USB_SendString(const char* str) {
    /* Wait until USB is ready */
    uint32_t timeout = 1000;
    while (CDC_Transmit_FS((uint8_t*)str, strlen(str)) == USBD_BUSY && timeout--) {
        HAL_Delay(1);
    }
}

/* Send formatted data (like printf to USB) */
char txBuf[256];

void USB_Printf(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    int len = vsnprintf(txBuf, sizeof(txBuf), fmt, args);
    va_end(args);
    
    if (len > 0) {
        uint32_t timeout = 1000;
        while (CDC_Transmit_FS((uint8_t*)txBuf, len) == USBD_BUSY && timeout--) {
            HAL_Delay(1);
        }
    }
}

/* Usage in main.c */
int main(void) {
    /* ... init code ... */
    
    float temperature = 28.5;
    int count = 0;
    
    while (1) {
        USB_Printf("Count: %d, Temp: %.1f°C
", count++, temperature);
        HAL_Delay(1000);
    }
}

Receiving Data from PC

/* In usbd_cdc_if.c, modify CDC_Receive_FS callback */
/* This function is called when data arrives from PC */

#define RX_BUFFER_SIZE 64
uint8_t usbRxBuffer[RX_BUFFER_SIZE];
uint16_t usbRxLen = 0;
volatile uint8_t usbRxReady = 0;

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
    /* Copy received data */
    usbRxLen = *Len;
    memcpy(usbRxBuffer, Buf, usbRxLen);
    usbRxReady = 1;
    
    /* Re-arm reception */
    USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
    USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    return (USBD_OK);
}

/* In main.c, check for received data */
while (1) {
    if (usbRxReady) {
        usbRxReady = 0;
        usbRxBuffer[usbRxLen] = '';  /* Null-terminate */
        
        /* Process received command */
        if (strncmp((char*)usbRxBuffer, "LED_ON", 6) == 0) {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
            USB_SendString("LED turned ON
");
        }
        else if (strncmp((char*)usbRxBuffer, "LED_OFF", 7) == 0) {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
            USB_SendString("LED turned OFF
");
        }
    }
}

Redirecting printf to USB CDC

/* Add to usbd_cdc_if.c or a separate file */
/* This redirects all printf() calls to USB CDC */

#include <stdio.h>
#include "usbd_cdc_if.h"

int _write(int file, char *ptr, int len) {
    /* Called by printf/puts for stdout */
    uint32_t timeout = 5000;
    
    /* Wait for USB ready */
    while (CDC_Transmit_FS((uint8_t*)ptr, len) == USBD_BUSY) {
        if (--timeout == 0) return -1;
        HAL_Delay(1);
    }
    return len;
}

/* In project settings (Keil/GCC): enable --specs=nosys.specs or link with syscalls.c */
/* Then in main.c you can use printf normally: */

printf("Temperature: %.2f°C
", temp);
printf("ADC Value: %d
", adcValue);

Troubleshooting and Tips

  • COM port not appearing: Verify 48 MHz USB clock. In STM32CubeIDE, check Clock Configuration — USB clock must show exactly 48 MHz
  • STM32 Blue Pill (F103): Many Blue Pill clones have wrong 10kΩ pull-up on BOOT0 — check that PA12 (USB D+) has a 1.5kΩ pull-up to 3.3V for USB enumeration
  • Transmit BUSY error: Call CDC_Transmit_FS from main loop only, not from ISR. USB stack is not ISR-safe.
  • Linux permissions: Add user to dialout group: sudo usermod -a -G dialout $USER then logout/login
  • India Windows 10/11: Windows automatically installs CDC driver if it’s a standard CDC device. No driver download needed.
  • Disconnect detection: Check USB plug event: USBD_CDC_HandleTypeDef->TxState to detect if PC is connected
Recommended: Waveshare ESP32-S3-Nano Development Board — ESP32-S3 also supports native USB CDC via the native USB OTG interface — another option for USB serial projects.

Frequently Asked Questions

Does STM32 USB CDC work on Windows 11 without additional drivers?

Yes — Windows 10 and 11 include built-in USB CDC driver (usbser.sys). Your STM32 CDC device should enumerate automatically as a COM port without any driver installation, provided the firmware is correctly configured as a standard CDC device.

What is the maximum data rate with STM32 USB CDC?

USB Full Speed (12 Mbps raw) with CDC overhead achieves approximately 1–2 Mbps effective throughput. The CDC_Transmit_FS function can send up to 64 bytes per USB packet. For maximum throughput, batch data into large chunks rather than sending many small packets.

Can I use USB CDC on STM32 Blue Pill (F103C8T6)?

Yes — Blue Pill has USB D+ on PA12 and D- on PA11. The main issue with clone Blue Pills is a wrong pull-up resistor value on PA12 (should be 1.5kΩ to 3.3V for USB enumeration, but some clones have 10kΩ or wrong placement). Check or replace this resistor if USB doesn’t enumerate.

How do I identify which COM port is my STM32 on Windows?

Open Device Manager (Win+X → Device Manager) → Ports (COM & LPT). Your STM32 will appear as “STMicroelectronics Virtual COM Port” or similar. The COMxx number is what you use in your terminal (PuTTY, CoolTerm, Arduino Serial Monitor).

Is it safe to draw power from USB for STM32 projects?

USB 2.0 provides 500mA at 5V. STM32F103 at 72 MHz draws ~50–100mA. With peripherals, stay under 400mA total to be safe. For projects exceeding this, use a separate power supply and connect only USB D+/D- to the STM32 for communication.

Shop Development Boards at Zbotic →

Tags: STM32, STM32CubeMX, USB CDC, USB communication, Virtual COM Port
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
PID Controller Tuning: Auto-Tu...
blog pid controller tuning auto tune vs manual for industry 598352
blog ir to wifi bridge use old ir remotes with google home 598358
IR to WiFi Bridge: Use Old IR ...

Related posts

Svg%3E
Read more

Battery Charger Module TP4056: LiPo and 18650 Charging Guide

April 1, 2026 0
The TP4056 battery charger module is one of the most essential components for any battery-powered electronics project. Costing under ₹30,... Continue reading
Svg%3E
Read more

Buck Converter vs Boost Converter: Voltage Regulation Guide

April 1, 2026 0
Understanding buck converters vs boost converters is essential for every electronics project involving power management. Whether you are stepping down... Continue reading
Svg%3E
Read more

Google Coral TPU: Accelerating AI Projects on Raspberry Pi

April 1, 2026 0
The Google Coral TPU (Tensor Processing Unit) transforms a Raspberry Pi from a sluggish AI hobbyist tool into a real-time... Continue reading
Svg%3E
Read more

NVIDIA Jetson Nano Projects India: Getting Started Guide

April 1, 2026 0
The NVIDIA Jetson Nano is the most accessible GPU-accelerated AI computer for developers in India. With 128 CUDA cores, a... Continue reading
Svg%3E
Read more

ATtiny85 Projects: Tiny Microcontroller for Space-Constrained Builds

April 1, 2026 0
The ATtiny85 is the Swiss Army knife of tiny microcontrollers — just 8 pins, 8 KB of flash, and a... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now