USB的协议其实是很复杂的,如果要深入学习估计要一两年才能熟悉透。本文主要是讲如何使用官方已经写好的库进行二次开发,以达到我们自己使用的目的。我们知道USB可以用来接U盘,声卡,读卡器,鼠标键盘等等,这里主要是讲USB接口用来当虚拟串口使用,这个VCP(虚拟串口)是通过USB的CDC(通信设备类)类来实现的,本文是基于CPU是STM32F4的USB来讲解的:

1.安装和使用STM32 CubeMx软件:

该软件是STM官方提供的图形化配置底层驱动的软件,可生成工程与代码,可去官方下载安装:

1)安装后如下界面:

2)接下来再点击菜单栏中的help选择安装库:

我们使用的是F4的底层库,该库为HAL库,不再是以前STM32的标准库,大约到2014年左右,ST在标准库的基础上又推出了HAL库。实际上,HAL库和标准库本质上是一样的,都是提供底层硬件操作API,而且在使用上也是大同小异。有过标准库基础的同学对HAL库的使用也很容易入手。个人认为ST官方之所以这几年大力推广HAL库,是因为HAL的结构更加容易整合STM32Cube,而STM32CubeMX是ST这几年极力推荐的程序生成开发工具。所以这两年新出的STM32芯片,ST直接只提供HAL库。在新型的STM32芯片中,用HAL库逐步淘汰标准库。

3)选择自己的mcu型号,选择好后双击打开:

4)配置RCC,USB等:

5)配置时钟树,根据自己硬件情况:

6)点击工具栏的生成代码工具,注意填写的堆栈空间要大一点,防止空间不够的意外:

点击OK后生成工程代码,可以下载测试验证,接下我们来分析生成的代码,并修改成自己想要的:

2.分析与修改代码:

1)生成的代码我们首先来看,初始化USB功能的

点击其中的Init

这里是关键,主要的功能是把CDC类的功能和我们用户要调用的_fops_FS函数都注册到USB的设备类里,这样在USB内核运行的时候就会调动我们注册进去的函数,点击USBD_Interface_fops_FS进去,这里面的函数指针 指向的函数就是我们需要使用和修改的了

函数在如下文件中:

2)我们修改这个文件:

首先在里面定义个串口属性的结构体:

USBD_CDC_LineCodingTypeDef linecoding =

{

USB_VIRTUAL_COM_BAUDRATE, /* baud rate*/

0x00,   /* stop bits-1*/

0x00,   /* parity - none*/

0x08    /* nb. of bits 8*/

};

然后修改CDC_Control_FS函数:

{

/* USER CODE BEGIN 5 */

switch (cmd)

{

case CDC_SEND_ENCAPSULATED_COMMAND:

break;

case CDC_GET_ENCAPSULATED_RESPONSE:

break;

case CDC_SET_COMM_FEATURE:

break;

case CDC_GET_COMM_FEATURE:

break;

case CDC_CLEAR_COMM_FEATURE:

break;

/*******************************************************************************/

/* Line Coding Structure                                                       */

/*-----------------------------------------------------------------------------*/

/* Offset | Field       | Size | Value  | Description                          */

/* 0      | dwDTERate   |   4  | Number |Data terminal rate, in bits per second*/

/* 4      | bCharFormat |   1  | Number | Stop bits                            */

/*                                        0 - 1 Stop bit                       */

/*                                        1 - 1.5 Stop bits                    */

/*                                        2 - 2 Stop bits                      */

/* 5      | bParityType |  1   | Number | Parity                               */

/*                                        0 - None                             */

/*                                        1 - Odd                              */

/*                                        2 - Even                             */

/*                                        3 - Mark                             */

/*                                        4 - Space                            */

/* 6      | bDataBits  |   1   | Number Data bits (5, 6, 7, 8 or 16).          */

/*******************************************************************************/

case CDC_SET_LINE_CODING:

linecoding.bitrate    = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\

(pbuf[2] << 16) | (pbuf[3] << 24));

linecoding.format     = pbuf[4];

linecoding.paritytype = pbuf[5];

linecoding.datatype   = pbuf[6];

/* Add your code here */

break;

case CDC_GET_LINE_CODING:

pbuf[0] = (uint8_t)(linecoding.bitrate);

pbuf[1] = (uint8_t)(linecoding.bitrate >> 8);

pbuf[2] = (uint8_t)(linecoding.bitrate >> 16);

pbuf[3] = (uint8_t)(linecoding.bitrate >> 24);

pbuf[4] = linecoding.format;

pbuf[5] = linecoding.paritytype;

pbuf[6] = linecoding.datatype;

/* Add your code here */

break;

case CDC_SET_CONTROL_LINE_STATE:

break;

case CDC_SEND_BREAK:

break;

default:

break;

}

return (USBD_OK);

/* USER CODE END 5 */

}

3)基本配置完毕,接下来就是发送和接收的,发送主要调用CDC_Transmit_FS函数:

