基于STM32的USB程序开发笔记

2026/4/24 2:05:12

http://www.hkaco.com

vsDeviceInfo.TransInfo.wLength -= wLength; vsDeviceInfo.TransInfo.wOffset += wLength;

return RESULT_LASTDATA; }

return RESULT_SUCCESS; }

如果发送的数据长度大于端点设置的最大数据包长度,数据将分割为若干次发送,记录发送数据的状态包含在结构体TRANSFER_INFO中:

// ***************************************************************************** // TRANSFER_INFO

// ***************************************************************************** typedef struct _TRANSFER_INFO {

unsigned short wLength; // total lengths data will be transmit unsigned short wOffset; // number of data be transmited unsigned short wPacketSize; // endpoints packet max size unsigned char* pBuffer; // address of data buffer }

TRANSFER_INFO, *PTRANSFER_INFO;

TRANSFER_INFO.wLength记录发送的数据长度,如果非0,表示有数据需要被发送。 TRANSFER_INFO.wOffset记录已发送的数据长度,用以确定数据缓冲TRANSFER_INFO.pBuffer的偏移量。

需要了解的一点:USB主机向USB设备正确发送一请求后(这部分的处理由硬件完成),USB主机将间隔若干次的向USB设备索取响应数据,STM32 USB TX状态为NAK说明不响应USB主机,USB主机在超时后退出此次请求;TX状态为STLL说明中断此次请求,USB主机将无条件退出请求;TX状态为 VALID说明设备已准备好数据发送,USB主机将从USB设备读取数据。

以非0长度数据请求的GET_DESCRIPTOR请求为例的响应过程:

CTR_SETUP0()->SETUP0_Data()->SR_GetDescriptor()->SETUP0_TransData()

RESULT SR_GetDescriptor(void) {

// RequestType: device->host, standard request and device recipient

if(vsDeviceInfo.SetupData.bmRequestType == RT_D2H_STANDARD_DEVICE) {

// SetupData.wValue.b.MSB: descriptor type // SetupData.wValue.b.LSB: descriptor index switch(vsDeviceInfo.SetupData.wValue.b.MSB) {

http://www.hkaco.com

case DESCRIPTOR_DEVICE: return SR_GetDescriptor_Device(); case DESCRIPTOR_CONFIG: return SR_GetDescriptor_Config(); case DESCRIPTOR_STRING: return SR_GetDescriptor_String();

default: return RESULT_UNSUPPORT; } }

return RESULT_UNSUPPORT; }

GET_DESCRIPTOR请求属于USB协议中的标准请求(standard request)并且数据方向为设备至主机(device->host),分设备描述符、配置描述符、字符串描述符三种。已设备描述符为例:

RESULT SR_GetDescriptor_Device(void) {

// Assigned the device descriptor to the transfer vsDeviceInfo.TransInfo.wOffset = 0;

vsDeviceInfo.TransInfo.wPacketSize = ENDP0_PACKETSIZE; vsDeviceInfo.TransInfo.pBuffer = DescBuffer_Device.pBuff; vsDeviceInfo.TransInfo.wLength = DescBuffer_Device.wLen; vsDeviceInfo.eControlState = CS_GET_DESCRIPTOR;

if(vsDeviceInfo.TransInfo.wLength> vsDeviceInfo.SetupData.wLength.w) {

vsDeviceInfo.TransInfo.wLength = vsDeviceInfo.SetupData.wLength.w; }

return SETUP0_TransData(); }

这里说明了发送数据的长度、缓冲、偏移、端点包大小以及当前的控制状态,并说明了如果发送的数据长度超出请求的数据长度,则将舍弃超出的部分。数据配置好后,调用SETUP0_TransData()进行数据发送。

在USB主机查询到USB设备准备就绪后,将读取出这些数据,完成后,USB设备将产生IN事件,此时将响应CTR_IN0()函数:

// ***************************************************************************** // Function Name : CTR_IN // Description : // Input : // Output : // Return :

// ***************************************************************************** void CTR_IN0(void) {

http://www.hkaco.com

