一、USB相关介绍

通用串行总线(英语:Universal Serial Bus,缩写:USB)是一种串口总线标准,也是一种输入输出接口的技术规范,被广泛地应用于个人电脑和移动设备等信息通讯产品,并扩展至摄影器材、数字电视(机顶盒)、游戏机等其它相关领域。最新一代是USB4,传输速度为40Gbit/s。
stm32f103单片机内部自带USB外设,但是最高只支持USB2.0,并且只可以作为从设备来使用。

从电路原理、所用元器件来看,USB可以直接连单片机,
但是,我们设计单片机的串口电路时候,通常在USB和单片机(使用串口功能)之间会添加一个串口转换转换芯片(比如CH340等),
USB接口可以衍化出很多高级功能,远远比串口通信功能强大得多。

二、cubeMX配置

1.时钟配置

2.USB硬件参数配置


3.USB驱动程序配置




只会影响电脑上的设备属性,不影响使用。

4.重新设置堆栈空间大小

三、驱动程序的修改


此时生成的初始化和中断的代码已经生成,用户发送和接收数据只需要调用两个函数就可以(也可以进行修改,实现自定义的通讯协议和功能)

in8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
uin8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);

类似于串口功能中的发送和接收一个字节数据的串口相关函数。

主要修改下图中的两个文件

1.接收和发送的相关协议修改配置

注:以下是在usbd_desc.c文件中修改

1)定义接收缓存区USB_RX_BUF和自定义接收标志USB_RX_STA

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t USB_RX_BUF[USB_REC_LEN];//接收缓冲,最大USB_REC_LEN个字节.
uint16_t USB_RX_STA=0;//接收状态标记(接收到的有效字节数量)
/* USER CODE END PV */

2)将接收到的数据一一放进缓存区中

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{/* USER CODE BEGIN 6 */if(*Len<USB_REC_LEN)//判断收到数据量是否小于寄存器上限{uint16_t i;USB_RX_STA = *Len;//将数据量值放入标志位for(i=0;i<*Len;i++)//循环(循环次数=数据数量)USB_RX_BUF[i] = Buf[i];//将数据内容放入数据寄存器}USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);  //将接收数组buff清空USBD_CDC_ReceivePacket(&hUsbDeviceFS);  //再次开启虚拟串口接收return (USBD_OK);/* USER CODE END 6 */
}

3)将需要发送的数据发送(先判断空闲才能发送,调用的都是底层寄存器)

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{uint8_t result = USBD_OK;/* USER CODE BEGIN 7 */uint32_t TimeStart = HAL_GetTick();USBD_CDC_HandleTypeDef *hcdc =  (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;//if (hcdc->TxState != 0) return  USBD_BUSY;while(hcdc->TxState){if(HAL_GetTick()-TimeStart > 10)return USBD_BUSY;elsebreak;}USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf,  Len);result =  USBD_CDC_TransmitPacket(&hUsbDeviceFS);TimeStart = HAL_GetTick();while(hcdc->TxState){if(HAL_GetTick()-TimeStart > 10)return USBD_BUSY;}/* USER CODE END 7 */return result;
}

4)自定义USB_printf()发送函数

/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
#include <stdarg.h>
void USB_printf(const char *format, ...)//USB模拟串口的打印函数
{va_list args;uint32_t length;va_start(args, format);length = vsnprintf((char  *)UserTxBufferFS, APP_TX_DATA_SIZE, (char  *)format, args);va_end(args);CDC_Transmit_FS(UserTxBufferFS, length);
}
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */

2.头文件中相关修改

注:以下是在usbd_desc.h文件中修改

/* USER CODE BEGIN INCLUDE */
#define USB_REC_LEN   200//定义USB串口最大接收字节数
extern uint8_t USB_RX_BUF[USB_REC_LEN];//接收缓冲,最大USB_REC_LEN个字节.末字节为换行符
extern uint16_t USB_RX_STA;//接收状态标记(接收到的有效字节数量)
/* USER CODE END INCLUDE */

自定义函数声明

/* USER CODE BEGIN EXPORTED_FUNCTIONS */
void USB_printf(const char *format,  ...);//USB模拟串口的打印函数
/* USER CODE END EXPORTED_FUNCTIONS */

四、main.c中应用程序的修改

1.头文件的包含

/* USER CODE BEGIN Includes */
#include "../../USB_DEVICE/App/usbd_cdc_if.h"
#include "../../icode/led/led.h"
/* USER CODE END Includes */

2.while()中循环

     //USB模拟串口的查寻接收处理(其编程原理与USART1串口收发相同)if(USB_RX_STA!=0)//判断是否有数据{USB_printf("USB_RX:");//向USB模拟串口发送字符串CDC_Transmit_FS(USB_RX_BUF,USB_RX_STA);//USB串口发送:将接收的数据发回给电脑端(参数1是数据内容,参数2是数据量)USB_printf("\r\n");//向USB模拟串口发送字符串(回车)USB_RX_STA=0;//数据标志位清0memset(USB_RX_BUF,0,sizeof(USB_RX_BUF));//USB串口数据寄存器清0}

五、实验现象

