打印
[STM32F1]

STM32F103 上 USB 的端点资源灵活使用

[复制链接]
953|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LEDyyds|  楼主 | 2021-11-12 16:49 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
前言
理解 STM32F103 USB 模块的端点资源,灵活在应用中的配置。  

使用特权

评论回复
沙发
LEDyyds|  楼主 | 2021-11-12 16:52 | 只看该作者
问题
某客户使用 STM32F103 的 USB 模块做设备时和上位机 PC 连接时碰到一个问题: PC 端驱动已经固
定好,是对下位机 USB 设备上的地址编号为 0x0A 和 0x0B 的两个端点通信,从 0x0A 端点读取数据,
向 0x0B 端点写数据。而 STM32F103 的 USB 模块只有 8 个双向端点,能否支持这样的寻址。

使用特权

评论回复
板凳
LEDyyds|  楼主 | 2021-11-12 16:53 | 只看该作者
1. 问题调研
我们先来看看 STM32F103 上的 USB 端点资源。从 STM32F103 参考手册( RM0008)可知,一共有
8 个双向端点,对应 8 个寄存器来控制其属性和表征其状态。 如下图,可知每一对端点必须配置成相同
的端点地址,这个地址位域是 4 位,取值从 0x0 到 0x0F 范围。

和以下摘录的 USB 规范符合:

客户使用的是 STSW-STM32121( STM32F10x, STM32L1xx and STM32F3xx 全速 USB 设备库),
那么应该修改哪些代码呢?

使用特权

评论回复
地板
LEDyyds|  楼主 | 2021-11-12 16:55 | 只看该作者
2. 问题分析
首先, USB 设备通过端点描述符向主机 PC 报告它所使用的端点有哪些:每个端点的地址(即 USB 规
范里,以及参考手册的寄存器中规定的那 4 位地址域)、传输方向、传输类型、最大包长等。以
STSW-STM32121 库中的 Mass_Storage 例程为例,需要把<usb_desc.c>中的端点描述符做如下修改:
0x0A 地址的端点作为 IN 端点( PC 从它读取数据), 0x0B 地址的端点作为 OUT 端点( PC 向它写数
据)。

使用特权

评论回复
5
LEDyyds|  楼主 | 2021-11-12 16:56 | 只看该作者

使用特权

评论回复
6
LEDyyds|  楼主 | 2021-11-12 16:56 | 只看该作者
接下来就是考虑使用 STM32F103 USB 模块提供的 8 个双向端点的哪个端点了。我们刚才从参考手册
关于寄存器描述的截图中看到,每一对端点具有相同的地址。在库函数里,对端点寄存器的地址位域
的操作在这里:

这个函数的名称是“设置(USB)设备地址”,但是其中除了最后一句是在设置 USB 设备的地址,前面
的 for 循环是在设置该设备内的端点地址。
从以上绿色标注的代码段可以看到,库代码固定给 1 号端点”0x01”这个地址, 2 号端点”0x02”这个地址,
以此类推。这里的”1 号”、 ”2 号”指的是端点的编号,对应的就是之前提到的 8 个寄存器的编号,即下图
中的 n=0~7。 n 在这里就是端点的编号。

使用特权

评论回复
7
LEDyyds|  楼主 | 2021-11-12 16:57 | 只看该作者
那么在这个应用中,需要用到地址为 0x0A 和 0x0B 的两个端点,但是端点编号最多只能到 7,因此需
要修改库代码中关于端点地址设置的地方如下:这里,我们使用编号为 1 和 2 的两个端点。
 为啥不用编号 0?因为编号 0 默认给双向 0 端点,即用于控制传输的 0 端点。
 为啥用 2 个编号?因为这里需要 2 个不同的端点地址,必须用 2 个编号。一个编号对应的 2 个
端点必须共享同样的端点地址。

既然这里指定了使用编号 1 和编号 2 的端点,那么需要在<usb_conf.h>中设置这两个端点的硬件收发
缓冲区地址

使用特权

评论回复
8
LEDyyds|  楼主 | 2021-11-12 16:58 | 只看该作者
当然如果你很任性,一定要使用编号为 6 和 7 的端点,也可以,那么代码就如下修改:
void SetDeviceAddress(uint8_t Val)
{
/* set address in every used endpoint */_SetEPAddress((uint8_t)0, (uint8_t)0);
_SetEPAddress((uint8_t)6, (uint8_t)0x0A);
_SetEPAddress((uint8_t)7, (uint8_t)0x0B);
_SetDADDR(Val | DADDR_EF); /* set device address and enable function */
}
相应地,需要在<usb_conf.h>中指明编号为 6 和 7 的这两个端点的硬件收发缓冲区地址。那么如法**
制做如下修改, 就可以了吗?就可以了吗?就可以了吗?



使用特权

评论回复
9
LEDyyds|  楼主 | 2021-11-12 16:59 | 只看该作者
/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR (0x18)
#define ENDP0_TXADDR (0x58)
/* 6 号端点, IN 端点,发送缓冲区如下 */
#define ENDP6_TXADDR (0x98)
/* 7 号端点, OUT 端点,接收缓冲区如下 */
#define ENDP7_RXADDR (0xD8)
答案是否定的!以下的代码才 OK。欲知详情,请参考下一条应用技巧《STM32F103 上 USB 模块的
包缓冲区详解》
/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR (0x40)
#define ENDP0_TXADDR (0x80)
/* 6 号端点, IN 端点,发送缓冲区如下 */
#define ENDP6_TXADDR (0xC0)
/* 7 号端点, OUT 端点,接收缓冲区如下 */
#define ENDP7_RXADDR (0x100)





使用特权

评论回复
10
wowu| | 2021-12-6 19:56 | 只看该作者
有多少端点资源 呢

使用特权

评论回复
11
xiaoqizi| | 2021-12-6 20:03 | 只看该作者
期待楼主的更新哈

使用特权

评论回复
12
tpgf| | 2021-12-6 20:07 | 只看该作者
什么是端点呢

使用特权

评论回复
13
木木guainv| | 2021-12-6 20:09 | 只看该作者
可以有多少个端点呢

使用特权

评论回复
14
guanjiaer| | 2021-12-6 20:12 | 只看该作者
可以共用缓存吗

使用特权

评论回复
15
heimaojingzhang| | 2021-12-6 20:13 | 只看该作者
它的配置确实非常灵活

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

119

主题

841

帖子

1

粉丝