STM32 USB 数据缓冲区解疑

原文链接: https://blog.csdn.net/dingzj2000/article/details/92795680

转载自: https://blog.csdn.net/dingzj2000/article/details/92795680

1. STM32 USB数据缓冲区疑问
USB不同的应用需要使用到的端点数和端点数据长度各不相同,如果为每个端点都单独规划一个存储区非常浪费。
所以STM32为USB模块提供了共512个字节的存储区,至于如何为每个端点分配使用这512B的空间,就是用户自己的事情了,这样存储区的分配就非常经济灵活。这512B空间的首地址是0x40006000。
你看到的#define ENDP2_RXADDR        (0xD8),
这个0xD8就是在这512B空间里的偏移地址,说明端点2收到的数据将放在0x40006000 + 0xD8 * 2的地址空间里。至于为什么要×2,是因为这部分存储区是按照2字节访问的,
即每存放1个字节的数据要占据2个字节的空间(只利用其中一个字节,另一个空闲在那)。所以这段存储区的地址是从0x40006000到0x400063FF。(占用3FF,1K空间)
至于如何定义端点2的发送缓冲区,就看你的应用了。你把端点2的接受缓冲区定义在0xd8,如果端点2的接收数据长度是64个字节,那就要为端点2的接收保留64个字节,端点2的发送缓冲区就要定义到0xd8+64之后的空间。
即:#define ENDP2_TXADDR        (0xD8+64),
当然也可以#define ENDP2_TXADDR        (0xD8+100)或是其他。
总之如何分配这段存储区,完全可以按照你应用的需求来做。

2. 为什么ENDP0_RXADDR从0x40开始? 前面64个字节怎么不利用?
因为发送缓冲地址寄存器USB_ADDR_TX、发送数据字节寄存器USB_COUNT_TX、 接收缓冲地址寄存器USB_ADDR_RX、接收数据字节寄存器USB_COUNT_RX这四个寄存器中的值也是存在在缓冲描述表中的。
一个端点有四个寄存器,每个寄存器2个字节,就是8个字节,一共8个端点,正好就是64个字节。也就为什么端点0的接收地址从0x40开始了。
代码:
// =============================================================================
_SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
_pEPTxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr))
// =============================================================================
就是将具体设置的值存在前面64个字节的某个位置,具体为什么乘以2,如前所述。
可以说这四个寄存器并不是真正的寄存器,只是虚拟出来的。

3. 缓冲区描述表在缓冲区内即0x4000 6000--0x400063FF。
如果我只用端点0,那么端点0的缓冲区描述表为ADDR0_TX、COUNT0_TX、ADDR0_RX、COUNT0_RX所对应的地址为0x4000 6000--0x4000 6008 (USB_BTABLE = 0) 

现在有两人疑问: 
1) A.0x4000 6008以后的地址可不可以作缓冲区? 
   B.如果给ADDR0_TX、COUNT0_TX赋个合适的值,会不会端点0的缓冲区在0x4000 6000--0x4000 6008内,从而覆盖了它的缓冲区描术表? 

2) 为什么分组缓冲区地址(按字节编址)要乘以2才是缓冲区在MCU的地址,能不能举个例子说明? 

3) 0x4000 6000--0x400063FF等于1024字节,为什么是512字节,是不是后一半没有使用,芯片为103VBT6?如果我有一个端 
   点用了512字节缓冲区,那么缓冲区就用完了,是不是表示其他端点就没有缓冲区可用了,连缓冲区描述表都没有空间可分配了

1.A)    如果只使用端点0,0x4000 6010以后的地址可以作缓冲区。注意不是0x4000 6008以后的地址,原因请看下面的2)。 
1.B)    如果给ADDR0_TX、COUNT0_TX赋的值不合适,端点0的缓冲区有可能覆盖缓冲区描述表,所以请选择合适的值,以避免冲突。 
2)      这是因为分组缓冲区是一个双端口的RAM,CPU一端需要使用32位方式访问,但USB模块一端使用16位方式访问。 
        例如需要从0x4000 6010开始分配8个字节的缓冲区,则从CPU一端看,需要占用0x4000 6010、0x4000 6014、0x4000 6018和0x4000 601C开始的4个字的空间,
        即CPU端每4个字节的地址空间中,只有2个字节的地址空间对应实际的存储器,而另2个字节的地址空间没有对应到任何物理的存储器。 

3)      1024字节与512字节的问题,请看上面的说明。 
        如果有一个端点用了512字节缓冲区,那么缓冲区就用完了,表示其他端点就没有缓冲区可用了,连缓冲区描述表都没有空间可分配了。
 

你可能感兴趣的:(STM32)