用C语言来实现单片机对U盘的操作

合集下载

USB单片机CH559实现模拟U盘应用源码

USB单片机CH559实现模拟U盘应用源码

USB单片机CH559实现U盘控制器应用实例一、摘要根据Mass Storage Class(大容量/海量存储器,以下简称MSC)协议,使用CH558、CH559和CH563分别实现模拟全速和高速U盘的功能,外部存储介质和U盘容量支持自由调整,用以解决数据转存或者定制U盘等功能。

关键在于CH5XX USB设备控制器操作、Bulk-Only传输协议、SCSI命令支持和存储介质读写这几个部分。

二、总体概述模拟U盘关键功能部件包括以下几点:(1)、USB Mass Storage Framework(2)、以U盘为例,下图是PC和U盘的内部抽象逻辑框图CH558、CH559和CH563内置USB设备控制器和PHY,对于实现U盘控制器的应用,只需要配置USB设备模式和读写外部存储介质。

(3)、USB MSC CBI/BBB TransportUSB MSC Control/Bulk/Interrupt Transport 只能用于Full-speed的软盘(Floppy drive),这里不赘述,有兴趣可以自己百度。

Bulk-only传输类控制、批量都是通过批量端点,即用Bulk端点来传送命令块,数据,状态,因此,才类似于Control/Bulk/Interrupt被简称为CBI一样,而Bulk/Bulk/Bulk被简称为BBB。

(4)、USB MSC Protocol relation传输通讯:Host和Device之间的数据通讯根据存储介质(Floppy或Flash)分别使用UFI和SCSI协议,更深入的设备特性配置参考More Feature。

(5)、U盘配置描述符Class,Subclass和Protocol对应关系对应的,了解USB的都知道,每个设备的描述符中,都有对应下面这几个域:bInterfaceClass 、 bInterfaceSubClass 、 bInterfaceProtocol分别对应着USB的Class,Subclass,Protocol。

单片机U盘读写参考程序

单片机U盘读写参考程序

/*******************************************************/#include"reg52.h"#include"stdio.h"#include "string.h"#include "intrins.h"#include"CH375INC.H"/*******************************************************/#define uchar unsigned char#define uint unsigned int/*******************************************************/sbit CH375_INT=P3^3;sbit CH375_A0=P3^4;sbit CH375_RD=P3^5;sbit CH375_WR=P3^6;sbit CH375_CS=P3^7;/*******************************************************/uchar xdata my_buf[512];/*******************************************************/void uart_init(){TMOD=0X20;TH1=TL1=0XFD;TR1=1;REN=1;SM0=0;SM1=1;EA=1;ES=1;}/*******************************************************/void uart_send_pc(uchar *s) //串口监视//void uart_send_pc(uchar a[20]) { //{uchar len=strlen(s); // uchar i;uchar i; // for(i=0;i<20;i++)for(i=0;i<len;i++) // {{ // ES=0;ES=0; // SBUF=a[i];SBUF=s[i]; // while(!TI);while(!TI); // TI=0;TI=0; // ES=1;ES=1; // }} //}}/*******************************************************/void Delay2us() //@11.0592MHz{unsigned char i;_nop_();_nop_();i = 2;while (--i);}//********************1ms延时函数*************void delay1ms(unsigned int z){unsigned int x,y;for(x=z;x>0;x--)for(y=845;y>0;y--);}/*******************************************************/ void ch375_write_datcmd(uchar dat_cmd,uchar k) //写数据、命令{Delay2us();CH375_CS=0;CH375_A0=k; // 0:data 1:cmdP2=dat_cmd;CH375_WR=0;CH375_WR=1;CH375_CS=1;CH375_A0=1;Delay2us();}uchar ch375_read_dat() //读数据{uchar dat;CH375_CS=0;CH375_A0=0;P2=0XFF;CH375_RD=0;// P2=0XFF;dat=P2;CH375_RD=1;CH375_CS=1;CH375_A0=1;return dat;}/************************等待获取状态并取消中断操作*******************************/uchar ch375_wait_int(){CH375_INT=1;while(CH375_INT);ch375_write_datcmd(CMD_GET_STATUS,1); //获取状态并取消中断return ch375_read_dat();}/************************获取U盘容量操作*******************************/ unsigned long* get_volume(){unsigned long volume[2];uchar status,i;ch375_write_datcmd(CMD_DISK_SIZE,1);status=ch375_wait_int();if(status==USB_INT_SUCCESS){ch375_write_datcmd(CMD_RD_USB_DA TA,1);i=ch375_read_dat();for(i=0;i<4;i++){volume[0]=volume[0]<<8;volume[0]=volume[0]+ch375_read_dat();delay1ms(1);}for(i=0;i<4;i++){volume[1]=volume[1]<<8;volume[1]=volume[1]+ch375_read_dat();delay1ms(1);}}return volume;}/************************U盘初始化操作*******************************/uchar ch375_init(){uchar status;// uart_send_pc("请插入U盘:\n");status=ch375_wait_int(); //等待插入,并获取状态if(status!=USB_INT_CONNECT){uart_send_pc("U盘插入错误!\n");}else{// uart_send_pc("U盘已插入!\n");}ch375_write_datcmd(CMD_DISK_INIT,1); //磁盘初始化status=ch375_wait_int();if(status!=USB_INT_SUCCESS){uart_send_pc("磁盘初始化失败!\n");}else{// uart_send_pc("磁盘初始化成功!\n");}return 0;}/*******************************************************//**********************读扇区操作*********************************/uchar read_section(unsigned long addr){uchar i,k,status,length;ch375_write_datcmd(CMD_DISK_READ,1); //发送读扇区命令ch375_write_datcmd(addr,0);ch375_write_datcmd(addr>>8,0);ch375_write_datcmd(addr>>16,0);ch375_write_datcmd(addr>>24,0); //发送地址,先低后高ch375_write_datcmd(1,0); //送入读取扇区数for(i=0;i<8;i++) //缓冲区为64个字节,512/64=8,所以要读8次{status=ch375_wait_int(); //等待,并获取状态if(status==USB_INT_DISK_READ) //读数据块{ch375_write_datcmd(CMD_RD_USB_DA TA,1);length=ch375_read_dat();for(k=0;k<length;k++){my_buf[k+i*64]=ch375_read_dat(); //每次获取length个数ES=0; // SBUF=a[i];SBUF=my_buf[k+i*64]; // while(!TI);while(!TI); // TI=0;TI=0; // ES=1;ES=1;}}ch375_write_datcmd(CMD_DISK_RD_GO,1);}status=ch375_wait_int();if(status!=USB_INT_SUCCESS){return status;}return 0;}/*******************************************************/void main(){uart_init();delay1ms(40);ch375_write_datcmd(CMD_SET_USB_MODE,1); //设置USB模式ch375_write_datcmd(0x07,0); //自检测,复位usb总线delay1ms(1);ch375_write_datcmd(CMD_SET_USB_MODE,1); //设置USB模式ch375_write_datcmd(0x06,0); //自检测,并且产生sop包if(ch375_init()==0){// uart_send_pc("初始化完成!\n");}delay1ms(1);if(read_section(96+0x3a19)==0){// uart_send_pc("已读到扇区!\n");}while(1){}}void t1() interrupt 4{RI=0; }。

