历史上的今天
返回首页

历史上的今天

今天是:2024年11月10日(星期日)

正在发生

2020年11月10日 | USB通讯的执行过程 - STM32 USB设计

2020-11-10 来源:eefocus

  首先,我们来看看usb的工作过程。


  当usb设备接入到主机时,主机开始枚举usb设备,并向usb设备发出指令要求获取usb设备的相关描述信息,其中包括设备描述(device descriptor)、配置描述(configuration descriptor)、接口描述(interface descriptor)、端点描述(endpoint descriptor)等。这些信息是通过端点0(endpoint 0)传送到主机的。获取各种描述信息后,操作系统会为其配置相应的资源。这样主机就可以与设备之间进行通信了。


  usb通讯有四种通讯方式控制(control)、中断(interrupt)、批量(bulk)和同步( synchronous)。usb通讯是通过管道(pipe)实现的。管道是一个抽象的概念,指的是主机与设备之间通讯的虚拟链路。不如说一个usb通讯 主机A和设备B,其中有bulk in(批量输入)、bulk out(批量输出)、control out(控制输出)三种通讯方式,那么A与B之间的通讯管道就有三个。(这里明确一个概念,在usb通信中数据流向都是相对设备来说的,in表示设备向主 机传送数据,out表示表示主机箱设备传输数据)。在设备一端,每个管道对应一个端点,端点配置相关的寄存器和缓冲区。在通讯之前需对端点进行相关设置。 在通信中,只需向缓冲写或读数据,并置位相关比特位即可。


  下面具体从usb的中断输入输出来讲述基于keil C mdk开发环境的stm32的USB接口单片机程序设计。值得一提的是,st或相关公司给我们提供许多封装函数和相关例子,我们可以根据其中的例子并进行修改即可实现我们自己需要的usb通讯程序。


  1.usb描述符配置

  从上面的讲述可以看出,usb描述符是usb通讯的前提。主机必须先了解设备后才能与其进行通讯。在st提供的例子中,描述符都在usb_des.c文件进行定义,下面就其中的Joystick例子说明usb描述负的配置。


  1.1设备描述符

  const u8 Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DESC] =

  {

  0x12, /*本描述长度*/

  USB_DEVICE_DESCRIPTOR_TYPE, /*指明为设备描述符*/

  0x00,

  0x02,

  0x00,

  0x00,

  0x00,

  0x40, /*最大数据包大小为64字节(对于端点0而言)*/

  0x84, /*生产商ID*/

  0x19,

  0x06, /*产品ID*/

  0x04,

  0x00,

  0x02,

  1,

  2,

  3,

  0x01 /*配置描述符数目*/

  }


  设备描述符两个重要参数是生产商ID和产品ID,主机将根据以上两个ID为设备选择相应驱动程序。在我们的应用中,我们一般只需修改例子中的这儿两个参数即可完成设备描述符的设置。


  1.2配置描述符

  const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =

  {

  0x09,

  USB_CONFIGURATION_DESCRIPTOR_TYPE,

  JOYSTICK_SIZ_CONFIG_DESC,

  0x00,

  0x01, /*接口数目*/

  0x01, /*Set_Configuration命令所需要的参数值*/

  0x00, /*描述该配置的字符串的索引值*/

  0xE0, /*供电模式的选择,bus供电、自供电、支持wakeup*/

  0x32, /*最大供电电流*/

  /************** 接口1配置****************/

  0x09,

  USB_INTERFACE_DESCRIPTOR_TYPE,

  0x00, /*接口编号*/

  0x00,

  0x02, /*端点数*/

  0x00,

  0x00,

  0x00,

  0, /*接口描述符索引值*/

  /******************** 端点1输出描述********************/

  0x07,

  USB_ENDPOINT_DESCRIPTOR_TYPE,

  0x81, /*端点地址,b.7表示方向(1为in,0为out)b.0-b.3为端点标号*/

  0x03, /*端点数据传输方式*/

  0x08, /*最大数据包大小*/

  0x00,

  0x20,

  /******************** 端点1输入描述********************/

  0x07,

  USB_ENDPOINT_DESCRIPTOR_TYPE,

  0x01, /*端点地址*/

  0x03, /*端点数据传输方式*/

  0x40, /*最大数据包大小*/

  0x00,

  0x20,

  }


  配置描述符中包括了接口、端点的配置。如果设备为HID设备,在配置描述符中还应加入HID描述,具体描述可以参照Joystick例子的配置。


  还有一些其他配置可以参可相关资料与例子加以理解。