switch(vsDeviceInfo.eControlState) {

case CS_GET_DESCRIPTOR:

if(SETUP0_TransData() == RESULT_SUCCESS) {

SetEPR_TXStatus(ENDP0, EP_TX_NAK); SetEPR_RXStatus(ENDP0, EP_RX_VALID); } break;

case CS_SET_ADDRESS:

SetEPR_TXStatus(ENDP0, EP_TX_NAK); SetEPR_RXStatus(ENDP0, EP_RX_VALID);

SetDADDR(0x0080 | vsDeviceInfo.bDeviceAddress); vsDeviceInfo.eDeviceState = DS_ADDRESSED; break;

case CS_SET_CONFIGURATION:

SetEPR_TXStatus(ENDP0, EP_TX_NAK); SetEPR_RXStatus(ENDP0, EP_RX_VALID);

vsDeviceInfo.eDeviceState = DS_CONFIGURED; break;

default: break; } }

再这如果响应GET_DESCRIPTOR请求发送的数据如果全部发送完毕,SETUP0_TransData()返回RESULT_SUCCESS,并设置TX状态为NAK;否则返回RESULT_LASTDATA,将继续发送剩余的数据直到数据全部被发送。至此,整个的GET_DESCRIPTOR请求过程完成。 0长度的数据请求在发送0长度数据响应后,因为不存在可能还未传送的数据,因而IN事件后直接结束此次请求。

在数据方向为USB主机->USB设备时,如果正确接收到数据,将响应CTR_OUT0()函数,处理过程类同CTR_IN0()函数。

在USB设备的枚举过程中,USB的一些描述符数据结构需要了解,具体在USB协议中有详细的说明,在usb_desc(.c/.h)文件中,定义了这些结构,这些结构是特定的:

设备描述符:长度、格式固定,其中VENDOR_ID与PRODUCT_ID决定上位机驱动的识别。设备分属类别决定了设备的性质,如果为自定义USB设备,设备分属类别值为0,同时上位机驱动必须配合编写;如果为标准USB设备,则必须使用这些标准设备的驱动、数据结构等等,条件是你必须了解这些标准设备的一些信息,好处是省去一些麻烦的驱动编写。

http://www.hkaco.com

const unsigned char cbDescriptor_Device[DESC_SIZE_DEVICE] = {

DESC_SIZE_DEVICE, // bLength: 18 DESCRIPTOR_DEVICE, // descriptor type

0x00, // bcdUSB LSB: USB release number -> USB2.0 0x02, // bcdUSB MSB: USB release number -> USB2.0

0x00, // bDeviceClass: Class information in the interface descriptors 0x00, // bDeviceSubClass: 0x00, // bDeviceProtocol:

0x40, // bMaxPacketSize0: LowS(8), FullS(8,16,32,64), HighS(64)

LOWORD(VENDOR_ID), // idVendor LSB: HIWORD(VENDOR_ID), // idVendor MSB:

LOWORD(PRODUCT_ID), // idProduct LSB: HIWORD(PRODUCT_ID), // idProduct MSB:

LOWORD(DEVICE_VERSION), // bcdDevice LSB: HIWORD(DEVICE_VERSION), // bcdDevice MSB:

0x01, // iManufacturer: Index of string descriptor describing manufacturer 0x02, // iProduct: Index of string descriptor describing product

0x03, // iSerialNumber: Index of string descriptor describing the device serial number

0x01 // bNumConfigurations: number of configurations };

配置描述符:前9个字节格式固定,后面紧跟的各种描述结构跟实际配置有关,每增加一种描述结构,该描述结构的第一字节说明了结构的长度,第二直接说明了结构的类型。在配置描述符中一般包含配置描述、接口描述、端点描述,如果需要同样可增加自定义的描述。使用标准USB设备类别时,配置描述符的结构也必须满足此类标准设备的数据结构。 const unsigned char cbDescriptor_Config[DESC_SIZE_CONFIG] = {

// Descriptor of configuration 0x09, // lengths

DESCRIPTOR_CONFIG, // descriptor type

DESC_SIZE_CONFIG, // Total configuration descriptor lengths LSB 0x00, // Total configuration descriptor lengths MSB

0x01, // bNumInterfaces: Total number of interfaces


基于STM32的USB程序开发笔记.doc 将本文的Word文档下载到电脑
搜索更多关于: 基于STM32的USB程序开发笔记 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219