单片机c语言程序设计

单片机c语言程序设计

单片机c语言程序设计
单片机C语言程序设计主要包括以下几个方面的内容:
1. 硬件初始化:包括对单片机的引脚、端口、定时器、中断等进行初始化设置。

2. 输入输出操作:对外部设备的输入输出进行控制,如读取按键、控制LED灯、驱动液晶显示屏等。

3. 时钟和定时器操作:利用单片机内部的定时器来生成精确的时间延时,进行定时操作。

4. 中断处理:单片机的中断是实现异步事件响应的重要手段。

程序中需要设置中断的触发条件,并编写对应的中断服务函数。

5. 存储器操作:包括对寄存器、变量、数组等进行读写操作,以及对外部存储器的读写操作。

6. 节能和休眠模式:单片机在待机、休眠等低功耗模式下可以通过设置进行省电操作。

7. 通信协议和接口:可以通过UART、SPI、I2C等通信协议
与其他外部设备进行数据交换。

8. 程序控制流程:包括循环、条件分支、跳转等控制结构的使用,以实现程序的逻辑控制。

以上只是单片机C语言程序设计的一些常见内容,具体的程序设计还需要根据实际需求进行设计。

可以根据单片机的型号和数据手册,选择合适的编译器和开发工具,参考相关资料和示例代码进行学习和实践。

51读写U盘

51读写U盘

读写U盘1.变量定义和基本操作函数(1)变量的定义#include<reg51.h>#define uchar unsigned charuchar volatile xdata CH372_CMD_PORT _at_ 0x7DFF; // CH372命令端口的I/O地址uchar volatile xdata CH372_DA T_PORT _at_ 0x7CFE; //CH372数据端口的I/O地址uchar Usb_Length; //USB数据缓冲区中数据的长度uchar Usb_Buffer[ CH372_MAX_DATA_LEN ]; // USB数据缓冲区#define CH372_MAX_DA TA_LEN 0x40 //最大数据包的长度,内部缓冲区的长度//命令代码#define CMD_RESET_ALL 0x05 //执行硬件复位#define CMD_CHECK_EXIST 0x06 //测试工作状态#define CMD_SET_USB_ID 0x12 // 设置USB厂商VID和产品PID#define CMD_SET_USB_ADDR 0x13 //设置USB地址#define CMD_SET_USB_MODE 0x15 //设置USB工作模式#define CMD_SET_ENDP2 0x18 //设置USB端点0的接收器#define CMD_SET_ENDP3 0x19 //设置USB端点0的发送器#define CMD_SET_ENDP4 0x1A //设置USB端点1的接收器#define CMD_SET_ENDP5 0x1B //设置USB端点1的发送器#define CMD_SET_ENDP6 0x1C //设置USB端点2/主机端点的接收器#define CMD_SET_ENDP7 0x1D //设置USB端点2/主机端点的发送器//命令CMD_SET_ENDP2~CMD_SET_ENDP7输入为:工作方式,位7为1则位6为同步触发位,否则同步触发位不变,位3~位0为事务响应方:0000~1000-就绪ACK,1101-忽略,1110-正忙NAK,1111-错误STALL#define CMD_GET_TOGGLE 0x0A //获取OUT事务的同步状态,输入:数据1AH,输出:同步状态#define CMD_GET_STA TUS 0x22 // 获取中断状态并取消中断请求#define CMD_UNLOCK_USB 0x23 //释放当前USB缓冲区#define CMD_RD_USB_DATA 0x28 //从当前USB中断的端点缓冲区读取数据块,并释放缓冲区#define CMD_WR_USB_DA TA3 0x29 //向USB端点0的发送缓冲区写入数据块#define CMD_WR_USB_DA TA5 0x2A //向USB端点1的发送缓冲区写入数据块#define CMD_WR_USB_DA TA7 0x2B // 向USB端点2的发送缓冲区写入数据块//操作状态#define CMD_RET_SUCCESS 0x51 //命令操作成功#define CMD_RET_ABORT 0x5F //命令操作失败(2)基本操作函数①函数DelayMs:在CH372读写过程中需要用到毫秒延时,该函数可以满足要求,程序代码如下。

单片机USB模拟U盘源码

单片机USB模拟U盘源码

单片机USB模拟U盘源码虽然现在成品U盘的成本已经非常低,但是单片机系统中模拟U盘还是有些场景会应用到,比如:①代替传统光盘,为用户提供说明书、驱动软件等(直接存储在产品中)②U盘数据监控、截取和加密等(定制U盘)③采集数据暂存,方便传输给主机下文是根据masstorage和Bulk-Only传输协议,使用CH559实现模拟U盘的功能(容量大小由选择的外部存储芯片决定),用以实现数据转存或定制U盘功能。

关键点在于USB 设备模式初始化、扇区读写和外部存储芯片的操作。

一、总体概述模拟U盘关键功能部件包括以下几点:(1)、具有USB设备功能的MCU或接口芯片,此例中CH559有2个USB主机接口和1个USB设备接口。

(2)、根据实际需要或者接口选择合适的外部存储来作为U盘的存储空间,比如SPI的串行Flash、E2PROM,甚至是Nand Flash等。

以上准备完毕整体的操作流程如下所示:二、硬件电路CH559模拟U盘使用的SPI接口的串行Flash,硬件如下图:CH559是增强型51内核的单片机,内置晶振,所以芯片外围也足够简洁。

芯片资源如下图:三、软件编写软件主要包括以下方面:(1)、USB设备模式初始化(2)、存储芯片接口初始化(3)Bulk_Only传输CBW包:CSW包:四、可拓展功能(1)、其他存储介质:除了以上提到的SPI接口的串行Flash,也可以替换成E2PROM或者Nand falsh等。

(2)、数据来源可以随意指定,比如串口数据流,并口数据流,甚至其他温湿度传感器设备等。

(3)、CH559+SPI串行Flash模拟U盘测试参数CH563模拟U盘源码.rar559模拟U盘源码.rar五、源码分享CH559模拟U 盘的源代码(C 语言):CH563模拟U 盘的源代码(C 语言):。

关于单片机读写U盘F16和F32文件系统

关于单片机读写U盘F16和F32文件系统

摘要本文以51单片机为例介绍如何扩展USB接口进行对U盘的读写,并详细介绍FAT16、F AT32文件系统的细节以及如何编码实现单片机对文件系统的常用操作,顺带提到一点关于U盘兼容性问题的解决经验。