示例:

很简单吧,由于我们的USB是从端,PC是主端,这里发送最后是写入到一个BUF里,PC会主动过来查询并读取.

继续看接收,接收的我们在CDC_Receive_FS函数加入自己的代码即可

示例:

到此,我们就完成了USB的配置,发送,接收等,最后看下效果:

PC装上stm的官方USB VCP驱动,然后连上电脑:

通信结果OK:

USB驱动之CDC类的介绍与应用20160905的更多相关文章

  1. CDC类介绍

    CDC类 中文介绍 CDC类定义的是设备上下文对象的类. CDC对象提供处理显示器或打印机等设备上下文的成员函数,以及处理与窗口客户区对应的显示上下文的成员. 通过CDC对象的成员函数进行所有的绘图. ...

  2. USB CDC类

    现代嵌入式系统中,异步串行通信接口往往作为标准外设出现在单片机和嵌入式系统中.但是随着个人计算机通用外围设备越来越少地使用串口,串口正在逐渐从个人计算机特别是便携式电脑上消失.于是嵌入式开发人员常常发 ...

  3. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  4. Linux USB驱动框架分析【转】

    转自:http://blog.csdn.net/jeffade/article/details/7701431 Linux USB驱动框架分析(一) 初次接触和OS相关的设备驱动编写,感觉还挺有意思的 ...

  5. linux usb驱动记录(一)

    一.linux 下的usb驱动框架 在linux系统中,usb驱动可以从两个角度去观察,一个是主机侧,一个是设备侧.linux usb 驱动的总体框架如下图所示:   从主机侧看usb驱动可分为四层: ...

  6. HarmonyOS USB DDK助你轻松实现USB驱动开发

    HDF(Hardware Driver Foundation)驱动框架是HarmonyOS硬件生态开放的基础,为开发者提供了驱动加载.驱动服务管理和驱动消息机制等驱动能力,让开发者能精准且高效地开发驱 ...

  7. extcon驱动及其在USB驱动中的应用

    extcon,是External Connector的简称,用于抽象外部连接器,比如说Audio Jack.USB MicroB/TypeC接口等.它的原型是Android的switch-class驱 ...

  8. usb驱动开发15之设备生命线

    总算是进入了HCD的片儿区,既然来到一个片区,怎么都要去拜会一下山头几个大哥吧.,先回忆一些我们怎么到这里的?给你列举一个调用函数过程usb_control_msg->usb_internal_ ...

  9. usb驱动开发1之学习准备

    此系列是http://blog.csdn.net/fudan_abc/博文的整理,同时加入了自己的理解.很敬佩fudan_abc的文章,仔细学习和分析受益很多.注:fundan_abc所分析linux ...

随机推荐

  1. 【SpringBoot】集成 Web Flux

    前言: 必需学会SpringBoot基础知识 简介: Takes an opinionated view of building production-ready Spring application ...

  2. Phaser3 场景Scene之间的传值 -- HTML JAVASCRIPT 网页游戏开发

      PHASERJS3 一.首先当然得有至少有二个场景sceneA.js,sceneB.js 二.从场景A传值到场景B二种方法 1)通过事件this.events.emit('event key',{ ...

  3. 洛谷【P1052】过河

    https://www.luogu.org/problemnew/show/P1052 题目描述 在河上有一座长度为 L 的独木桥, 一只青蛙想沿着独木桥从河的一侧跳到另一侧. 在桥上有一些石子, 青 ...

  4. 十大经典排序算法总结 (Python)

    作业部落:https://www.zybuluo.com/listenviolet/note/1399285 以上链接是自己在作业部落编辑的排序算法总结- Github: https://github ...

  5. Python坑系列:可变对象与不可变对象

    在之前的文章 http://www.cnblogs.com/bitpeng/p/4748148.html 中,大家看到了ret.append(path) 和ret.append(path[:])的巨大 ...

  6. Right-BICEP 测试四则运算程序

    测试方法:      Right-BICEP 测试计划: 1.边界测试是否正确 2.负数表示是否实现 3.是否有乘除法 4.是否可以选择题目数量 5.是否有输出方式 6.是否有括号 7.是否有重复查询 ...

  7. vue cli3 配置postcss

    1.安装postcss-import,postcss-cssnext 包 2.修改package.json 将postcss响应的内容替换为 "postcss": { " ...

  8. POJ 2063 Investment 滚动数组+完全背包

    题目链接: http://poj.org/problem?id=2063 题意: 你现在有现金m元,你要做n年的存款投资,给你k种投资方式,每种需要现金vi元,能获得xi元的理论,一年到期后你要利用拿 ...

  9. 第八,九周web制作代码

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...

  10. python实现进制之间的转换

    十进制转36进制: #36位映射模板 loop = '0123456789abcdefghijklmnopqrstuvwxyz' # 测试用例输入 n = a = [] : a.append( loo ...