基于高速51单片机的模拟USB接口设计
作者:廖颂文
摘要:参照AVRUSB技术给出了51单片机通过模拟USB通信的实现方法。用VC编写了上位机软件,通过libusb驱动实现了PC与ST12LE5608AD的通信。
关键字:AVRUSB,模拟USB,NRZI编码,USB通信协议,libusb驱动,VC。
1994年11月11日USB正式诞生,1996年1月15日,USB1.0发布,1998年USB开始流行,2000年4月27日高速USB2.0发布,传输速率达480Mb/S, 2008年11月12日USB3.0发布,传输速率可达5Gb/s。至今USB被广泛应用,带串口和并口的PC越来越少,这使得基于单片机的设备必须将串口经过USB芯片转换才能和PC通信,为了解决MCU和PC通信的问题,1998年Atmel公司开发了AVRUSB技术,这是一种不通过USB芯片,直接使用单片机的IO口模拟USB通信协议完成单片机与PC通信的技术,理论上任何一款速度足够快的高速单片机都可以通过IO模拟USB1.1的通信协议。本文给出了广泛使用的也是最易上手的低成本1T 51单片机模拟USB通信实现的方法。
USB1.1使用单端伪差分信号,速率1.5Mb/S;USB2.0使用差分信号传输,最低速率12Mb/S,最高480Mb/S,详细的USB通信协规范可以参考《Universal Serial Bus Specification》。所以对于51、 AVR或STM8单片机,只能模拟出USB1.1规范的通信。本文参照AVRUSB 给出了USB在STC12LE5608AD单片机上的实现,适用于STC12系列和STC10系列的单片机,也可以移植到性能相同的51单片机。重点是SIE的实现,其余部分可以参考AVRUSB相关技术文章。
USB1.0通信中使用的是NRZI编码,信号是伪差分信号,当Dp=1时Dm=0,Dp=0时Dm=1,SE0和SE1信号信号除外。这种编码不需要时钟和数据一起发送,电平跳变代表0,无电平跳变代表1。为了避免一长串1导致的接收方失去同步信号,USB使用位填充机制,在6个连续1后面强制填充0,特殊情况是6个1后面原本就是0,但USB位填充机制还是会在6个1后面填充0,将信号状态变为11111100,接收方必须将填充的0丢弃,还原数据。如图1-1所示:X表示是填充的数据位。
图1-1
对比AVRUSB,51单片机必须完成5部分的功能USBSYNC同步帧的识别,USB数据的接收,USB数据的解码,USB数据回传。其中USB SYNC同步帧的识别,USB数据的接收,有着严格的时序要求和实时性。 USB数据的解码和USB数据回传在USB通信超时之前完成即可。
USB主机与MCU通信前,发送数据是先发送SYNC同步帧,接着是PID等数据,如图1-2所示。
图1-2
当主机发送USB数据给从机时,先输出SYNC同步帧,Dm被首先变低,MCU利用低电平进入中断,经过延时进入中断USB通信处理程序,通过示波器测量工作在33MHZ的STC12LE5608AD这个延时大约640ns。这个延时对于不同型号,不同批次的单片机会有差异,气温变化也会导致这个延时变化。SYNC同步帧识别必须将延时考虑进去,详见代码。
接下来是SIE的核心代码,由于STC12单片机的速度比AVR单片机慢,不能像AVR单片机一样接收1bit后异或操作得到实际数据,所以用跳转取代异或操作。接收1字节的流程如图2-1所示,程序中使用了宏汇编,并且每个字节调用一次宏,最后拼接完11字节的数据(去掉同步信号,低速USB一次最多发送11字节数据,包括1字节PID、8字节数据和2字节CRC校验数据),这种算法虽然增加了程序大小,但MCU处理速率可以低一点,适用于多数1T MCU。发送数据流程如图2-2。
图2-1
图2-2
使用注意事项:
Usbdrv.c中的void usbProcessRx(void)函数用于处理控制传输,包括USB识别过程中必须的操作和用户控制传输,函数被IN令牌处理函数调用,必须在USB超时前完成所有功能,所以回传的数据中CRC是提前计算的。如果修改这部分的代码,例如idVendor、idProduct和usbDescriptorStringVendor等必须同时修改CRC值。
如图3-1,例子中使用的是P3.3和P3.4口,中断用的是INT1。如果使用其它接口,需要修改A51_USB.A51文件中对应的USB_INT_Fg、USB_INT_En、USB_Dp、USB_Dm、USB_Port、USB_CFG_IN_P、USB_CFG_IN_N 、USB_CFG_OUT_P、USB_CFG_OUT_N、USBddr_I、USBddr_O定义和usbdrv.h文件中USBDDR_I、USBDDR_O、USB_DP_CFG、USB_DM_CFG、USB_CFG_INT、USB_INT_EN、USB_INT_FG、USB_INT_TYPE的定义。STC12系列单片机和STC10系列单片机的指令一样,但IO口配置寄存器的定义不一样,移植时需要交换PxM0和PxM1位置,这一点对比两个型号的datasheet即可发现。
使用3.3V的STC12LE5608ADUSB端口不需要加嵌位电路。5V的STC12系列单片机,需要在Dp和Dm信号加3.3V嵌位电路。因为SIE 在每1bit只采集1次信号,这对于低速的USB是足够的,但在干扰较大情况下,可以按照USB规范在Dp和Dm信号线上增加电容滤除高频干扰,但应注意信号上升时间增加导致SIE采样点偏移的问题。
A51USB SIE必须工作在33MHZ,受处理速度限制A51USB SIE在接收数据时直接丢弃了CRC16校验,PID和地址端口数据直接使用比对判断结果,没有CRC5校验。如需校验数据可以在应用层校验。例子中A51USB只使用了控制传输,没有使用中断传输,传输速率可以达到5KB/S。最后提供基于VC的上位机测试程序源码及MCU源码(文件名A51USBDataTest、USB_ADC),用户可以在此基础上修改。PC程序中使用的libUSB和 AVRUSB中的一样,这里不再赘述。
图3-1
参考文档:
1.《USB2.0原理与工程开发》 (第2版),李英伟等著,工业出版社。
2. 《AVR309 USB协议转换到UART》
3.《Universal Serial Bus Specification Revision1.1》
联系方式:[email protected]