在这里单片机是host,U盘是slave。

在嵌入式系统中实现host很有意义,可以直接扩展出大容量的外存储器。

只要对单片机有一点点了解的人应该可以很顺利地阅读下去,如有简单的C语言编程基础更佳。

本文是科普性质,并不面面俱到,有一点应用笔记的味道。

章节间关联性较强,最好按顺序来阅读。

本文资料完全来自网络,再加入了笔者自己的理解和实践结果。

本文末尾列出了所有的参考资料。

如果觉得有知识产权问题请在21ic社区发信给fjh。

仓促成文,错误绝对存在,但希望不影响阅读。

关键词USB枚举过程;读写U盘;SL811;F AT16;F AT32Abstract[Click here and input abstract in English]Keywords[Click here and input keywords in English]符号说明(略)目录第一章硬件设计1.1 硬件概述先详细介绍基于Cypress公司的SL811芯片的扩展方案,基于国内南京沁恒电子的CH375芯片的方案最后介绍。

本文尽量介绍关于USB、U盘和文件系统等平台无关的内容,SL811硬件平台方面的内容不可避免要涉及到一点,但尽量控制到最少。

硬件很简单,详见protel文件(省略了无关的部分,比较粗糙,凑合看…)。

主要是扩展一片32K的外部RAM 62256作为数据缓冲,同时分配好SL811的地址。

通过51单片机的A15地址线分别连接到外部RAM 62256和SL811的片选CS端,来区分两者的地址,可见RAM占据低32K地址空间,而SL811依“写地址”和“读写数据地址”分别占据8000H和8001H两个字节的地址空间。

第二章U盘的逻辑结构2.1 U盘的逻辑结构U盘可以看成是以扇区(1扇区=512Bytes)为单位线性排列的实体,即0号扇区,1号扇区,2号扇区,……这样按顺序地排列下去。

c代码实现u盘检测的方法 -回复

c代码实现u盘检测的方法 -回复

c代码实现u盘检测的方法-回复实现U盘检测的方法主要涉及以下几个步骤:第一步:获取设备列表首先,我们需要获取系统中连接的所有设备列表。

在C语言中,我们可以使用一些系统调用函数来实现这个功能。

例如,Windows系统中可以使用Windows API函数`GetLogicalDrives`来获取所有逻辑驱动器列表,而Linux系统中可以使用`opendir`和`readdir`函数来遍历`/dev`目录下的所有设备。

以下代码展示了如何在Windows系统中获取所有逻辑驱动器列表的方法:c#include <stdio.h>#include <windows.h>void getDrivesList() {DWORD drives = GetLogicalDrives();char driveLetter = 'A';while (drives > 0) {if (drives & 1) {char drivePath[4];sprintf(drivePath, "c:\\", driveLetter);printf("Drive: s\n", drivePath);}drives >>= 1;driveLetter++;}}第二步:判断设备类型获取设备列表后,我们需要根据设备的类型进行判断,以确定是否为U盘。

在Windows系统中,我们可以使用`GetDriveType`函数来获取驱动器类型。

如果类型为`DRIVE_REMOVABLE`,则表示是可移动设备,也即U盘。

在Linux系统中,可以通过判断设备节点是否以`sd`开头来确定设备类型。

以下代码展示了如何判断设备是否为U盘的方法:c#include <stdio.h>#include <windows.h>void isUSB(char* drivePath) {UINT driveType = GetDriveType(drivePath);if (driveType == DRIVE_REMOVABLE) {printf("The device is a USB drive.\n");} else {printf("The device is not a USB drive.\n");}}第三步:检测U盘容量如果设备被确认为U盘,我们可以继续检测U盘的容量信息。

单片机读写U盘方案

单片机读写U盘方案

板卡上资源:
单片机:采用的是完全兼容51的单片机w78e54.
USB-HOST接口芯片:CYPRESS的SL811
高速SRAM存储器:用于数据缓冲。
RS232标准3线制串行接口,可以连接到PC机进行相关功能的测试。
套件相关问题:
套件硬件采用的结构为单片机+USB-HOST接口芯片,其中单片机采用的是最为通用的51系列单片机W78E54,也可以使用其他型号的51系列单片机,如ATMEL,PHILIPS等公司的产品,从而很容易就可以集成到您的系统中。USB接口芯片采用的是CYPRESS公司的USB-HOST接口芯片SL811,该芯片特点支持USB1.1协议;价格低(低于50元);性能突出,可靠性高,可以理想地用于多种外设。
本套件已经可以实现对U盘地读写操作,主要功能如下:
1,检测U盘地状态(如接入,拔出)
2,创建文件和目录
3,打开一个已经创建地文件和目录
4,从文件中读取指定长度和指定位置的数据
5,写数据到指定文件的指定地址
6,列举目录下的文件和目录
7,删除文件和目录
8,查询U盘容量
套件板卡跟用户CPU的接口为标准RS232三线接口,用户CPU可以按照我们提供的命令格式通过RS232接口ห้องสมุดไป่ตู้USB-HOST模块发送读写和控制命令,USB-HOST模块对命令进行解释并对U盘进行相应的读写操作,从而实现用户CPU对U盘的操作。
由于我们的套件完全开放硬件电路图和所有的软件源码,从而使您可以自由修改USB-HOST模块的接口方式和命令格式,如可以改成并行接口,从而很容易就可以集成到您自己的系统中。
单片机读写U盘方案__SL811开发套件
详细信息请访问我们的网站:

单片机usb程序设计

单片机usb程序设计

单片机usb程序设计单片机USB程序设计是一个涉及硬件与软件相结合的技术领域,它允许单片机通过USB接口与计算机或其他设备进行通信。

这种设计在现代电子项目中非常普遍,特别是在需要数据传输和设备控制的应用中。

以下是单片机USB程序设计的基本概念和步骤。

1. 理解USB接口USB(通用串行总线)是一种广泛使用的接口技术,用于连接计算机和各种外围设备。

它支持即插即用和热插拔功能,使得设备连接变得简单快捷。

USB接口有多种类型,包括USB A、B、C等,每种类型适用于不同的设备和应用场景。

2. 单片机与USB的连接单片机要实现USB通信,通常需要一个USB转接芯片或模块,这些芯片提供了USB协议的物理层、数据链路层和传输层的实现。

例如,常见的USB转接芯片有FTDI的FT232、Silicon Labs的CP2102等。

3. 硬件设计在硬件设计阶段,需要考虑单片机与USB转接芯片之间的连接方式,包括电源、数据线、控制线等。

此外,还需要设计电路板的布局,以确保信号的完整性和电磁兼容性。

4. 单片机编程单片机编程是实现USB通信的关键步骤。

