找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5354|回复: 4
收起左侧

STM32 USB模块讲解

[复制链接]
ID:136005 发表于 2019-2-23 10:37 | 显示全部楼层 |阅读模式
天有空,开贴讲讲,怎样配合 ST提供的库函数理解 STM32F102/103的USB模块,以及怎么调用这些库函数来实现基本的USB通信。
题目很大,先只讲讲最简单的应用。

1
关于512字节的Packet Buffer
在STM32F103的USB模块中有一个RAM区,称为PacketBuffer,共有512字节。
SB模块中有个BufferDescriptionTable,这个Table位于512字节的PacketBuffer中,可以在PacketBuffer的任意位置。
USB模块提供一个寄存器USB_BTABLE来设置BufferDescriptionTable在Packet

uffer的偏移地址。
在库函数中, Define了这个偏移地址:
usb_conf.h:
#defineBTABLE_ADDRESS (0x00)
这意味着 Buffer Description Table位于 Packet Buffer的首地址


Buffer DescriptionTable中的,是所用到的端点的缓存区地址寄存器和缓存区长度寄存器。所有用到的端点的这两个寄存器都位于这个Table中。
如上所说, 由于这个 Table位于 Packet Buffer的首地址。 所以端点 0的发送缓冲区地址寄存器就位于 Packet Buffer的首地址, 紧接的是端点0发送缓冲区长度寄存器, 接着的是端点0接收缓存区的地址寄存器, 跟着是端点0的接收缓存区的长度寄存器, 等等等等, 一直到最后一个端点8的接收缓存区的长度寄存器。
每个端点的一个方向有 2个寄存器, 共8个端点 16个方向, 一共32个寄存器, 每个寄存器为4个字节,所以这个 Table一共占有128字节
端点 0发送缓存区的地址寄存器中的值,是端点 0发送缓存区在 Packet Buffer中的偏移地址。而端点 0接收缓存区的地址寄存器中的值, 是端点 0接收缓存区在Packet Buffer中的偏移地址。
如前所说, Buffer Description Table从理论上占有 128个字节。但对于具体的应用,不是每个应用都会用到 8个端点的 16个方向的。所以,对于那些没有用到的端点寄存器,我们可以不考虑为他们预留位置。
在ST提供的例程中,通常这么定义
define BTABLE_ADDRESS (0x00)
/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR (0x18)
#define ENDP0_TXADDR (0x58)
这 3句定义,意味着:
1, 端点 0的接收缓存区位于 Packet Buffer的 0x18地址。
2, 端点 0的发送缓存区位于 Packet Buffer的 0x58地址。
3, Buffer Description Table 位于 Packet Buffer的前 24字节。 24个字节意味着
应用需要使用6个寄存器,即 3个端点。
4, 端点 0的接收缓存区长度为64字节
了,关于这个PacketBuffer讲解完毕。
要做一个USB应用,第一步就是要根据应用合理的分配好这个PacketBuffer。
出个题目给大家做做
假设, 需要使用端点0的IN,OUT传输, 端点长度为8字节, 端点1的IN传输, 长度为16字节。端点2的OUT传输,长度为64字节。端点2的IN传输,长度为64字节。
该怎么分配这个PacketBuffer?
2 使用STM32F102/103USB函数库 进行USB通信
第一步:
根据应用的需求,定义使用到的端点数量
usb_conf.h
#define EP_NUM(3)
上意味着应用需要使用到EP0, EP1和EP2
第二步:
初始化每个使用到的端点
usb_prop.c
SetEPType(ENDP2,EP_INTERRUPT);
定义端点2为中断端点
SetEPTxAddr(ENDP2,ENDP2_TXADDR);
如果需要进行EP2IN通信,需要定义端点 2的发送缓存区的地址,也就是在PacketBuffer
中的偏移地址
SetEPRxAddr(ENDP2,ENDP2_RXADDR);
如果需要进行EP2OUT通信,需要定义端点2的接收缓存区在PacketBuffer中的偏移地址
SetEPRxStatus(ENDP2,EP_RX_NAK);
设置端点2的接收状态为NAK,设备将以NAK来响应主机发起的所有OUT通信。
SetEPTxStatus(ENDP2,EP_TX_NAK);
设置端点2的发送状态为NAK,设备将以NAK来响应主机发起的所有IN通信。
第三步:
使能端点的通信
对于IN端点的使能:
UserToPMABufferCopy(Send_Buffer,ENDP2_TXADDR,8);
拷贝用户数据到端点2的发送缓存区
SetEPTxCount(ENDP2,8);
设置端点2发送数据长度
SetEPTxValid(ENDP2);
设置端点2的发送状态为VALID
以上三句可以在应用代码的任意位置调用,一旦调用,即使能了一次USBIN通信。
USB设备将在收到主机的 INTOKEN后,自动发送缓存区中的数据到主机,并在发送完毕
后产生EP2_IN_Callback中断,同时将端点2的发送状态自动改为NAK。
如果需要再次进行数据传送,需要再次调用以上的三句函数。
对于OUT端点的使能:
SetEPRxValid(ENDP2);
设置端点2的接收状态为VALID。
以上的这句函数即使能了端点2的OUT通信,可以在任意位置调用。
一旦调用,即使能了一次OUT通信。 USB设备将以 ACK来响应主机随后的OUT通信,并
在接收数据完毕后, 产生EP2_OUT_Callback中断, 同时自动将端点的接收状态改为NAK。
在EP2_OUT_Callback中断函数中调用
USB_SIL_Read(EP2_OUT,Receive_Buffer);
可以将端点2接收缓存区中收到的数据拷贝到用户数据区

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:479654 发表于 2019-2-23 15:04 | 显示全部楼层
和U盘通讯是一样的吗
回复

使用道具 举报

ID:49877 发表于 2019-2-23 16:03 | 显示全部楼层
学习、收藏了
回复

使用道具 举报

ID:136005 发表于 2020-10-27 11:31 | 显示全部楼层
白菜19 发表于 2019-2-23 15:04
和U盘通讯是一样的吗

U盘的通讯 是USB四大通信中的一种应用 属于MSD 大容量存储,通讯的模式属于批量 传输,官方有开源的代码,移植很方便
回复

使用道具 举报

ID:169559 发表于 2020-10-30 17:32 | 显示全部楼层
楼主能讲讲  USB_CDC_host  吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表