博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
USB驱动之CDC类的介绍与应用20160905
阅读量:5050 次
发布时间:2019-06-12

本文共 2990 字,大约阅读时间需要 9 分钟。

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:

 

转载于:https://www.cnblogs.com/yuweifeng/p/5843688.html

你可能感兴趣的文章
(转)Intent的基本使用方法总结
查看>>
Windows Phone开发(24):启动器与选择器之发送短信
查看>>
JS截取字符串常用方法
查看>>
Google非官方的Text To Speech和Speech Recognition的API
查看>>
stdext - A C++ STL Extensions Libary
查看>>
Django 内建 中间件组件
查看>>
bootstrap-Table服务端分页,获取到的数据怎么再页面的表格里显示
查看>>
进程间通信系列 之 socket套接字及其实例
查看>>
天气预报插件
查看>>
Unity 游戏框架搭建 (十三) 无需继承的单例的模板
查看>>
模块与包
查看>>
mysql忘记root密码
查看>>
apache服务器中设置目录不可访问
查看>>
嵌入式Linux驱动学习之路(十)字符设备驱动-my_led
查看>>
【NOIP模拟】密码
查看>>
java容器---------手工实现Linkedlist 链表
查看>>
three.js 性能优化的几种方法
查看>>
《梦断代码》读书笔记(三)
查看>>
FreeMarker解析json数据
查看>>
Java8 Lambda表达应用 -- 单线程游戏server+异步数据库操作
查看>>