这通常涉及以下几个方面:- 初始化程序:在程序开始时,需要对单片机的I/O端口、时钟、中断等进行初始化设置。

- USB协议栈:编写或集成USB协议栈,这是一组实现USB通信协议的软件代码。

- 设备描述符:定义单片机作为USB设备的描述符,包括设备类型、版本号、制造商信息等。

- 端点配置:配置USB端点,端点是数据传输的基本单元,可以是控制端点、数据端点或反馈端点。

5. 设备驱动开发为了使计算机能够识别并正确使用单片机,需要开发相应的设备驱动程序。

驱动程序负责处理操作系统与单片机之间的通信,包括数据的接收和发送。

6. 应用层软件开发应用层软件是用户与单片机交互的界面。

它可以是一个简单的控制面板,也可以是一个复杂的应用程序,用于显示数据、发送指令等。

7. 调试与测试在设计和编程完成后,需要进行调试和测试,确保单片机的USB通信功能正常工作。

单片机读写U盘闪盘超精简C源程序

单片机读写U盘闪盘超精简C源程序

单片机读写U盘闪盘超精简C源程序,不用子程序库(2007-04-05 21:40:45) 标签:单片机u 盘源程序分类:源程序代码/* 这个程序用180行C代码就能够读取FAT16文件系统U盘的根目录,可以看到根目录下的文件名,并可显示首文件内容,不过,该程序很不严谨,也没有任何错误处理,对U盘兼容性较差,只是用于简单试验,作为参考.这个程序可以支持INDOWS按FAT16格式化的U盘,因为程序精简,所以只兼容超过50%以上的U盘品牌,如果换成CH375A芯片则兼容性可提高到85%,当然,如果使用公司的子程序库或者正式版本的C源程序兼容性更好。

下面贴出的程序注释较少,如果需要加注释的C源程序,请到楼下的跟贴中下载,欢迎各位将本源程序转贴到其它网站,比较一下,如何做出最简洁的单片机读写U盘文件的程序测试以下U盘通过:郎科/超稳经典64M/超稳迷你128M/U160-64M/超稳普及128M,爱国者/迷你王16M/邮箱型,黑匣子/64M,微闪/64M,飙王/32M/64M/128M,晶彩/C200-64M,新科/256M,昂达/128M...,欢迎提供测试结果未通过U盘:爱国者/智慧棒128M,清华普天/USB2.0-128M,当然,使用子程序库或CH375A都可以测试通过*/#include <stdio.h>#include "CH375INC.H"#include <reg51.h> /* 以下定义适用于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_DA T_PORT ); /* 因为MCS51单片机较慢所以实际上无需延时*/ }UINT8 mWaitInterrupt( void ) { /* 等待CH375中断并获取状态,返回操作状态*/while( CH375_INT_WIRE ); /* 查询等待CH375操作完成中断(INT#低电平) */CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断,获取中断状态*/return( CH375_RD_DA T_PORT( ) );}/* ********** BulkOnly传输协议层,被CH375内置了,无需编写单片机程序*//* ********** RBC/SCSI命令层,虽然被CH375内置了,但是要写程序发出命令及收发数据*/UINT8 mInitDisk( void ) { /* 初始化磁盘*/UINT8 Status;CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态*/Status = CH375_RD_DA T_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_DA TA ); /* 从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\n", (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( "In**sert USB disk\n" );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\n", 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\n", DISK_BUFFER ); /* 显示首行*/Cluster = mLinkCluster( Cluster ); /* 获取链接簇,返回0说明错误*/}}while ( mWaitInterrupt( ) != USB_INT_DISCONNECT ); /* 等待U盘拔出*/mDelaymS( 250 );}}。

单片机控制U盘程序-移植

单片机控制U盘程序-移植
/* 输入: 数据68H, 当前文件长度(总长度32位,低字节在前) */
#define CMD11_SET_USB_MODE 0x15 /* 设置USB工作模式 */
/* 输入: 模式代码 */
/* 00H=未启用的设备方式, 01H=已启用的设备方式并且使用外部固件模式(串口不支持), 02H=已启用的设备方式并且使用内置固件模式 */
有些命令能够实现0到多个字节的数据块读写, 数据块本身的字节数未包含在上述x或y之内 */
/* 本文件默认会同时提供与CH375芯片命令码兼容的命令码格式(即去掉x和y之后), 如果不需要, 那么可以定义_NO_CH375_COMPATIBLE_禁止 */
/* ********************************************************************************************************************* */
#define CMD10_SET_FILE_NAME 0x2F /* 主机文件模式: 设置将要操作的文件的文件名 */
/* 输入: 以0结束的字符串(含结束符0在内长度不超过14个字符) */
/* ********************************************************************************************************************* */
/* 输出中断 */
#define CMD1H_FILE_CLOSE 0x36 /* 主机文件模式: 关闭当前已经打开的文件或者目录(文件夹) */
/* 输入: 是否允许更新文件长度 */

单片机的U盘读写模块的设计

单片机的U盘读写模块的设计

唐山学院毕业设计设计题目:基于单片机的U盘读写模块的设计系别:班级:姓名:指导教师:2013年6月 6 日基于单片机的U盘读写模块的设计摘要介绍了一种USB总线的通用接口芯片CH375,并在此基础上提出了一种外部单片机读写U盘的基本方法及其硬件连接方法。

单片机只要在原硬件系统中增加1个CH375芯片就可以直接调用CH375提供的子程序库来直接读取U盘中的数据,从而实现了普通单片杌与U盘的通讯、方法简单、便于操作、综合成本比较低,具有较大的推广应用价值。

关键词:U盘;CH375;接口芯片;单片机RESEARCH ON IMAGE REGISTRATION TECHNOLOGY BASED ON MATLABAbstractA general purpose interface chip CH37 5 for USB is introduced in this paper.Based On which a new method of Using external single chip microcomputer to connect with the flash disk is given.Only add one CH375 chip to the single chip microcomputer s hardware system,the operator can use the program given by the CH375 to read the data from the flash disk and realize the communication between the single chip microcomputer and the flash disk.This method is very simple and can be operated easily.Key words: Powell; PSOUSB;CH375;interface chip;single chip microcomputer目录1 引言 (1)1.1 论文背景和意义 (1)1.2 图像配准技术研究现状 (2)2 图像配准综述 (4)2.1 图像配准理论 (4)2.2 图像配准一般步骤 (4)2.3 特征空间 (5)2.3.1 基于灰度统计信息的配准 (5)2.3.2 基于特征的配准方法 (7)2.4 搜索空间 ..................................................................... 错误!未定义书签。

C51单片机C语言程序设计

C51单片机C语言程序设计

C51单片机C语言程序设计单片机C语言程序设计是指使用C语言编写程序来控制和操作单片机的工作。

单片机是一种集成电路,它包含了中央处理器、存储器、输入输出接口等功能模块,广泛应用于嵌入式系统中。