可以像之前的串口程序一样使用,但是上位机的波特率似乎是任意值,都可以正常使用。

12_STM32Cubeide开发_USB从设备串口驱动程序相关推荐

  1. 【TX2】TX2开发板系统默认串口有ttyS0(调试口)、ttyTHS1、ttyTHS2、ttyTHS3,通过修改设备树文件,可以新增三个串口

    1.简述 TX2开发板系统默认串口有ttyS0(调试口).ttyTHS1.ttyTHS2.ttyTHS3,通过修改设备树文件,可以新增三个串口. 2.设备树 设备树中关于串口部分的描述 2.1 基础配 ...

  2. Linux串口驱动程序(3)-打开设备

    先来分析一下串口打开的过程: 1.用户调用open函数打开串口设备文件: 2.在内核中通过tty子系统,把open操作层层传递到串口驱动程序中: 3.在串口驱动程序中的xx_open最终实现这个操作. ...

  3. PCI设备WINDOWS驱动程序的开发

    PCI设备WINDOWS驱动程序的开发 摘要:本文主要介绍了在Windows9x操作系统下开发PCI设备驱动程序的方法. 关键词:PCI设备 驱动程序 PCI设备概述 近几年来,随着诸如图形处理.图像 ...

  4. 驱动开发基础知识——设备树

    BSP开发工程师[原来BSP就是那些被指臃肿的文件啊 BSP的出生 Linux经过不断的发展,原先嵌入式系统的三层结构逐步演化成为一种四层结构. 这个新增加的中间层次位于操作系统和硬件之间,包含了系统 ...

  5. 基于android的串口开发板,210开发板Android系统串口程序

    最近由于项目需要,花了两天时间在Android平台下编写了一个串口助手软件.硬件平台是友善之臂的tiny210开发板.起初的想法是首先基于Linux驱动做一些修改,然后自行编写HAL层代码,最后编写A ...

  6. Linux USB 驱动开发(五)—— USB驱动程序开发过程简单总结

    http://blog.csdn.net/zqixiao_09/article/details/51057086 设备驱动程序是操作系统内核和机器硬件之间的接口,由一组函数和一些私有数据组成,是应用程 ...

  7. Linux内核深入理解中断和异常(8):串口驱动程序

    Linux内核深入理解中断和异常(8):串口驱动程序 rtoax 2021年3月 /*** start_kernel()->setup_arch()->idt_setup_early_tr ...

  8. linux驱动基础开发1——linux 设备驱动基本概念-转

    学习linux设备驱动首先我们必须明确以下几个概念,为我们接下来学习linux驱动打下坚实的基础: 应用程序.库.内核.驱动程序的关系 设备类型 设备文件.主设备号与从设备号 驱动程序与应用程序的区别 ...

  9. linux uart应用开发(ttyS*设备)

    写这篇文章的原因:因为在linux开发串口应用的时候,遇到了问题,让遇到相同问题的人少走点弯路: ①读串口数据的时,需要接受换行符才能返回. ②接受数据时,一个字节一个字节的返回.无法接受完多个字节在 ...

最新文章

  1. 张一鸣的微博世界-产品篇二
  2. python中安装一个第三方库的命令格式是-无法使用pip命令安装python第三方库的彻底解决方案...
  3. vue中使用第三方UI库的移动端rem适配方案
  4. sql三表连接查询 - 使用sqlite 演示
  5. Nginx-rtmp直播之业务流程分析--比较详细
  6. 导致oracle 控制文件坏,异常断电导致ORACLE控制文件等受到破坏的处理
  7. 使用anconada 的conda更换环境
  8. 【转】DCM(DICOM)医学影像文件格式详解
  9. 结合源代码分析一个完整的中断过程【转】
  10. [译]Java 设计模式之组合
  11. 大学计算机word操作教程,word技巧大全:73个word实用技巧分享-电脑教程
  12. 2022年江西理工大学软件工程学院程序设计竞赛C++题解
  13. 编程题——真题训练一(WYYX)
  14. uploadify--上传文件控件
  15. 房价基本上决定于货币政策.----看中国货币发行量增长
  16. Python学习摘录(自用)
  17. 【转载】为什么样本方差(sample variance)的分母是 n-1?
  18. 数学上的一些小技巧韩信点兵的问题
  19. 计算机视觉(视频追踪检测分类、监控追踪)常用测试数据集
  20. 语音识别之语音激活(VAD)检测(一)

热门文章

  1. 关于Android中RSA数字签名的理解及使用
  2. 坚果云网盘教你拥有这5个习惯 升职加薪不是梦
  3. 再次携号转网_全国携号转网真来了!这些坑一定要小心!
  4. C语言文件英文,c语言文件操作(国外英文资料).doc
  5. 符号链接symlink_什么是符号链接或符号链接? 如何为Windows和Linux创建Symlink?
  6. Latex写创新作业
  7. 港科夜闻|香港科大彭倩教授分析疫情下企业如何减低投资损失
  8. 基于FPGA的并行PRBS实现方法
  9. MIPI CSI-2笔记(12) -- Low Level Protocol(数据加扰,扰码,Data Scrambling)
  10. 8.3 bert的蒸馏方法概述