2、USB通讯的执行过程。

  首先,当主机数据传送到USB设备,USB怎样接收命令和数据呢?USB首先会产生一个中断,这个中断在stm32fxxx_it.c文件的 USB_HP_CAN_TX_IRQHandler和USB_LP_CAN_RX0_IRQHandler中定义,一般使用 USB_LP_CAN_RX0_IRQHandler。在这个函数中继续调用USB_Istr()函数,这个函数是usb通讯的关键。它接收到主机命令, 指派调度相应函数进行处理。对于这一点,详细过程我现在还不是很明白。如果以后搞懂了再补述。


  当USB设备接入主机时,主机要枚举该USB设备,他将要求USB设备提供自身相关信息,这是通过endpoint0实现的。endpoint0是 一个特殊的端点,每一个接口(interface)必须有endpoint0。一般情况下,我们需要使用多个端点(如前所述,配置描述符定义了端点的数 目、类型、传输数据大小等)。在使用端点前需对端点进行初始化。这个过程在usb_prop.c文件中的xxx_reset()函数定义。如我定义端点1 的两种传输方式:

  /* Initialize Endpoint 1 */

  SetEPType(ENDP1, EP_INTERRUPT);

  SetEPRxAddr(ENDP1, ENDP1_RXADDR);

  SetEPRxCount(ENDP1, 8);

  SetEPRxStatus(ENDP1, EP_RX_VALID);

  /* Initialize Endpoint 1 */

  SetEPType(ENDP1, EP_INTERRUPT);

  SetEPTxAddr(ENDP1, ENDP1_TXADDR);

  SetEPTxCount(ENDP1, 64);

  SetEPTxStatus(ENDP1, EP_TX_NAK);

  在定义完端点后,我们就可以使用端点进行数据传输了。

  向主机输入数据(in):IN传输过程是

  1.向缓冲区填入数据;

  2.设定USB数据计数器:

  3.设置USB输出有效。

  XXX_send()

  {

  /*copy mouse position info in ENDP1 Tx Packet Memory Area*/

  UserToPMABufferCopy(sendBuffer, ENDP1_TXADDR, 2); /*sendBuffer为要输出的数据,ENDP1_TXADDR端点1的向外传输缓冲区,2为数据大小byte为单位*/

  SetEPTxCount(ENDP1, 2);

  /* enable endpoint for transmission */

  SetEPTxValid(ENDP1);

  }

  注意一般情况下,端点的输入输出缓冲区地址没有定义,须在usb_conf.h中定义具体定义可以参考端点0的定义。

  读从主机输出的数据(out):out传输过程是

  1.定义out回调函数;

  2.从缓冲区读出数据:

  3.设置USB输入有效。

  void EP1_OUT_Callback(void)

  {

  u8 DataLen;

  DataLen = GetEPRxCount(ENDP1);

  PMAToUserBufferCopy(rcvData, ENDP1_RXADDR, DataLen);

  SetEPRxValid(ENDP1);

  }


  注意在一般情况下,EPX_OUT_Callback()回调函数的申明为空执行函数。需将usb_conf.h中#define EPX_IN_Callback NOP_Process隐掉。再在合适的地方从新定义void EP1_OUT_Callback(void)(合适的位置是指定义之后运行不会出现EP1_OUT_Callback为申明的错误就行)。


  总结,在此将stm32芯片的usb通讯进行了简单的阐述。本人水平有限,以上难免会有错误,希望大家积极留言,共同探讨,共同进步。这篇文章是断 断续续写的,给大家带来不便,在此向大家道歉了。不管怎样希望这篇文章能够对那些还在对stm32usb编程初步摸索的朋友有一点帮助。


推荐阅读

史海拾趣

CONTRINEX公司的发展小趣事

在数控加工领域,Contrinex的数字测量智能传感器带来了革命性的变革。这些先进的传感器能够精确实时地测量拉杆位置,通过智能决策,确保加工精度,防止潜在损坏。其卓越的性能和稳定性,使得Contrinex在这一领域取得了显著的成绩,并赢得了众多客户的赞誉。

Hsuan Mao Technology Co公司的发展小趣事

2015年,Contrinex正式进入中国市场,成立了全新的中国子公司。这一重要举措不仅进一步拓宽了公司的业务范围,也为中国客户提供了更加便捷和高效的服务。在中国市场,Contrinex凭借其电感式、光电式、安全光幕和RFID系统的工业级传感器产品,赢得了众多客户的青睐和信赖。

上海晶丰明源(BPS)公司的发展小趣事

上海晶丰明源半导体股份有限公司的创立,标志着中国在半导体领域的又一重要布局。公司自成立之初,就专注于电源管理芯片的研发与销售,凭借对技术的深入理解和市场需求的敏锐洞察,迅速在行业中崭露头角。初步发展阶段,晶丰明源通过不断优化产品设计、提升生产工艺,逐步赢得了客户的信任,并在市场上占据了一席之地。