在单片机C语言程序设计中,首先需要了解C语言的基本语法和语法规则。

C语言是一种面向过程的编程语言,具有简洁、高效和可移植等特点。

接下来,要熟悉单片机的硬件结构和寄存器的使用方法,了解单片机的输入输出方式、中断、定时器等功能。

在进行单片机C语言程序设计时,需要按照以下步骤进行:1.设置寄存器和引脚的初始化:根据单片机的型号和需要的功能,设置相关的寄存器和引脚的初始化。

这些初始化可以包括引脚的输入输出模式设置、中断向量表的初始化、定时器的设定等。

2.主程序的编写:主程序是单片机的执行入口,通过主程序可以完成各种功能的实现。

在主程序中,可以定义变量、函数和结构体等。

3.中断程序的编写:中断程序是由硬件触发的,可以在需要时被调用执行。

中断程序可以包括外部中断、定时器中断等。

在编写中断程序时,需要设置相应的中断向量,并完成相应的中断服务程序。

4.函数的编写:函数是实现其中一特定功能的代码段,通过函数可以提高程序的模块化和可重用性。

需要根据实际需求编写相应的函数,并在主程序中调用。

5. 调试和测试:在编写完程序后,需要进行调试和测试。

通过调试和测试可以发现程序中的bug和错误,并进行修复。

可以通过缓慢单步调试、观察变量值和输出结果等方式进行调试和测试。

6.优化和改进:在程序完成后,可以对程序进行优化和改进。

通过优化可以提高程序的性能和效率,减少资源的占用。

可以使用编译优化选项、减少不必要的计算和内存使用等方式进行优化。

以上是单片机C语言程序设计的基本步骤和内容。

在实际操作中,还需要根据具体的需求和硬件平台进行相应的调整和编程。

通过合理的设计和编程,可以实现单片机的各种功能和应用,广泛应用于电子设备、汽车、家电等领域。

无论是初学者还是有经验的程序员,都可以通过单片机C语言程序设计来进一步提高和拓展自己的技能。

(经典)基于单片机的U盘读写

(经典)基于单片机的U盘读写

基于单片机的U盘数据传输装置机电工程学院测控技术与仪器专业李朋飞摘要:随着单片机技术的发展,各种嵌入式系统的逐渐应用于工作现场的数据采集和控制之中。

USB总线技术的发展,使得数据传输和采集技术,变得简单,易携和方便使用。

基于USB总线技术的USB储存设备简称U盘,它具有支持热拔热插,储存量大,耐用,和轻巧方便的特点。

基于单片机技术的U盘数据采集是把单片机系统作为主机系统,再利用支持USB总线协议的U盘读写芯片或者模块来完成工业现场的数据采集或者传输。

这样,便可以把U盘的大容量存储,方便易用的功能从PC机系统扩展到单片机系统中,可以方便在室外进行大量数据的采集。

例如,可以将单片机系统中AD转换后采集到的数据,储存到U盘之中,以便于利用计算机对数据经行整理或分析。

本文主要介绍一种技术成熟U盘读写芯片CH375和以此芯片为核心的U盘读写模块,简单介绍了CH375芯片的构造和特点,以及U盘模块的应用特点。

再次,介绍了串口版U盘模块的应用,并设计了串口模块和单片机之间的通信的应用方式,并附有模块和单片机之间采用RS232电平进行通信的连接电路图。

同时,还简单的介绍了,U盘读写之中需要注意的几个协议等。

最后附录中的程序提供了一个能够实现单片机以字节的方式对U盘的读和写的程序。

关键词:单片机 U盘 USB2.0 U盘模块串口通信 RS232接口 CH375 电平一,引言半导体技术的发展带来计算机向微型化发展的革命,同时随着计算机技术的快速发展,USB (Universal Serial Bus)存储设备的使用已经非常普遍,USB 用于将适用USB 的外围设备(device)连接到主机(host),实现二者之间数据传输的外部总线结构;是一种快速、灵活的总线接口。

它最大的特点是易于使用,携带方便,主要是用在中速,低速的外设。

随着USB 规范的完善和成熟,USB 外设的种类不断丰富,应用领域也不断扩大。

在传统的应用中,主要是PC 扮演着主机的角色。

c代码实现u盘检测的方法 -回复

c代码实现u盘检测的方法 -回复

c代码实现u盘检测的方法-回复U盘是一种便携式存储设备,被广泛应用于文件传输和数据存储。

然而,由于其便携性,U盘也容易成为计算机系统遭受恶意软件和病毒入侵的渠道之一。

为了确保计算机的数据安全,我们需要对插入计算机的U盘进行实时检测。

本文将介绍如何使用C代码实现U盘检测的方法。

首先,我们需要明确的是U盘是通过USB接口与计算机连接的。

因此,我们可以通过检测计算机的USB接口来判断是否存在插入的U盘。

下面是一种使用C代码检测U盘的方法:1. 引入必要的库文件:c#include <windows.h>#include <stdio.h>2. 定义一个检测U盘的函数:cint detectUSB(){int driveType;char driveLetter;char strDrive[] = "A:\\";WIN32_FIND_DATA FindData;从A盘开始检测到Z盘for (driveLetter = 'A'; driveLetter <= 'Z'; driveLetter++) {strDrive[0] = driveLetter;driveType = GetDriveType(strDrive);检测到USB设备if (driveType == DRIVE_REMOVABLE){HANDLE hFind = FindFirstFile(strDrive, &FindData);打印U盘的驱动器号printf("Detected USB Drive: c\n", driveLetter);FindClose(hFind);}}return 0;}3. 在主函数中调用检测函数:cint main(){detectUSB();return 0;}以上代码中的主要思路是通过循环检测计算机的每个驱动器符号,然后使用`GetDriveType`函数判断驱动器的类型。

使用STC12C5A60S2单片机实现U盘音频播放器

使用STC12C5A60S2单片机实现U盘音频播放器

使用STC12C5A60S2单片机实现U盘音频播放器U盘即闪存盘,是一种用闪存进行数据存储的介质,通常使用USB插头。

U盘体积极小、重量轻、可热插拔也可以重复写入。

U盘所储存的数据,现今仍大多通过计算机提取并进行处理,这也局限了U盘的发展范围。

笔者认为,针对某一特定功能,剥离相应数据对计算机的依赖性,一方面可充分利用U 盘数据,另一方面也发挥出USB协议的通用性,使U盘实现所用即所得的便携特性。

基于此,设计了U盘MP3播放器电路,主要完成U盘存储的音频文件的数据提取及功能运行任务。

该播放器等同于个人计算机的音频处理模块,不仅可识别、提取U盘所存储的MP3、WMA或MIDI格式的文件,并可自行完成音频解码等数据处理工作,最后送入扬声器或耳机进行播放。

