简单理解:嵌入式 USB 基础通信代码

张开发
2026/4/16 15:23:14 15 分钟阅读

分享文章

简单理解:嵌入式 USB 基础通信代码
完整 USB 虚拟串口代码带超详细注释// 包含单片机寄存器定义头文件根据你的芯片型号修改比如stm32f10x.h #include stm32f10x.h // 包含USB驱动库文件标准USB设备库 #include usb_lib.h // 包含USB配置描述符文件定义USB设备信息 #include usb_desc.h // 包含USB接口函数文件 #include usb_pwr.h // 包含串口打印调试文件可选用于调试看信息 #include stdio.h /************************************************* 函数USB_GPIO_Config 功能配置USB接口的GPIO引脚必须先配置引脚才能用USB 参数无 返回值无 *************************************************/ void USB_GPIO_Config(void) { // 定义GPIO初始化结构体用来存引脚配置参数 GPIO_InitTypeDef GPIO_InitStructure; // 1. 开启USB引脚对应的时钟时钟不开引脚无法工作 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 2. 配置USB_D引脚PA12USB通信必须用这个引脚 // 选择要配置的引脚PA12 GPIO_InitStructure.GPIO_Pin GPIO_Pin_12; // 配置为推挽输出模式 GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; // 配置速度为50MHz GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; // 把配置写入寄存器 GPIO_Init(GPIOA, GPIO_InitStructure); // 3. 让USB_D引脚输出低电平USB设备必须拉低D才能被电脑识别 GPIO_ResetBits(GPIOA, GPIO_Pin_12); // 延时一小段时间让电脑识别到USB插入 Delay_Ms(100); // 4. 配置PA12为USB复用功能切换成USB通信模式 GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_Init(GPIOA, GPIO_InitStructure); } /************************************************* 函数USB_Clock_Config 功能配置USB时钟USB必须用48MHz精确时钟 参数无 返回值无 *************************************************/ void USB_Clock_Config(void) { // 开启USB时钟USB模块供电 RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); // 使能USB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); } /************************************************* 函数USB_Init 功能USB总初始化函数调用它就能启动USB 参数无 返回值无 *************************************************/ void USB_Init(void) { // 1. 配置USB引脚 USB_GPIO_Config(); // 2. 配置USB时钟 USB_Clock_Config(); // 3. 复位USB设备让USB模块回到初始状态 USB_Reset(); // 4. 初始化USB设备库核心驱动初始化 USB_Init_Device(); // 5. 加载USB设备描述符告诉电脑我是USB虚拟串口 USB_SetDeviceDescriptor(USB_Device_Descriptor); // 6. 加载USB配置描述符 USB_SetConfigDescriptor(USB_Config_Descriptor); // 7. 启动USB设备开始和电脑通信 USB_Connect(ENABLE); } /************************************************* 函数USB_Send_Data 功能通过USB向电脑发送数据像串口一样发数据 参数buf要发送的数据len数据长度 返回值无 *************************************************/ void USB_Send_Data(uint8_t *buf, uint16_t len) { uint16_t i; // 定义循环变量 // 判断USB是否连接成功没连电脑就不发送避免出错 if(bDeviceState CONFIGURED) { // 循环发送每一个字节的数据 for(i 0; i len; i) { // 等待发送缓冲区为空上一个数据发完再发下一个 while(USB_TxStatus() 0); // 发送一个字节数据到电脑 USB_SendByte(buf[i]); } } } /************************************************* 函数USB_Receive_Data 功能从电脑接收数据 参数buf存接收数据的数组 返回值接收到的数据长度 *************************************************/ uint16_t USB_Receive_Data(uint8_t *buf) { uint16_t len 0; // 记录接收到的数据长度 // 判断是否有数据收到 if(USB_RxBytes() 0) { // 读取接收到的所有数据 len USB_ReceivePacket(buf); } // 返回数据长度 return len; } /************************************************* 函数main 功能主函数程序入口 *************************************************/ int main(void) { uint8_t send_buf[] Hello USB我是嵌入式USB设备\n; // 发送数据缓存 uint8_t recv_buf[64]; // 接收数据缓存 uint16_t recv_len; // 接收数据长度 // 1. 系统时钟初始化单片机最基础配置 SystemInit(); // 2. 延时函数初始化用来延时 Delay_Init(); // 3. USB初始化启动USB USB_Init(); // 4. 无限循环嵌入式程序永远在循环里运行 while(1) { // 发送数据到电脑 USB_Send_Data(send_buf, sizeof(send_buf)); // 接收电脑发来的数据 recv_len USB_Receive_Data(recv_buf); // 如果收到数据 if(recv_len 0) { // 把收到的数据发回电脑回声功能 USB_Send_Data(recv_buf, recv_len); } // 延时500毫秒 Delay_Ms(500); } }小白必看说明非常重要1. 这个代码能实现什么单片机 USB 插电脑 → 电脑会多出一个串口单片机自动发送Hello USB我是嵌入式USB设备电脑发数据给单片机 → 单片机会原样发回来回声测试2. 代码怎么用把代码复制到你的 STM32 工程里下载到单片机用 USB 线连接单片机和电脑打开电脑串口助手 → 就能看到 USB 通信数据3. 小白最容易踩的坑必须用支持 USB 的单片机STM32F103C8T6/STM32F407 都可以USB 必须接DPA12和 D-PA11电脑会自动安装驱动不需要你手动装代码里的stm32f10x.h要换成你芯片对应的头文件

更多文章