基于uCOSⅡ和CH375的U盘数据读写接口设计
- 格式:pdf
- 大小:218.01 KB
- 文档页数:3
单片机通过CH375读写U盘时的注意事项版本:1B1、概述USB总线接口芯片CH375支持USB-HOST和USB-DEVICE,可以用于单片机读写U盘。
本说明中的多数内容为建议性说明,而非强制性说明,建议的目的旨在提高最终产品的稳定性和可靠性,很多内容只是针对一般情况和大多数用户而言,而未考虑个别或者例外。
本说明中列举了一些发生在某些品牌U盘上的怪现象,都是我们实际测试现象的描述,我们并没有以此评价U盘的优劣,因为实际上它们可能已经算是所有U盘中比较优秀的几种,而且,我们也不排除这仅仅是品牌U盘中的个别现象,只是正好被我们碰到而已。
2、硬件2.1. CH375芯片1) CH375内部含有时钟振荡电路,但是驱动能力比普通的单片机要弱一些,振荡波形通常比较接近正弦波(普通单片机的振荡波形接近方波),这种弱振荡的优点是对外产生的电磁干扰较少,缺点是理论上自身比较容易受外来的干扰,当然,如果电路及PCB设计良好则不会产生干扰。
2) CH375的时钟可以使用普通12MHz石英晶体或者普通12MHz有源晶振,但是不宜使用频率误差较大的陶瓷晶体。
对于普通石英晶体,虽然CH375手册中标明振荡电容为15pF,但是原则上应该根据晶体厂家的推荐值选择匹配的振荡电容,例如是18pF、20pF、22pF、24pF、27pF等。
3) 如果电源电压为3.3V,可以将XI引脚的电容C1容量选用小些(例如10pF),或者用有源晶振或者外部振荡电路为CH375的XI引脚提供时钟,以保证时钟稳定性。
有的电路还可以在CH375的XO引脚串接100Ω到300Ω的电阻,改善振荡参数。
对于CH375B芯片,不需要外串电阻。
4) 为了降低电磁辐射,并减少来自外界的干扰,振荡电路的晶体X1的金属外壳应该接地,晶体X1以及电容C1、C2应该尽量靠近CH375,C1和C2的GND端应该尽量接近CH375的GND端,相关的PCB走线应该尽量短,并且可以在周边环绕接地线或敷铜。
CH375是USB总线的通用接口芯片,支持HOST主机方式和SLAVE设备方式。
MCS-51单片机读写U盘的电路原理图,CH375芯片的TXD引脚接高电平,工作于串口方式。
在串口方式下,CH375只需要与单片机/DSP/MCU连接3个信号线,TXD引脚、RXD引脚以及INT#引脚,其他引脚都可以悬空。
除了连接线较少之外,其他外围电路与并口方式基本相同。
由于INT#引脚和TXD 引脚在C H375复位期间只能提供微弱的高电平输出电流,在进行较远距离的连接时,为了避免INT#或者TXD在CH3 75复位期间受到干扰而导致单片机误操作,可以在INT#引脚或者TXD引脚上加阻值为1~5kΩ的上拉电阻,以维持较稳定的高电平。
在CH375芯片复位完成后,INT#引脚和TXD引脚将能够提供5mA的高电平输出电流或者5mA的低电平吸入电流。
单片机读写U盘的接口由于CH375内置了处理Mass-Storage海量存储设备的专用通信协议的固件,所以嵌入式系统的单片机可以通过CH375将U盘(USB闪存盘、USB外置硬盘)作为可移动的大容量存储器。
数据读写只需要几条指令,而不需要详细了解USB通信协议。
如果嵌入式系统需要将USB存储设备组织为文件系统,可调用CH375文件级子程序库提供的接口API,由子程序库处理文件系统。
MCS-51单片机读写U盘范例源程序如下:#include#include "CH375INC.H"#include /* 以下定义适用于MCS-51单片机 */#define UINT8 unsigned char#define UINT16 unsigned short#define UINT32 unsigned long#define UINT8X unsigned char xdata#define UINT8VX unsigned char volatile xdataUINT8VX CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */UINT8VX CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */#define CH375_INT_WIRE INT0 /* P3.2, 连接CH375的INT#引脚,用于查询中断状态 */UINT8X DISK_BUFFER[512*32] _at_ 0x0000; /* 外部RAM数据缓冲区的起始地址 */UINT32 DiskStart; /* 逻辑盘的起始绝对扇区号LBA */UINT8 SecPerClus; /* 逻辑盘的每簇扇区数 */UINT8 RsvdSecCnt; /* 逻辑盘的保留扇区数 */UINT16 ; FATSz16; /* FAT16逻辑盘的FAT表占用的扇区数 *//* ********** 硬件USB接口层,无论如何这层省不掉,单片机总要与CH375接口吧 */void mDelaymS( UINT8 delay ) {UINT8 i, j, c;for ( i = delay; i != 0; i -- ) {for ( j = 200; j != 0; j -- ) c += 3;for ( j = 200; j != 0; j -- ) c += 3;}}void CH375_WR_CMD_PORT( UINT8 cmd ) { /* 向CH375的命令端口写入命令 */CH375_CMD_PORT=cmd;for ( cmd = 2; cmd != 0; cmd -- ); /* 发出命令码前后应该各延时2uS */}void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的数据端口写入数据 */CH375_DAT_PORT=dat; /* 因为MCS51单片机较慢所以实际上无需延时 */}UINT8 CH375_RD_DAT_PORT( void ) { /* 从CH375的数据端口读出数据 */return( CH375_DAT_PORT ); /* 因为MCS51单片机较慢所以实际上无需延时 */ }UINT8 mWaitInterrupt( void ) { /* 等待CH375中断并获取状态,返回操作状态 */while( CH375_INT_WIRE ); /* 查询等待CH375操作完成中断(INT#低电平) */CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断,获取中断状态 */return( CH375_RD_DAT_PORT( ) );}/* ********** BulkOnly传输协议层,被CH375内置了,无需编写单片机程序 *//* ********** RBC/SCSI命令层,虽然被CH375内置了,但是要写程序发出命令及收发数据*/UINT8 mInitDisk( void ) { /* 初始化磁盘 */UINT8 Status;CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */Status = CH375_RD_DAT_PORT( );if ( Status == USB_INT_DISCONNECT ) return( Status ); /* USB设备断开 */CH375_WR_CMD_PORT( CMD_DISK_INIT ); /* 初始化USB存储器 */Status = mWaitInterrupt( ); /* 等待中断并获取状态 */if ( Status != USB_INT_SUCCESS ) return(Status ); /* 出现错误 */CH375_WR_CMD_PORT( CMD_DISK_SIZE ); /* 获取USB存储器的容量 */Status = mWaitInterrupt( ); /* 等待中断并获取状态 */if ( Status != USB_INT_SUCCESS ) { /* 出错重试 *//* 对于CH375A芯片,建议在此执行一次CMD_DISK_R_SENSE命令 */mDelaymS( 250 );CH375_WR_CMD_PORT( CMD_DISK_SIZE ); /* 获取USB存储器的容量 */Status = mWaitInterrupt( ); /* 等待中断并获取状态 */}if ( Status != USB_INT_SUCCESS ) return( Status ); /* 出现错误 */return( 0 ); /* U盘已经成功初始化 */}UINT8 mReadSector( UINT32 iLbaStart, UINT8 iSectorCount, UINT8X *oDataBuffer ) {UINT16 mBlockCount;UINT8 c;CH375_WR_CMD_PORT( CMD_DISK_READ ); /* 从USB存储器读数据块 */CH375_WR_DAT_PORT( (UINT8)iLbaStart ); /* LBA的最低8位 */CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 8 ) );CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 16 ) );CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */CH375_WR_DAT_PORT( iSectorCount ); /* 扇区数 */for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- ) {c = mWaitInterrupt( ); /* 等待中断并获取状态 */if ( c == USB_INT_DISK_READ ) { /* 等待中断并获取状态,请求数据读出 */CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从CH375缓冲区读取数据块 */c = CH375_RD_DAT_PORT( ); /* 后续数据的长度 */while ( c -- ) *oDataBuffer++ = CH375_RD_DAT_PORT( );CH375_WR_CMD_PORT( CMD_DISK_RD_GO ); /* 继续执行USB存储器的读操作 */}else break; /* 返回错误状态 */}if ( mBlockCount == 0 ) {c = mWaitInterrupt( ); /* 等待中断并获取状态*/if ( c== USB_INT_SUCCESS ) return( 0 ); /* 操作成功 */}return( c ); /* 操作失败 */}/* ********** FAT文件系统层,这层程序量实际较大,不过,该程序仅演示极简单的功能,所以精简 */UINT16 mGetPointWord( UINT8X *iAddr ) { /* 获取字数据,因为MCS51是大端格式 */ return( iAddr[0] | (UINT16)iAddr[1] << 8 );}UINT8 mIdenDisk( void ) { /* 识别分析当前逻辑盘 */UINT8 Status;DiskStart = 0; /* 以下是非常简单的FAT文件系统的分析,正式应用绝对不应该如此简单 */Status = mReadSector( 0, 1, DISK_BUFFER ); /* 读取逻辑盘引导信息 */if ( Status != 0 ) return( Status );if ( DISK_BUFFER[0] != 0xEB && DISK_BUFFER[0] != 0xE9 ) { /* 不是逻辑引导扇区 */DiskStart = DISK_BUFFER[0x1C6] | (UINT16)DISK_BUFFER[0x1C7] << 8| (UINT32)DISK_BUFFER[0x1C8] << 16 | (UINT32)DISK_BUFFER[0x1C9] << 24; Status = mReadSector( DiskStart, 1, DISK_BUFFER );if ( Status != 0 ) return( Status );}SecPerClus = DISK_BUFFER[0x0D]; /* 每簇扇区数 */RsvdSecCnt = DISK_BUFFER[0x0E]; /* 逻辑盘的保留扇区数 */FATSz16 = mGetPointWord( &DISK_BUFFER[0x16] ); /* FAT表占用扇区数 */return( 0 ); /* 成功 */}UINT16 mLinkCluster( UINT16 iCluster ) { /* 获得指定簇号的链接簇 *//* 输入: iCluster 当前簇号, 返回: 原链接簇号, 如果为0则说明错误 */UINT8 Status;Status = mReadSector( DiskStart + RsvdSecCnt + iCluster / 256, 1,DISK_BUFFER );if ( Status != 0 ) return( 0 ); /* 错误 */return( mGetPointWord( &DISK_BUFFER[ ( iCluster + iCluster ) & 0x01FF ] ) ); }UINT32 mClusterToLba(UINT16 iCluster ) { /* 将簇号转换为绝对LBA扇区地址 */ return( DiskStart + RsvdSecCnt + FATSz16 * 2 + 32 + ( iCluster - 2 ) *SecPerClus );}void mInitSTDIO( void ) { /* 仅用于调试用途及显示内容到PC机,与该程序功能完全无关 */SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 0xf3; TR1=1; TI=1; /* 24MHz, 9600bps */}void mStopIfError( UINT8 iErrCode ) { /* 如果错误则停止运行并显示错误状态 */ if ( iErrCode == 0 ) return;printf( "Error status, %02X", (UINT16)iErrCode );}main( ) {UINT8 Status;UINT8X *CurrentDir;UINT16 Cluster;mDelaymS( 200 ); /* 延时200毫秒 */mInitSTDIO( );CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); /* 初始化CH375,设置USB工作模式 */CH375_WR_DAT_PORT( 6 ); /* 模式代码,自动检测USB设备连接 */while ( 1 ) {printf( "Insert USB disk" );while ( mWaitInterrupt( ) != USB_INT_CONNECT ); /* 等待U盘连接 */mDelaymS( 250 ); /* 延时等待U盘进入正常工作状态 */Status = mInitDisk( ); /* 初始化U盘,实际是识别U盘的类型,必须进行此步骤 */ mStopIfError( Status );Status = mIdenDisk( ); /* 识别分析U盘文件系统,必要操作 */mStopIfError( Status );Status = mReadSector( DiskStart + RsvdSecCnt + FATSz16 * 2, 32,DISK_BUFFER );mStopIfError( Status ); /* 读取FAT16逻辑盘的根目录,通常根目录占用32个扇区*/for ( CurrentDir = DISK_BUFFER; CurrentDir[0] != 0; CurrentDir += 32 ) {if ( ( CurrentDir[0x0B] & 0x08 ) == 0 && CurrentDir[0] != 0xE5 ) {CurrentDir[0x0B] = 0; /* 为了便于显示,设置文件名或者目录名的结束标志 */ printf( "Name: %s", CurrentDir ); /* 通过串口输出显示 */}} /* 以上显示根目录下的所有文件名,以下打开第一个文件,如果是C文件的话 */if ( (DISK_BUFFER[0x0B]&0x08)==0 && DISK_BUFFER[0]!=0xE5 && DISK_BUFFER[8] =='C' ) {Cluster = mGetPointWord( &DISK_BUFFER[0x1A] ); /* 文件的首簇 */while ( Cluster < 0xFFF8 ) { /* 文件簇未结束 */if ( Cluster == 0 ) mStopIfError( 0x8F ); /* 对于首簇,可能是0长度文件*/Status = mReadSector( mClusterToLba( Cluster ), SecPerClus,DISK_BUFFER );mStopIfError( Status ); /* 读取首簇到缓冲区 */DISK_BUFFER[30] = 0; printf( "Data: %s", DISK_BUFFER ); /* 显示首行*/Cluster = mLinkCluster( Cluster ); /* 获取链接簇,返回0说明错误 */}}while ( mWaitInterrupt( ) != USB_INT_DISCONNECT ); /* 等待U盘拔出 */mDelaymS( 250 );}}该程序可以支持WINDOWS按FAT16格式化的U盘__________________________。
基于CH375的USB数据采集应用程序摘要利用USB接口技术,采用USB模块CH375与AT89C81结合,实现与计算机通信。
给出了CH375与单片机接口电路的原理简图,并详细介绍了实现USB数据传输的上位机的程序设计。
关键词:USB,CH375,AT89C51,上位机一、CH375模块简介USB模块CH375是一个USB总线的通用设备接口芯片,用户无需编写驱动程序,内置有USB通讯中的底层协议,完全满足USB1.1标准。
具有8位数据总线(D0~D7)、地址输入(A0)、读(RD#)、写(WR#)、片选控制线(CS#)以及中断输出(INT#),可以方便地挂接到单片机的数据总线上。
当A0为低电平时选择数据端口,单片机通过8位并口对CH375进行读写数据;为高电平时选择命令端口,可以向其写入命令。
在本地端,单片机对CH375的操作是采用命令加数据的I/O操作方式,任何操作都是先发命令给CH375,然后执行数据输入输出。
CH375接收到上位机发送的数据或者发送完给上位机的数据后,以中断方式通知单片机,并进行相应处理。
将CH375芯片的驱动程序、动态链接库拷贝到上位机中,利用CH375动态链接库DLL 提供的API函数对其进行操作,对USB设备的通信就几乎和访问本地硬盘中的文件差不多了。
二、系统原理图CH375的数据总线直接与AT89C51的数据总路线P0口相连,中断输出INT#与AT89C51的外部中断INT1相连,RD#、WR#与A T89C51的RD、WR对应,片选A0及CS#分别接P2.0和P2.1。
接接线电路图如下:三、设计通信方案USB模块CH375在计算机应用层与其本地端单片机AT89C51之间提供了端对端的连接。
统一采用数据加应答方式进行通信,所有的通信都由计算机应用层发起,然后以接收到单片机的应答结束。
单一通道完整的通信过程包括:①计算机应用层按事先约定的格式将数据请求发送给CH375;②CH375以中断方式通知单片机。
收稿日期:2005-09 作者简介:秦霆镐(1953—),男,副教授,主要研究方向为自动测控技术及楼宇自动化等。
图2 CH375的U 盘读写模块外观图基于CH375的U 盘读写模块在移动数据交换中的应用秦霆镐,凌 辉,庞海珑(上海大学自动化系,上海200072) 摘要:提出一种基于CH375的U 盘读写模块与51系列单片机相结合以实现US B 主机功能的方法,给出了该方法的软硬件具体实现。
关键词:US B 主机;数据交换;CH375中图分类号:TP39 文献标识码:B 文章编号:1006-2394(2006)01-0034-03Appli ca ti on of USB M odule Ba sed on CH375i n Da t a ExchangeQ I N G Ting 2hao,L I N G Hui,P ANG Hai 2l ong(Aut omati on Depart m ent,Shanghai University,Shanghai 200072,China )Abstract:A method of realizati on of US B host functi on is devel oped by combiningMCS 251MC U and the US B module based on the chi p of CH375.The design of s oft w are and hard ware is p resented in detail and p r os pect is made .Key words:US B host;data exchange;CH3751 基于CH375的U 盘读写模块简介CH375是一个US B 总线的通用接口芯片,支持HOST 主机方式和S LAVE 设备方式。
在本地端,CH375具有8位数据总线和读、写、片选控制线以及中断输出,可以方便地挂接到单片机/DSP /MCU 等控制器的系统总线上。
信息产业引言在人们的日常生活中或是在工业控制领域,常常需要一套简单的设备,长时间采集数据,然后集中分析。
在这种情况下,传感器+单片机+USB接口+U盘存储器是一种简便、实用、成本小的解决方案。
文中主要介绍了单片机与CH375的硬件连接,U盘数据存储格式以及软件设计。
1硬件设计1.1芯片选择微处理器芯片的选择依据是片内RAM,片内RAM主要作用是临时存储采集到的数据(数据缓冲区),如果片内RAM不够大,那么会导致频繁的写U盘,这对U盘的寿命和通讯的速率都会产生影响,在此选择AVR128(4K片内RAM)。
USB接口芯片选择CH375,CH375是国内的南京沁恒公司开发的产品,是USB总线的通用接口芯片,支持USB-HOST主机方式和USB-DEVICE/SLAVE设备方式,内置了处理Mass-Storage海量存储设备的专用通讯协议的固件。
外部单片机可以直接以扇区为基本单位读写常用的USB存储设备(包括USB硬盘/USB闪存盘/U盘)。
存储设备可选普通U盘,价格低、寿命长、携带方便。
1.2硬件连接(见图1)单片机与CH375模块之间的连接使用8位并行数据线、A0线、读使能、写使能、片选和中断信号,可以方便进行数据交换。
U盘直接插在CH375模块的USB接口上。
具体电路图如图2。
片选是通过地址线A9来直接操作的,低电平选中,A0接地址线,中断接在INT上。
单片机控制CH375的命令是通过在数据总线上写命令字节来实现的,其中地址线A0用来区分写命令或者数据,当A0=1时可以在总线上写命令;当A0=0时可以在总线上读写数据。
所以,单片机写命令即为写地址0x1**(**为命令字节),读写数据则为0x0**(**为数据字节)。
2U盘数据存储结构2.1存储数据的两种方式方式一:不按PC机上文件系统的方式存储,这种方式只是单纯的把U盘作为一个ROM存储器。
这种存储数据的方式对于单片机来说比较简单,但是把U盘插入电脑后,不能直接读出U盘的数据。
基于CH375接口电路的LPT-USB打印机驱动器的设计与实现1 本课题来源于北京普析通用公司。
由于该公司现有光谱仪器的单机版(如1810和T6等)采用的是并行口打印技术,而随着USB打印机技术的逐渐普及,并行口打印机越来越少,有些用户原有的打印机只是USB接口而非并行口,因此现有仪器对打印机的支持不能适应用户需要。
为了使该公司的并行口仪器直接和USB打印机相连,笔者设计了一种 LPT-USB打印机驱动器,实现并口仪器与USB打印机的连接。
笔者利用单片机和USB总线接口器件实现LPT-USB打印机驱动器的设计。
利用该设计将能够实现并行打印口数据在USB打印机上的直接打印,克服了有些并口仪器必须连接并口打印机才能打印的弊端,极大地方便了用户的使用。
2 CH3752.1 CH375 CH375 是一个USB总线通用接口电路,支持HOST主机方式和SLAVE设备方式。
CH375内部集成了PLL倍频器、主从USB接口SIE、数据缓冲区、被动并行接口、异步串型接口、命令解释器、控制传输的协议处理器、通用的固件程序等。
在本地端,CH375具有8位数据总线和读、写、片选控制线及中断输出,可以方便地挂接到单片机、DSP、MCU等控制器的系统总线上。
CH375的USB主机方式支持各种常用的USB全速设备,外部单片机、DSP、MCU可以通过CH375按照相应的USB协议与USB设备通信。
CH375的特点如下: (1)全速USB-HOST主机接口符合USB1.1,支持动态切换主机与设备方式,外围元器件只需要1个晶体和2个电容; (2)主机端点输入和输出缓冲区各有64字节,支持常用的12Mb/s全速USB设备; (3)支持USB设备的控制传输、批量传输、中断传输; (4)自动检测USB设备的连接和断开,提供设备连接和断开的通知; (5)内置控制传输的协议处理器,简化常用的控制传输; (6)并行接口包含8位数据总线,4线控制:读选通、写选通、片选输入和中断输出; (7)串行接口包括串行输入、串行输出和中断输出,支持通信波特率的动态调整。