1.概述
对USB硬件和数据的四种传输类型有基本的了解。
控制传输(Control Transfers)
批量传输(Bulk Data Transfers)
中断传输(Interrupt Data Transfers)
同步传输(Isochronous Data Transfers):
让我举一个USB的具体工作流程为例。这里更实用的例子是使用USB将主板连接到PC,然后在PC端显示模拟串行端口,通过串行支持打开串行端口,然后实现数据的双向传输。(大卫亚设,Northern Exposure(美国电视),Northern Exposure(计算机))最后,让我们谈谈许多工程师可能忽略的USB认证问题。
2.例行程序
在ST的Cube库中打开了CDC例程。
STM 32 cube _ fw _ f1 _ v 1 . 8 . 0 \ projects \ STM 3210 c _ eval \ applications \ USB _ device \
这个例程将USART与USB一起使用。USB在PC端收到数据后,将转发到USART,在USART收到消息后,将上载到PC。USART的TX和RX可以短接,因此PC端发送的数据将原封不动地传递回PC端。
此例程使用的硬件是STM3210C-EVAL,原理图可以在中找到。如果我们使用不同的板子,就要在这个工程的基础上做一些修改。例如,如果现在使用STM32F105RBT6,8M晶振、用于串行端口的PTA2和PTA3,则必须进行以下修改:
首先修改使用的MCU。
然后修改时钟初始化部分。下图是STM32F105时钟模块的示意图。USB操作需要48MHz时钟。
(stm32f 105xx数据表)
如果电路板的结晶为8米,则参数应配置如下:
(OSC IN=8M)
Prediv 1 src=0b0,HSE oscillator clock selected as prediv 1 clock entry
Prediv1=0b0,prediv1 input clock not divided
Pllsrc=0b1,clock from prediv 1 selected as PLL input clock
PLLMUL=0b0111,PLL input clock x 9
(PLLCLK=72M)
Sw=0b10,PLL selected as system clock
PLLVCO=2*PLLCLK=144M
Usb pre=0,PLL clock is divided by 1.5(或PLL VCO/3)
USB Clock==PLLCLK=72M=48M
修改实例的相应代码:
修改上次使用的串行针脚:
//afio comx _ REMAP(0);//Remap USART2 to PTD5/6
u
/* Definition for USARTx Pins */
//# defineusartx _ tx _ ping Pio _ pin _ 5
//# defineusartx _ tx _ gpio _ portgpiod
//# defineusartx _ rx _ ping Pio _ pin _ 6
//# defineusartx _ rx _ gpio _ portgpiod
#define USARTx_TX_PIN G
PIO_PIN_2#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_RX_PIN GPIO_PIN_3
#define USARTx_RX_GPIO_PORT GPIOA
终于可以编译运行了,用USB线把板子连到PC的USB口,记得把板子的PTA2和PTA3引脚短接起来。在设备管理器我们看到多出来一个串口,看它的属性会看到它的VID,PID跟我们程序中设置的一致。
用串口助手打开此串口,发送字符串,会看到返回同样的字符串。
下面我们来看一下具体的工作过程。
3. USB枚举(Enumeration)
当我们给设备上电,程序控制芯片内集成的上拉电阻连接至USBDP时,USB主机(PC端)会检测到这一变化并向设备供电。此时设备处于Powered状态。
主机等待100ms设备稳定后复位并使能此端口,此时设备可以从Vbus获取不超过 100mA 的电流,其默认地址是0,处于Default状态。
主机通过0地址向该设备发送Get_Descriptor标准请求,获取设备的描述符。主机再次复位该PORT,并发送标准请求Set_Address给设备分配一个地址,之后的通信都是用此地址,设备进入Address状态。
主机通过新地址向设备再次发送Get_Descriptor标准请求,获取设备描述符。发送Get_Configuration请求,获取配置描述符。一个设备可以有多个配置,主机选择合适配置,通过 Set_Configuration请求对设备而进行配置,设备进入Configured状态。
USB的枚举过程是标准的,所以库里也有对应的标准处理代码。我们可以不用关心。好了,现在可以开始数据的双向传输了。
4. 数据传输
我们已经了解所有USB传输都是由USB主机(Host)发起的,作为USB设备只能是被动的等待。当Host下发请求时会在设备中产生各种中断,设备完成各种中断的处理就行了。其中需要特别关注的有两个:
OEPINT(Output Endpoint Int),表明主机下发了数据。
IEPINT(Output Endpoint Int)。表明主机请求设备上传数据。
那么用户在代码里如何收发USB数据的呢?
我们在u里关注下面这些就够了:
uint8_t UserRxBuffer[APP_RX_DATA_SIZE]; //USB下发数据缓冲区
uint8_t UserTxBuffer[APP_TX_DATA_SIZE]; //需要发给USB上位机的数据缓冲区
下面这个函数是用户用来处理接收缓冲区数据的,在初始化时需要传递给USB驱动,然后驱动收到USB下发的数据后会回调此函数。在例程中此函数把接收数据转发给了USART2。当然你也可以什么都不做。
static int8_t CDC_Itf_Receive(uint8_t * Buf, uint32_t * Len);
那么如果有数据需要发给上位机呢?我们可以用下面这个函数:
USBD_CDC_TransmitPacket(&USBD_Device);
注意此数据是先放入IN端点,然后等待IEPINT中断发生时才被取走发送。
5. 一个重要又容易被忽视的问题
至此好像万事大吉了。
等等,如果产品这样发出去,你可能给公司惹麻烦了!
还有一个很重要的问题我们千万不要忽视,就是VID和PID,即厂商识别符(Vendor ID)和产品识别符(Product ID)。我们例程中使用的是VID 0x0483, PID 0x5740。这个VID是专门分配给ST的,虽然我们用这个号程序也能运行,但是不符合规范的。我们的可以在 u 网站查到当前为所有USB厂商分配的VID。如果我们要开发USB设备,还要向USB组织申请自己的VID,之后还要做微软徽标认证,就可以畅行无阻了。
参考资料:
UM1734 STM32Cube USB device library
USB Specification 2.0
Universal Serial Bus Class Definitions for Communications Devices 1.2
STM32F105xx Datasheet
STM32F105xx RM
1.《【板子串口怎么连接电脑】单片机周边模块扭矩5、USB开发,不要犯这个错误》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《【板子串口怎么连接电脑】单片机周边模块扭矩5、USB开发,不要犯这个错误》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/why/3050108.html