单片机外围模块漫谈之五,USB开发,别犯这个错误
1.
概述我们已经对USB硬件和数据的四种传输类型有了一个基本的了解。
控制传输(Control Transfers)
批量传输(Bulk Data Transfers)
中断传输(Interrupt Data Transfers)
同步传输(Isochronous Data Transfers):
下面我们通过一个例子看一下USB的具体工作过程。在此我们用一个比较实用的例子,就是把我们的板子用USB连接至PC,然后在PC端出现一个模拟串口,通过串口助手打开这个串口,然后实现数据的双向传输。最后我们聊一下很多工程师都会忽视的USB认证问题。
2. 例程
我们打开ST的Cube库中的CDC例程:
STM32Cube_FW_F1_V1.8.0\Projects\STM3210C_EVAL\Applications\USB_Device\CDC_Standalone\MDK-ARM\Project.uvprojx
这个例程用到USB的同时还会用到USART,USB从PC端收到数据后会转发到USART,从USART接收到消息会上传至PC。我们可以把USART的TX和RX短接,这样从PC端下发的数据会原样回传给PC端。
这个例程使用的硬件是STM3210C-EVAL,原理图可以在stmcu.org.cn找到。如果我们使用的是其它板子,就需要在这个工程基础上做一些改动。比如现在我们使用STM32F105RBT6,8M晶振,串口用PTA2,PTA3,那么我们的要做如下修改:
首先,修改使用的MCU:
然后修改时钟初始化部分。下图为STM32F105时钟模块示意图。USB工作需要48MHz的时钟。
(STM32F105xx Datasheet)
如果板子的晶振是8M,那么参数需要做如下配置:
(OSC IN = 8M)
PREDIV1SRC = 0b0, HSE oscillator clock selected as PREDIV1 clock entry
PREDIV1 = 0b0, PREDIV1 input clock not divided
PLLSRC = 0b1, Clock from PREDIV1 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
USBPRE = 0, PLL clock is divided by 1.5 (or PLLVCO/3)
USB Clock = = PLLCLK/1.5 = 72M/1.5 = 48M
例程中的对应代码修改:
最后修改使用的串口引脚:
stm32f1xx_hal_msp.c
//AFIOCOMx_REMAP(0); // Remap USART2 to PTD5/6
usbd_cdc_interface.h
/* Definition for USARTx Pins */
//#define USARTx_TX_PIN GPIO_PIN_5
//#define USARTx_TX_GPIO_PORT GPIOD
//#define USARTx_RX_PIN GPIO_PIN_6
//#define USARTx_RX_GPIO_PORT GPIOD
#define USARTx_TX_PIN GPIO_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数据的呢?
我们在usbd_cdc_interface.c里关注下面这些就够了:
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的,虽然我们用这个号程序也能运行,但是不符合规范的。我们的可以在 usb.org/developers 网站查到当前为所有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
一款深藏功与名的国产单片机——F1C100A
说到单片机,可能首先想到的是atmel的at89c52,这多亏了大学教材的传承发扬。从我们的老师的老师,用到我们,说是大学的传家宝都不夸张。然后,就是现在大规模流行的STM32单片机,经过ST每个季度的峰会和国内的野火、正点原子等厂商的大力推广,电子专业从业的工程师只有两种人不知道它,那么是特别牛逼的,要么是装逼的。但这里要说的是一款国产的单片机,很低调的一款------全志的F1C100A。
F1C100A
1、资源
从这款IC的数据框图来看,粗略的可以得到几个点:
A、支持高清解码,分辨率为1920*1080。这是个什么概念呢?咱们可以打开笔记本电脑,如果是win10系统,那么咱们的最高分辨率就是这个。
但是,不仅仅是解码,它还支持编码,也就是可以录像,分辨率为1280*720。虽然不是专业的录像机IC,但这个分辨率也很实在了,已经有点那会彩电的感觉了。对比STM32F1系列的单片机,虽然也能图形处理 ,但也只基于静态界面。
B、作为单片机,USB、SPI、Timer、TWI(就是平常的IIC)都是有的,而且还有IIS接口,可以接个话筒,这个功能不是低端应用的单片机能有的。不过STM32F1系列的MCU,这些外设都有。
C、cpu已经具有了I-cache和D-cache,本身来说这两者有一定的区别,但是这里都看做cache来说,都是SRAM。因为CPU从这个里面读数据特别快,所以将它作为DRAM到CPU的一个仓库。
既然有了SRAM那么DDR的控制是肯定不会少了,不然怎么跑Linux系统。说到Linux系统,STM32H7系列也是可以跑Linux。
说了这么多,咱们来看看价格 全新原装解码芯片 F1C100A C100A (带A)TQFP128------9.50元 、STM32F103C8T6 LQFP48 ARM芯片 嵌入式微控制器------7.50元 、STM32H743VIT6 LQFP100 ARM 32位微控制器芯片原装正品------58.95元 。
这个IC价格完全可以在30元以内跑起最小开发系统板,自己打板子的那种。
F1C100A的系统框图
2、资料
既然这IC支持Linux系统,那么有没有开源社区在做开发呢。是的,还真有那就是荔枝派Nano 。荔枝派Nano的主芯片—全志F1C100s;Arm9架构,16KB D-Cache,32KB I-Cache,支持从SPI Flash或TF卡启动,支持USB OTG载入更新。官方的宣传更加厉害,9.9元起,这个核心板就是一块STM32F1ZET6的价格。那么,我们来看看这个9.9元买到的板子怎么入门。
荔枝派nano
因为是开源社区,所以板子的基本操作官网(http://nano.lichee.pro/)都有,其中包括系统适配篇、驱动开发篇、应用开发篇。依靠这些资料进不了华为,进不了阿里,但是入门个Linux应该是可以的。高级不高级不知道,但是价格亲民哪,9.9元入门Lniux 。
荔枝派官网
3、应用
学习的目的不是学习,而是应用,不然谁知道学得怎么样。接下来介绍一款应用,各位绝对见过,只是没有细究------看戏机。
第一张图是看戏机的背面,标明了输入电压和输出功率。为什么还有个输出功率呢,外接喇叭的,或许是为了可以大家一块听戏。
背面
第二张图是看戏机的正面,两边按钮,中间屏幕,有点游戏手柄的感觉。看这画质,是不是能够感受到这满满的年代感。
正面
最后一张图,咱们来看看内部电路,能够看到USB接口、miniusb接口、耳机输出接口,最明显的就是F1C100A和海力士的内存了。
主控IC
这个设计不能说是复杂,但是很精巧,确实不浮夸。
最后的话:
看到这些,是不是有种用F1C100A玩Linux的感觉了。
相关问答
如何用51 单片机驱动USB 鼠标?有3种办法去实现:1、使用您手里的PL2303芯片串口接PD12USB芯片,然后自己写固件之后驱动。2、使用C8051F320带USB接口的51单片机直接驱动,也需要启动固件。3...
51 单片机 最小系统板如何连接 USB ?单片机最小系统板不能直接和PC机USB相连,如果是支持ISP下载的单片机,可以通过USB转232(TTL电平),单片机的串口RXD(P3.0)接232的TXD,单片机的串口TXD(P3....单.....
单片机 无法 驱动 用 usb 电脑供电db9这样接?如果只是单纯的给单片机供电,用一个两端都是usb的接口将单片机与电脑相连,而且你上面的max232,RS232(即db9)是用来给单片机下载程序的,根本不能给单片机供...
单片机 +电脑 usb 接口供电?USB供电电流最好在100mA以下,如果超过的话,要在USB驱动的描述符上做修改。如果你的USB只是用来供电而没有USH协议的话,就没辙了。如果只是最小系统的话,不...
单片机USB 直接插上就能下载数据打通电源,为什么还要有 USB 转T...亚马逊USB连接线讨论回答(5)大多数单片机开发板上的USB串口只是用来供电的,大多数单片机也不带USB功能,甚至板上也没集成USB转TTL芯片USB转TLL线的作用,一是...
怎样用自己焊的板子 单片机usb 与电脑联接-ZOL问答USB连接单片机时需要用USB转串口芯片,CH341或PL2303,单片机的RXTX接芯片,详见芯片说明,也可以用市场上卖的USB转串口接头连接。重装usb驱动或者换个usb线试试...
学习51 单片机 需要用到哪些硬件 开发 工具?学习单片机主要是学习三方面的内容:1)单片机的使用方法;2)单片机外设电路的设计;3)单片机程序的设计。而且单片机是一门偏重动手实践的技术,所以在学习的过程...
win8.1的系统,51 单片机 插进 USB 接口后就显示这,而且烧录不进...亚马逊USB连接线讨论回答(6)肯定是驱动没装好,建议重新安装,完成后重启电脑在试试。你好,这个原因你应该看看设备管理器里面的串口用的对你不对,我的公司里...
在keil中怎么设置通过串口向 单片机 下载程序-ZOL问答有专门的单片机烧写软件的。那个软件的名字叫STC-ISPV391(你可以下载个更高版本的)的,你的开发板里面应该自带下载软件的啊!如果你用的下载下是USB转串口的线...
32 单片机 可以用 usb 下载程序吗?32单片机是指使用ARMCortex-M3核心的32位微控制器。通常情况下,32单片机可以通过USB接口进行程序下载和调试。在32单片机中,常见的下载和调试接口是JTAG(Joi...