STM32
直播中

刘辉

8年用户 1161经验值
私信 关注
[问答]

STM32_USB硬件模块有哪些主要特征

什么是STM32_USB硬件模块呢?
STM32_USB硬件模块有哪些主要特征?



回帖(1)

王敏

2021-10-29 17:23:41
  1、STM32_USB硬件模块简介
  首先对STM32系列MCU自带的USB模块有一个概念性的认知,官方提供的培训PPT写的也很清晰,如下。
  
  我们下面所说的全部都是F103系列的USB_FS.
  在STM32F10X参考手册里面有如下两段话。
  
  
  除了对USB硬件模块有了一个最基本的说明外,需要注意的就是有以下三点。
  ● F103系列的MCU里面CAN和USB模块不能同时使用(F105,F107不受该影响)
  ● USB的ACK包的发送和ACK包的处理,令牌包分组的检测,数据的发送和接收,包括USB里面的CRC校验,全部都由硬件自动做完了。
  ● 一共8个双向端点,可以作为16个单向端点使用
  除此之外,USB提供低功耗模式(不产生任何静态电流,USB时钟减慢或停止)。
  2、STM32_USB硬件功能框图
  
  各个功能框图的描述其实在ST官方的培训文档也说的很详细了,如下所示。
  
  
  3、STM32_USB硬件中断
  USB模块的寄存器主要分为三大类,在手册里面也说了。
  
  先看一下通用寄存器里面最简单的两个寄存器。这部分基本没啥说的,和STM32其他模块大同小异。
  寄存器功能描述
  BTABLE寄存器里面存放了缓冲区描述表的起始地址
  DADDR寄存器 1、USB模块的总开关
  2、记录了HOST设置的设备地址
  下面的两个寄存器都是和中断相关的。
  ● CNTR寄存器
  
  ● ISTR寄存器
  
  可以很清晰的看到CNTR里面存放着USB中断的使能位,在这里我们只需要关注ISTR的CTR、WKUP、SUSP和RESET这4个bit即可。
  [tr]中端标志位描述[/tr][tr]CTR[td]每次传输完成后都会触发这个标志位[tr]WKUP[td]只有在挂起的时候检测到总线的复位信号才会触发[tr]SUSP[td]总线无信号后,硬件自动挂起[tr]RESET[td] 检测到复位信号后触发,触发后USB模块的发送和接收将会被禁止,直至此为被清除
  4、STM32_USB端点相关寄存器
  端点寄存器的数量由USB模块所支持的端点数目决定。每个端点都有与之对应的USB_EpnR寄存器,用于存储该端点的各种状态信息。比如F1系列一共有8个双向端点, 则0≤n≤7.具体寄存器内容如下。
  
  这个寄存器中有 4 类标志,分别是只能清零( rc_w0),写1 翻转(t),只读( r),读写( rw)。
  rc_w0 写1无效,写0清0
  t 写1翻转,写0无变化
  主要关注下表的几个寄存器。
  位名称含义
  CTR_RX正确接收到OUT或SETUP分组时由硬件置位,如果CTRM被置位,产生对应中断,以NAK或者STALL结束的分组和出错不会导致该位置位。
  STAT_RX[1:0]指示端点当前状态
  
  EP_TYPE[1:0]
  
  CTR_TX正确传输一个IN分组时由硬件置位,如果CTRM被置位,产生对应中断.IN分组传输完成后,如果主机响应NAK或STALL,则不会被置位。
  STAT_TX[1:0]指示发送数据的状态位
  
  DEVICE库
  4、PMA读写
  在开始的时候就提到过PC和USB的交互是通过一段专属的数据缓冲区进行的,该数据缓冲区在硬件功能框图里面又被叫做Packet Buffer Memory,该区域在ST官方的USB库里面又被叫做Packet Memory Area,简称PMA.那么我们如何和这段内存进行交互呢?
  首先从上面的信息里面可以知道,PMA的大小是512字节,可以通过APB1总线/USB控制器访问,且APB1的访问权限要高于USB.且软件部分通过Packet buffer interface访问(管理)PMA的存储空间,我们想使用的packet buffer的位置和大小可以随意配置,由buffer描述表指定。
  buffer描述表,这个东西实在难理解,首先要明白,它本身也是占用内存的,且占用的内存也在PMA区域里面,但是这块内存的地址是由USB_BTABLE寄存器指定的!!!如下所示。
  
  可以看到这个寄存器的功能只有一个,那就是保存了buffer描述表的起始地址。
  通过上面的几段话,可以明白,想要操作这段内存空间(Packet Buffer Memory)就要对buffer描述表进行操作,但buffer描述表本身就处于这段内存中。那该如何操作这个描述表呢?这个描述表的大小又如何确定?
  4.1、操作描述表
  首先来看如何操作这个描述表,下面看官方提供的一段描述。
  
  
  简单点说,这个描述表本身可以看成寄存器,使用操作寄存器的收发去操作。下面看一段官方的代码。
  可以很清楚的看到,_wRegVal其实就是你要操作的ADDR_TX/RX的地址,这两段代码就是设置TX/RX缓冲区的起始地址。
  这个时候已经设置好了数据存放的地址点了,但是数据交互的长度还没有设置,同理,如下所示。
  
  
  其实也没什么好说的,就是根据数据量的不同,对寄存器进行设定,只是运算方法比较巧妙,有兴趣可以自己琢磨琢磨。
  4.2、描述表大小的确定
  上面说完了如何操作描述表,让我们可以自由的设定发送和接收的地址缓冲区和长度了,但如何确定你要使用的缓冲区地址呢,毕竟我要用的缓冲区和描述表是出于同一段内存空间的。下面看一张图。
  
  有了上面的知识,应该已经知道能大概理解这张图的含义了,可以看出每个端点所使用的描述表大的大小为8个字节,简单点理解
  描述表大小 = MAN_EP_NUM*8
  结合例子,可以看到端点0的地址设定的是0X18(24),意思就是前24个字节用于缓冲区描述符,后续的各项间隔为0X40,其实就是端点描述符中的wMaxPacketSize.
  其实我挺好奇的,复合设备的端点用的是0、1、2的双向端点,3的单向端点,其实按道理来说这地方应该是0X20,但是依旧能正常使用,后来经过实际测试,发现在通讯过程的并没有CDC_CMD_EP的传输数据。所以只使用了0,1,2三个端点。所以这个地方还是可以正常使用的。
  建议使用端点的时候最好使用连续的端点,如果使用的是0,1,3.计算的时候还是需要按照4个端点进行计算的,端点2虽然没有使用,但是在实际的内存空间里面还是有端点2的描述表的。这样的话就会有空间浪费。
  下面说一些我整了半天才整明白的概念,可能有点简单,但是我确实很迷。
  
  简单说一下,USB_EPnR寄存器的低四位是专门存储端点地址的,比如我们在EP1R的寄存器里面写入0X0A,那么我们代码里面使用的EP1的实际地址就是0X0A,那么如果你的实际端点号其实是0X0A,但是在代码层面8个端点被抽象成为了IN_ep[8],调用的时候使用IN_ep[1]操作的依然是0X0A端点,实现了对底层的抽象。
  
  还有就是一直说STM32有8个双向端点,可以作为16个单向端点使用,我被这句话迷惑了好久,明明只有8个EPnrR寄存器,为什么可以使用16个单向端点,后来在上述图片内看到这句话,才明白,USB_IP最多只能使用8个端点,也就是说,我们不能同时使用15个IN/OUT端点。
  他说的这16个单向端点受EPnR控制,说的就是受上图红框内的寄存器位控制。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分