High Voltage Semiconductor Inc公司的发展小趣事

面对日益激烈的市场竞争和不断变化的市场需求,美高测始终保持着对技术创新的执着追求。公司不断投入研发资源,探索新的测试技术和应用场景,如微电网、新能源汽车等领域的高压半导体测试。同时,美高测还积极构建开放式的创新生态体系,与众多合作伙伴共同推动行业的进步和发展。通过这些努力,美高测在高压半导体测试领域持续保持着领先地位,为电子行业的未来发展贡献着重要力量。

Essentra Components公司的发展小趣事

面对日益激烈的市场竞争,Essentra Components公司决定实施全球化战略,以拓展更广阔的市场。公司先后在亚洲、欧洲、美洲等多个地区设立了生产基地和销售服务点,实现了产品的全球覆盖。同时,公司还积极与当地企业合作,共同开发适合当地市场需求的产品,进一步巩固了其在全球市场的地位。

Datapro International Inc公司的发展小趣事

为了进一步提升技术实力和市场竞争力,Datapro International Inc公司开始寻求与国内外知名企业的战略合作。他们与一些在数据存储和处理领域具有领先地位的企业建立了合作关系,共同研发新产品、拓展新市场。

通过战略合作,Datapro International Inc公司获得了更多的技术资源和市场机会。同时,他们也从合作伙伴身上学到了许多先进的管理理念和市场策略。这些经验和知识为Datapro International Inc公司的未来发展提供了有力的支持。

问答坊 | AI 解惑

EEWORLD深圳“低功耗创新设计论坛”报道出炉!

感谢大家对EEWORLD深圳会议的支持,去了的朋友,希望可以多多交流,并提出宝贵建议,使得我们下次做的更好;没有参加的朋友,可以通过以下内容对会议有个全方位的了解,如还需要其他方面的内容,请与soso联系,我们会尽可能提供全面的资料给大家。 ...…

查看全部问答>

颀邦合并飞信,全球驱动IC将涨价

本帖最后由 jameswangsynnex 于 2015-3-3 19:56 编辑 2010年颀邦科技正式合并飞信半导体,资本额逐步扩增至54.49 亿元新台币,今年上半年营收高达57.04亿元新台币,稳坐全球最大面板驱动IC封测代工厂龙头宝座(三星电子是自产自用)。合并飞信后 ...…

查看全部问答>

在驱动中怎么运行一个exe文件

比如在驱动中运行\\\\windows\\aa.exe,可以吗?怎么做?…

查看全部问答>

选取GPRS模块的问题

想做GPRS终端,要内嵌协议的,西门子MC55,SIM300,ENFORA GSM0308等,不知道选择哪款好?各位做过相关开发的大侠们,能不能向小弟介绍一款性价比好,在长时间运行中,运行稳定一些的模块! …

查看全部问答>

给点提示Win32驱动能否实现过滤/保护进程及窗口

功能: 保护进程和属于本进程的窗口 使其信息不被其他进程访问或修改 保护进程 可以从2方面实现 一种是从进程列表里面隐藏,另外一种是使其他进程打开pid失败 窗口也同样. 设想安装了该驱动的机器,软件调用驱动提供的服务后 就进入了保护模式,其 ...…

查看全部问答>

精流塔磁翻板液位计与dcs显示不对

今天我公司和利时MACS V 1.1.0+SP2dcs出现奇怪的故障,现场一个精流塔磁翻板液位计与dcs显示不对,仪表工在现场液位计把dcs 过来的两根线拆除(两根线测量过有24vdc电压),可是在dcs上还有液位显示,再在模块卡件上两根线拆除,还是有液位显示, ...…

查看全部问答>

2009年STMCU技术研讨会上海站地址

由于我们工作的失误,造成部分注册参加研讨会的朋友没有收到告知研讨会地址的回函,特此道歉。 现特将明天上海研讨会的地址公布如下,请已经报名的朋友前往捧场,谢谢! ---------------------------------- 2009年9月16日ST MCU上海巡回研 ...…

查看全部问答>

求DSP移植大牛

在做基于DM642开发板的人脸识别系统,其中需要将OpenCV移植到DM642上求大牛出现或有偿帮忙哦!…

查看全部问答>

TI 电源设计小贴士 28

欢迎来到电源设计小贴士!随着现在对更高效、更低成本电源解决方案需求的强调,我们创建了该专栏,就各种电源管理课题提出一些对您有帮助的小技巧。该专栏面向各级设计工程师。无论您是从事电源业务多年还是刚刚步入电源领域,您都可以在这里找到一 ...…

查看全部问答>

MSP430F5438学习资料

所有资源来源网络! 作者   蔡智強教授…

查看全部问答>