1播放器组成原理框图播放器组成原理如图1所示,共由3个主要模块组成:单片机处理模块,由STC12C4A60S52单片机及其外围电路组成;U盘读写模块,由CH375及其外围电路组成;为音频解码模块,由VS1003芯片及其外围电路组成。

播放器的工作过程是:MCU通过CH375读取来自USB存储设备的数据,并依据功能键的控制指令,将USB存储设备的相关数据送入音频解码模块,在VS1003解码后,送入扬声器或耳机。

设置6个人机交互功能按键,分别实现播放、暂停、上一曲、下一曲、增大音量、减小音量等基本操作功能。

2硬件电路设计如图1所示,主要完成U盘读写、单片机处理及音频解码3个模块的电路设计。

图1原理方框图2.1U盘读写模块U盘读写模块由CH375及其外围电路组成,其构成如图2所示。

图2CH375外围硬件电路CH375是USB总线通用接口芯片,支持USB主机及从设备方式。

在本地端,CH375具有8位数据总线和读、写、片选控制线以及中断输出,可以方便地挂接到单片机/DSP/MCU/MPU等控制器的系统总线上。

在USB主机方式下,CH375还提供了串行通讯方式,通过串行输入、输出和中断输出与单片机/DSP/MCU/MPU等相连接。

10分钟学C语言,100多行代码打造U盘加密解密,间谍程序!

10分钟学C语言,100多行代码打造U盘加密解密,间谍程序!

10分钟学C语言,100多行代码打造U盘加密解密,间谍程序!
C++ U盘加密与解密程序,对U盘进行加密及解密。

VC++编写。

防止资料泄密。

插上U盘,打开U盘加密器。

选择“加密其他文件夹”,在弹出的窗口选择计算机中的U盘。

然后点击“确定”
源码结构截图:
主要源码截图:
代码测试截图:
为了解决用户可能碰到关于'怎么给U盘加密?加密后,除了自己的电脑,放到其他电脑上,打开还是要密码的那种,怎么做?满意可加分!
最后,如果你想学C++可以百度网上那篇“溪加加”文章,获取素材资料以及开发工具和听课权限!。

在嵌入式系统中实现对U盘的操作

在嵌入式系统中实现对U盘的操作

在嵌入式系统中实现对U盘的操作
向前
【期刊名称】《单片机与嵌入式系统应用》
【年(卷),期】2005(000)002
【摘要】主要介绍在嵌入式系统中利用SL811HS对U盘操作的实现方法;简要介绍USB设备中的海量存储类、SL811HS的芯片特点及FAT文件系统.
【总页数】4页(P36-39)
【作者】向前
【作者单位】中国电子科技集团公司电子41所
【正文语种】中文
【中图分类】TP334.7
【相关文献】
1.用C语言来实现单片机对U盘的操作 [J], 程序;张毅
2.嵌入式Linux下用AT91RM9200实现对U盘的操作 [J], 毛玲;阎学文
3.嵌入式系统上无操作系统Telnet服务器的实现 [J], 胡奕;唐莉萍
4.基于PXA250和Linux嵌入式系统在机器人遥操作中的设计与实现 [J], 李殿敏;李科杰
5.基于嵌入式系统U盘开发的设计与实现 [J], 刘萍萍;于帆
因版权原因,仅展示原文概要,查看原文内容请购买。

ch375读写u盘C51示例源程序

ch375读写u盘C51示例源程序

ch375读写u盘C51示例源程序/* 以下定义的详细说明请看CH375HF9.H文件 */#define LIB_CFG_FILE_IO 1 /* 文件读写的数据的复制方式,0为\外部子程序\为\内部复制\#define LIB_CFG_INT_EN 1 /* CH375的INT#引脚连接方式,接s3c44b0x外部中断2引脚\/* 单片机的RAM有限,其中CH375子程序用512字节,剩余RAM部分可以用于文件读写缓冲 */ #define FILE_DATA_BUF_LEN 0x2000 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */#include \#define CH375Cmd *(volatile U8 *)(0x4000001) /*总线方式*/ #defineCH375Dat *(volatile U8 *)(0x4000000) extern U32 MCLK;/* CH375 主机文件系统接口*/ /* 支持: FAT12/FAT16/FAT32 *//* ARM单片机C语言的U盘文件读写示例程序 *//* 该程序将U盘中的/C51/CH375HFT.C文件中的小写字母转成大写字母后, 写到新建的文件NEWFILE.TXT中,如果找不到原文件CH375HFT.C, 那么该程序将显示C51子目录下所有以CH375开头的文件名, 并新建NEWFILE.TXT文件并写入提示信息,如果找不到C51子目录, 那么该程序将显示根目录下的所有文件名, 并新建NEWFILE.TXT文件并写入提示信息 *//* CH375的INT#引脚采用查询方式处理, 数据复制方式为\内部复制\本程序适用于s3c44b0x单片机, 串口0输出监控信息,57600bps */ /* ENDIAN = \void mDelay1_2uS( ) /* 至少延时1.2uS,根据单片机主频调整 */ { UINT32 i;for ( i = 30; i != 0; i -- ); }void __irq CH375Interrupt( void ) /* CH375中断服务程序,由CH375的INT#的低电平或者下降沿触发单片机中断 */ {rEXTINTPND=0xf; //clear EXTINTPND reg.rI_ISPC=BIT_EINT2; //clear pending_bitxWriteCH375Cmd( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */CH375IntStatus = xReadCH375Data( ); /* 获取中断状态 */if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus =DISK_DISCONNECT; /* 检测到USB设备断开事件 */else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus =DISK_CONNECT; /* 检测到USB设备连接事件 */ }extern void CH375Interrupt( void ); void CH375_PORT_INIT( ) /*初始化 */ {rINTCON=0x5;rINTMOD=0x0; //All=IRQ mode rPDATG=0xff; rPCONG=0xffff;rPUPG=0x0; //should be enabled rEXTINT=0x0;pISR_EINT2 = (unsigned)CH375Interrupt;rINTMSK=~(BIT_GLOBAL|BIT_EINT2); //start INT }void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */ {mDelay1_2uS( ); mDelay1_2uS( ); /* 至少延时1uS */ CH375Cmd = mCmd;mDelay1_2uS( ); mDelay1_2uS( ); /* 至少延时2uS */ }void xWriteCH375Data( UINT8 mData ) /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */ {CH375Dat = mDatamDelay1_2uS( ); /* 至少延时1.2uS */ }UINT8 xReadCH375Data( void ) /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */ {UINT8 mData;mDelay1_2uS( ); /* 至少延时1.2uS */mData = (UINT8)CH375Dat;return( mData ); }/* 延时指定毫秒时间,根据单片机主频调整,不精确 */ void mDelaymS( UINT32 ms ) { UINT32 i;while ( ms -- ) for ( i = 25000; i != 0; i -- ); }/* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) {if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ printf( \/* 显示错误*/ while ( 1 ) {mDelaymS( 100 ); } }/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) { }U16 SERIAL_BAUD = 57600;char table_begin[] = \void ShowSysClock(int argc, char *argv[]) {printf(\ystem is running @%dHz\\n\ }int Main(void) {unsigned char t; UINT8 i, c, SecCount;UINT16 NewSize, count; /* 因为RAM容量有限,所以NewSize限制为16位,实际上如果文件较大,应该分几次读写并且将NewSize改为UINT32以便累计 */ UINT8*pCodeStr; ChangePllValue(24, 6, 1); Port_Init();console_init(57600);next_line(); puts(table_begin);puts(\ShowSysClock(0, NULL);printf(\next_line(); puts(table_begin);puts(\mDelaymS( 50 ); /* 延时100毫秒 */ printf( \测试CH375是否正常\\n\mDelaymS(60 ); /* 延时50ms */ printf(\完成!!\i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError( i );/* 其它电路初始化 */ CH375_PORT_INIT( ); while ( 1 ) {printf( \请插入U盘!\\n\while ( CH375DiskStatus != DISK_CONNECT ) /* 查询CH375中断并更新中断状态,等待U盘插入 */mDelaymS( 10 );/* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */ for ( i = 0; i < 10; i ++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */printf( \if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ }/* 查询磁盘物理容量 */ printf( \i = CH375DiskSize( );mStopIfError( i );printf( \/* 读取原文件 */ printf( \strcpy( (char *)mCmdParam.Open.mPathName, \/* 文件名,该文件在C51子目录下*/ i = CH375FileOpen( ); /* 打开文件 */if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { /* 没有找到文件 */ /* 列出文件 */if ( i == ERR_MISS_DIR ) pCodeStr = (UINT8 *)\/* C51子目录不存在则列出根目录下的文件 */ else pCodeStr = (UINT8 *)\/* CH375HFT.C文件不存在则列出\\C51子目录下的以CH375开头的文件 */printf( \for ( c = 0; c < 255; c ++ ) { /* 最多搜索前255个文件 */strcpy( (char *)mCmdParam.Open.mPathName, (char *)pCodeStr ); /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */i = strlen( (char const *)mCmdParam.Open.mPathName ); /* 计算文件名长度,以处理文件名结束符 */ mCmdParam.Open.mPathName[ i ] = c; /* 根据字符串长度将结束符替换为搜索的序号,从0到255 */ i = CH375FileOpen( ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */ if ( i == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */if ( i == ERR_FOUND_NAME ) { /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */printf( \match file d#: %s\\n\/* 显示序号和搜索到的匹配文件名或者子目录名*/continue; /* 继续搜索下一个匹配的文件名,下次搜索时序号会加1 */ }else { /* 出错 */ mStopIfError( i ); break; } }pCodeStr = (UINT8 *)\找不到/C51/CH375HFT.C文件\\xd\\n\for ( i = 0; i != 255; i ++ ) {if ( ( FILE_DATA_BUF = *pCodeStr ) == 0 ) break; pCodeStr++; }NewSize = i; /* 新文件的长度 */SecCount = 1; /* (NewSize+511)/512, 计算文件的扇区数,因为读写是以扇区为单位的 */ }else { /* 找到文件或者出错 */ mStopIfError( i ); /* printf( \i = CH375FileQuery( ); 查询当前文件的信息感谢您的阅读,祝您生活愉快。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ElectronicComponent&DeviceApplicationsVol.10No.3Mar.2008第10卷第3期2008年3月2008.3www.ecda.cn0引言随着U盘技术的迅速发展,单片机海量存储选用U盘已经成为大家的首选。

而如何让单片机像在WINDOWS下识别FAT文件系统那样识别U盘并进行随意读写呢?本文针对这一情况,给出了如何在嵌入式系统中利用CH375实现单片机对U盘进行读写操作的具体方法。

1CH375的主要特点其实,单片机读写U盘主要是找到USB总线接口芯片,而CH375就是一个非常好用的芯片USB接口,它的主要特点如下:◇全速USB-HOST主机接口,兼容USBV2.0,外围元器件只需要晶体和电容;◇可全速动态切换主机与设备;◇主机端点有输入和输出缓冲区各64字节,可支持常用的12Mbps全速USB设备;◇支持USB的控制、批量和中断传输;◇可自动检测USB设备的连接和断开,并提供设备连接和断开的事件通知;◇内置控制传输的协议处理器,可简化常用的控制传输;◇内置固件处理海量存储设备的专用通讯协议,可支持Bulk-Only传输协议和SCSI、UFI、RBC或等效命令集的USB存储设备(包括USB硬盘/USB闪存盘/U盘);◇可通过U盘文件级子程序库实现单片机读写USB存储设备中的文件。

◇并行接口包含8位数据总线,其中4线控制包括读选通、写选通、片选输入、中断输出等;◇串行接口包含串行输入、串行输出、中断输出,支持通讯波特率动态调整;◇可支持5V电源电压和3.3V电源电压,此外,CH375A芯片还支持低功耗模式;◇采用SOP-28封装。

2FAT文件系统由于绝大部分单片机海量存储系统最终会与Windows操作系统计算机交换数据,所以,为了方便数据交换,U盘中的数据应该符合Windows文件系统格式。

常用的FAT文件系统有FAT12、FAT16、FAT32等,U盘上的数据按照其不同的特点和作用大致可分为以下几部分:(1)主引导记录(MBR)实际上,在总共512字节的主引导扇区中,MBR只占用了其中的446字节,另外的64字节交给了DPT(DiskPartitionTable盘分区表),最后两字节“55AA”是分区的结束标志。

(2)系统引导记录(DBR)包括一个引导程序和一个被称为BPB(BiosParameterBlock)的本分区参数记录表,在BPB参数记录表里包含着本分区的起始扇区、结束扇区、文件存储格式、根目录大小、FAT个数、分配单元的大小等重要参数。

(3)文件分配表(FAT)文件分配表是DOS文件组织结构的主要组成收稿日期:2007-09-05用C语言来实现单片机对U盘的操作程序,张毅(南瑞集团公司,江苏南京210003)摘要:介绍了在嵌入式系统中利用CH375对U盘进行读写的实现方法;同时介绍了USB总线接口芯片CH375的主要特点及FAT文件系统的组成。

给出了USB的接口电路和软件流程。

关键词:USB-HOST;FAT文件系统;CH37564Vol.10No.3Mar.2008第10卷第3期2008年3月www.ecda.cn2008.3部分。

DOS进行分配的最基本单位是簇,而文件分配表可反映硬盘上所有簇的使用情况,也就是说,通过查文件分配表可以得知任一簇的使用情况。

DOS在给一个文件分配空间时,总是先扫描FAT,找到第一个可用簇,便将该空间分配给文件,同时将该簇的簇号填到目录的相应段,以形成“簇号链”,FAT就是记录文件簇号的一张表。

(4)文件目录表(FDT)文件目录区是DOS文件组织结构的又一重要组成部分,文件目录分为两类:根目录和子目录。

其中根目录有一个,子目录可以有多个,DOS为目录项分配了32字节,它包含文件名、扩展名、文件属性、时间日期、文件的开始簇号和文件长度等重要信息。

(5)数据区(DATA)数据区是真正存储数据的地方。

3USB读写的硬件设计本设计采用CH375的并行接口来完成对U盘的操作,它使用8位双向数据总线D7 ̄D0、读选通输入脚RD、写选通输入脚WR、片选输入脚CS、中断输出脚INT以及地址输入脚A0。

CH375芯片的RD和WR可以分别连接到单片机的读选通输出引脚和写选通输出引脚。

CS由地址译码电路驱动,用于在单片机具有多个外围器件时进行设备选择。

INT输出的中断请求是低电平有效,可以连接到单片机的中断输入引脚或者普通I/O引脚,单片机可以使用中断方式或者查询方式来获知中断请求。

当WR为高电平并且CS和RD及A0都为低电平时,CH375中的数据将通过D7 ̄D0输出;当RD为高电平并且CS和WR及A0都为低电平时,D7 ̄D0上的数据将被写入CH375芯片中;即当RD为高电平并且CS和WR都为低电平但A0为高电平时,D7 ̄D0上的数据被作为命令码写入CH375芯片中。

单片机与CH375的并行接口电路如图1所示。

CH375芯片复位期间,TXD引脚用于选择通讯接口。

若CH375在复位期间检测到TXD引脚为低电平,则启用并行接口,否则启用串行接口。

由于本设计中采用的是并行方式,所以,将CH375的TXD引脚直接接地。

USB总线包括一对5V电源线和一对数据信号线。

USB插座J1可以直接接USB设备,也可以在提供给USB设备的+5V电源线上串接具有限流作用的快速电子开关,但USB电源必须为5V。

电容C4用于CH375内部电源节点的退耦,C4是容量为0.01μF的独石或高频瓷片电容。

如果对EMI没有要求,那么可以省掉C4;电容C5和C6用于外部电源退耦,C5应选择容量为0.1μF的独石或高频瓷片电容;晶体Y1、电容C1和C2用于CH375的时钟振荡电路;USB-HOST主机方式要求时钟频率比较准确,Y1的频率是12MHz±0.4‰,C1和C2是15pF的独石或高频瓷片电容。

如果电源上电过程较慢且电源断电后放电时间较长,那么CH375将不能可靠复位,可以在RSTI引脚与VCC之间跨接一个容量(为0.47μF的电容C3),同时可以减少干扰。

4软件设计通过USB主控芯片对U盘进行操作的主要工作量在软件方面,它需要对众多规范、协议进行透彻理解。

一般情况下,单片机或嵌入式系统处理USB存储设备的文件系统需要实现如图2所示的4个层次,但如果USB主控芯片选用CH375则要图1单片机与CH375的并行接口电路设计参考65ElectronicComponent&DeviceApplicationsVol.10No.3Mar.2008第10卷第3期2008年3月2008.3www.ecda.cn简单得多,因为它内置了处理Mass-Storage海量存储设备的专用通讯协议固件,外部单片机可以直接以扇区为基本单位来读写常用的U盘,所以,实际的单片机程序只需要处理图2最上层的FAT文件系统层,而且即使这一层也可以由CH375的U盘文件级子程序库来实现。

不过,应用厂家提供的U盘文件级子程序库固然能为程序编写提供很大方便,但仍需要调整单片机以适应它们的设置,这个过程也是很麻烦的。

由于单片机的程序空间有限,利用U盘文件级子程序库会使程序空间变得更紧张,而由自己编写文件系统处理程序,不但能有效节省单片机资源,而且能灵活的想怎么升级就怎么升级。

单片机读写U盘的关键问题是找到目标扇区,一般可先找到FAT表,读出有用的数据,再根据这些数据计算出文件所在的簇,然后根据簇和扇区的数学关系找到文件的扇区,这样就可以随心所欲地读写一个扇区(512B)了。

4.1USB初始化软件设计时,应先初始化CH375,以设置其工作模式,让其工作在USB主机方式:WR_CMD_PORT(SET_USB_MODE);//设置模式WR_DAT_PORT(6);//主机模式初始化U盘实际就是识别U盘的类型,该操作不影响U盘中的数据,但在所有读写操作之前必须进行此步骤:WR_CMD_PORT(DISK_INIT);/*初始化USB存储器*/Status=WaitInterrupt();/*等待中断并获取状态*/之后,还应当初始化U盘里的文件格式:ReadBPB();//读U盘系统引导记录(DBR)里的BPB表通过读BPB表可以获取每扇区字节数、每簇含扇区数、FAT表起始地址、FAT表个数、根目录个数、根目录所占扇区数、FDT表起始地址、DATA区起始地址、FAT类型等等重要信息。

4.2文件操作要将单片机系统的数据导入到U盘,而且能直接被计算机识别,所要做的工作有下面几步:(1)创建文件目录CreatFile()即创建文件目录里的文件名、扩展名、文件属性、时间日期、文件的开始簇号和文件长度。

(2)写文件WriteFile()写入新文件时,需在FAT表中查找未使用的簇,并将该簇号写入文件所对应的目录数据结构中的文件开始簇号位置;当文件长度大于一簇时,还需在FAT表中的对应起始簇号位置填入下一可用簇的簇号,直到文件的最后一簇。

(3)更新文件目录ModifyCatolog();文件写完后,目录数据结构里有些项可能需要更改,如文件长度等。

而将外面的数据通过USB导入到单片机系统的步骤如下:(1)搜索文件SearchFile()通过搜索文件目录可以找到所要读的文件的开始簇号、文件长度等重要信息。

(2)读文件ReadFile()读文件时,可将文件开始簇号转为扇区号,并读出扇区号对应的数据,若文件长度不止一簇,应根据前一簇号找到其链节簇,然后再将链节簇转换为扇区号并读出数据,直到文件结束。

(3)删除文件DeleteFile()如果你想删除文件,只需要将该文件对应的目录数据结构置相应标志,然后修改FAT表及备份FAT表,将此文件使用的簇号位置清0来表示此簇未被使用。

5结束语在单片机系统中利用USB主控芯片CH375来实现对U盘的操作技术,目前已应用在笔者自己开发的水情遥测系统中,从而实现了水情遥测系统与U盘之间各类信息的传输。

图2USB存储的层次结构66。

相关文档
最新文档