当前位置:文档之家› (经典)基于单片机的U盘读写

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

(经典)基于单片机的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 扮演着主机的角色。根据USB 的规范,可以看到在USB 的拓朴结构中居于核心地位的是主机,每一次的数据传输都必须由主机发起和控制。但是随着单片机产品应用领域的日益增长,USB 外设的应用范围也随之扩大,为此在单片机系统中实现对USB外设控制也变得日益迫切。因此在一些需要转存数据的设备,仪器上使用USB移动存储设备接口的芯片便相继产生了,CH375 就是其中之一,它是一个USB 总线的通用接口芯片,支持HOST 主机方式和SLAVE 设备方式。

如今的USB 就象当日的RS232,最终发展必是业界的主流外设接口技术。USB 有着其它接口不可替代的优势。随着USB 技术的发展,计算机的移动存储介质普遍采用U 盘或移动硬盘。如今,USB 技术已经越来越普及和成熟,低成本、高稳定性、较高的数据传输速率和即插即用的方便性,使其备受硬件厂商的青睐。随着数据采集和单片机用户对移动存储的需求越来越大,具有USB 接口的存储设备以其优异的性价比和灵活性常用来进行数据的存储和交换,所以在单片机系统中实

现对优盘或移动硬盘的直接读写是非常有价值的。

二,研究的意义

USB是近年发展起来的一种快速、灵活的总线接口。它最大的特点是易于使用、可热插拔、接口连接灵活,并且能够提供外设电源,在嵌人式系统及智能仪表中得到广泛的应用。而51系列单片机以其优越的性能、成熟的技术、高性价比被广应用于测控仪器等自动化领域。因此用51系列单片机实现USB主机接口,进而实现对USB外设的控制,对提高整个系统的数据存储、数据传输、设备控制等性能都有很大的作用。

根据我们的调查和了解,我们发现,随着Flash Memory非易失存储技术的发展,基于USB 接口的闪存即U盘现已得到广泛应用。从理论上讲,以U盘作为便携式采集存储系统的存储载体完全能够满足长时间采集海量数据的要求。但目前所面临的问题是,U盘主要应用于PC机系统中。以单片机等微处理器为核心的嵌入式系统的应用中,尚缺少与U盘的直接接口技术。因此将单片机技术与U盘存储技术两者结合起来,利用单片机直接读写U盘,并通过总线方式与嵌入式系统的其它部分实现命令和数据的通信。采用单片机直接控制读写U盘,关键在于USB-HOST技术的实现,即单片机作为USB主机系统。

USB系统包括两部分:USB主机和USB外设,它们组合在一起就构成了完整的USB系统。USB 的拓扑结构中居于核心地位的是Host(也称为主机),任何一次USB的数据传输都必须由主机来发起和控制,所有的USB外设都只能和主机建立连接,任何两个外设之间或是两个主机之间无法直接通信。鉴于复杂的USB协议,我们觉得可以采用USB读写模块,这样只要将USB读写模块嵌入到用户单片机系统中,就可以通过单片机的串口与USB读写模块之间的通信,进而读写U 盘里面的数据,还可以方便的利用U盘储存海量的AD转换后的数据等。

三 , USB总线接口芯片CH375

3.1 概述:

CH375 是一个USB总线的通用接口芯片,支持USB-HOST主机方式和USB-DEVICE/SLAVE设备

方式。在本地端,CH375具有8位数据总线和读、写、片选控制线以及中断输出,可以方便地

挂接到单片机/DSP/MCU/MPU等控制器的系统总线上。在USB主机方式下,CH375还提供了串行

通讯方式,通过串行输入、串行输出和中断输出与单片机/DSP/MCU/MPU 等相连接。

CH375的USB 主机方式支持常用的USB 全速设备,外部单片机可以通过CH375 按照相应的

USB 协议与USB 设备通讯。CH375 还内置了处理Mass-Storage 海量存储设备的专用通讯协议的固件,外部单片机可以直接以扇区为基本单位读写常用的USB 存储设备(包括USB 硬盘/USB闪存盘/U 盘)

3.2 特点

1)全速USB-HOST 主机接口,兼容USB V2.0,外围元器件只需要晶体和电容。

2)全速设备接口,完全兼容CH372 芯片,支持动态切换主机与设备方式。

3)主机端点输入和输出缓冲区各64 字节,支持常用的12Mbps 全速USB 设备。

4)支持USB 设备的控制传输、批量传输、中断传输。

5)自动检测USB 设备的连接和断开,提供设备连接和断开的事件通知。

6)内置控制传输的协议处理器,简化常用的控制传输。

7)内置固件处理海量存储设备的专用通讯协议,支持Bulk-Only传输协议和SCSI、UFI、RBC 或等效命令集的USB 存储设备(包括USB 硬盘/USB 闪存盘/U 盘)。

8)通过U 盘文件级子程序库实现单片机读写USB 存储设备中的文件。

9)并行接口包含8 位数据总线,4 线控制:读选通、写选通、片选输入、中断输出。

10)串行接口包含串行输入、串行输出、中断输出,支持通讯波特率动态调整。

11)支持5V 电源电压和3.3V 电源电压,CH375A 芯片还支持低功耗模式。

12)采用SOP-28 封装,可以提供SOP28 到DIP28 的转换板。

图1 CH375各引脚说明

3.3 功能说明

CH375 芯片可以工作于USB-HOST 主机方式或者USB 设备方式。CH375的USB 主机方式支持并行接口和串行接口。在USB主机方式下,CH375支持各种常用的USB全速设备,外部单片机需要编写固件程序按照相应的USB协议与USB 设备通讯。但是对于USB存储设备,CH375 内置了相关协议,通常情况下,外部单片机不需要编写固件程序,就可以直接通讯。CH375 芯片在本地端提供了通用的被动并行接口和点对点的串行接口。

图2 CH375芯片的电器参数

3.4 CH375工作于串口模式下

串行接口只能用于USB 主机方式,CH375 芯片的USB 设备方式不支持串口。串口信号线包括:串行数据输入引脚RXD、串行数据输出引脚TXD、中断输出引脚INT#。通过串行接口,CH375 可以用最少的连线与单片机、DSP、MCU 进行较远距离的点对点连接。

CH375芯片的RXD 和TXD可以分别连接到单片机的串行数据输出引脚和串行数据输入引

脚。INT#输出的中断请求是低电平有效,用于通知单片机。CH375 的串行数据格式是1个起始位、9个数据位、1个停止位,其中前8个数据位是一个字节数据,最后1个数据位是命令标志位。第9位为0时,前8位的数据被写入CH375芯片中,第9位为1时,前8位被作为命令码写入CH375芯片中。CH375的串行通讯波特率默认是9600bps,单片机可以随时通过SET_BAUDRATE 命令选择合适的通讯波特率。

3.5 其它功能简介

在CH375 芯片的复位期间,TXD引脚用于选择通讯接口。如果CH375 在复位期间检测到TXD 引脚为低电平则启用并行接口,否则启用串行接口。如果启用串行接口,那么复位完成后TXD引脚将用于串行数据输出,并且CH375 芯片只能工作于USB 主机方式。

CH375芯片的ACT#引脚用于状态指示。在内置固件的USB设备方式下,当USB 设备尚未配置或者取消配置后,该引脚输出高电平;当USB 设备配置完成后,该引脚输出低电平。对于CH375A 芯片,在USB主机方式下,当USB 设备断开后,该引脚输出高电平;当USB设备连接后,该引脚输出低电平。CH375 的ACT#引脚可以外接串了限流电阻的发光二级管LED,用于指示相关的状态。

CH375 芯片的UD+和UD-引脚是USB 信号线,工作于USB 设备方式时,应该直接连接到USB总线上;工作于USB 主机方式时,可以直接连接到USB设备。如果为了芯片安全而串接保险电阻或者电感,那么交直流等效串联电阻应该在5Ω之内。

CH375芯片内置了电源上电复位电路,一般情况下,不需要外部提供复位。RSTI 引脚用于从外部输入异步复位信号;当RSTI 引脚为高电平时,CH375芯片被复位;当RSTI 引脚恢复为低电平后,CH375会继续延时复位20mS 左右,然后进入正常工作状态。为了在电源上电期间可靠复位并且减少外部干扰,可以在RSTI引脚与VCC 之间跨接一个容量为0.47uF 左右的电容。RST引脚和RST#引脚是复位状态输出引脚,分别是高电平有效和低电平有效;当CH375电源上电复位或者被外部强制复位以及复位延时期间,RST 引脚和RST#引脚分别输出高电平和低电平;CH375复位完成后,RST 引脚和RST#引脚分别恢复到低电平和高电平。RST 和RST#引脚可以用于向外部单片机提供上电复位信号。

CH375芯片正常工作时需要外部为其提供12MHz 的时钟信号。一般情况下,时钟信号由

CH375内置的反相器通过晶体稳频振荡产生。外围电路只需要在XI 和XO 引脚之间连接一个标称

频率为12MHz的晶体,并且分别为XI 和XO 引脚对地连接一个高频振荡电容。如果从外部直接输入12MHz时钟信号,那么应该从XI 引脚输入,而XO 引脚悬空。

CH375芯片支持5V电源电压或者3.3V 电源电压。当使用5V 工作电压时,CH375 芯片的VCC 引脚输入外部5V 电源,并且V3 引脚应该外接容量为0.01uF 左右的电源退耦电容。当使用3.3V 工作电压时,CH375 芯片的V3引脚应该与VCC引脚相连接,同时输入外部的3.3V 电源,并且与CH375 芯片相连接的其它电路的工作电压不能超过3.3V。

3.6 内部结构

CH375 芯片内部集成了PLL 倍频器、主从USB 接口SIE、数据缓冲区、被动并行接口、异步串行接口、命令解释器、控制传输的协议处理器、通用的固件程序等。PLL 倍频器用于将外部输入的12MHz 时钟倍频到48MHz,作为USB 接口SIE 时钟。

主从USB 接口SIE是USB主机方式和USB设备方式的一体式SIE,用于完成物理的USB数据接收和发送,自动处理位跟踪和同步、NRZI编码和解码、位填充、并行数据与串行数据之间的转换、CRC数据校验、事务握手、出错重试、USB 总线状态检测等。

数据缓冲区用于缓冲USB 接口SIE 收发的数据。

被动并行接口用于与外部单片机/DSP/MCU 交换数据。

异步串行接口用于代替被动并行接口与外部单片机/DSP/MCU 交换数据。

命令解释器用于分析并执行外部单片机/DSP/MCU 提交的各种命令。

控制传输的协议处理器用于自动处理常用的控制传输的多个阶段,简化外部固件编程。

通用的固件程序包含两组:一组用于USB 设备方式,自动处理USB默认端点0 的各种标准事务等;另一组用于USB 主机方式,自动处理Mass-Storage 海量存储设备的专用通讯协议。

CH375 芯片内部具有7 个物理端点:

端点0 是默认端点,支持上传和下传,上传和下传缓冲区各是8 个字节;

端点1包括上传端点和下传端点,上传和下传缓冲区各是8个字节,上传端点的端点号是81H,下传端点的端点号是01H;

端点2 包括上传端点和下传端点,上传和下传缓冲区各是64 个字节,上传端点的端点号是82H,下传端点的端点号是02H;

主机端点包括输出端点和输入端点,输出和输入缓冲区各是64 个字节,主机端点与端点2合用同一组缓冲区,主机端点的输出缓冲区就是端点2 的上传缓冲区,主机端点的输入缓冲区就是端点2 的下传缓冲区。

CH375 的端点0、1、2 只用于USB 设备方式,在USB 主机方式下只需要用到主机端点。在USB 主机方式下,CH375 支持各种常用的USB 全速设备。USB 设备的端点号可以是0~15,两个方向最多支持31 个端点,USB 设备的包长度可以是0~64 字节。

内置固件可以处理Mass-Storage 海量存储设备的通讯协议,要求USB 存储设备支持

Bulk-Only传输协议,支持SCSI、UFI、RBC或者等效的命令集,并且数据端点的最大包长度是64 字节,但是默认端点0 的最大包长度可以是8、16、32 或者64 字节。如果USB 存储设备不符合上述要求,则需要外部单片机通过控制传输以及ISSUE_TOKEN 命令或者ISSUE_TKN_X命令自行处理相关通讯协议。

图3 CH375芯片内部中断逻辑图

3.7 本地端的单片机软件

CH375芯片占用两个地址位,当A0 引脚为高电平时选择命令端口,可以写入命令;当A0 引脚为低电平时选择数据端口,可以读写数据。

单片机通过8 位并口对CH375 芯片进行读写,所有操作都是由一个命令码、若干个输入数据和若干个输出数据组成,部分命令不需要输入数据,部分命令没有输出数据。命令操作步骤如下:

①、在A0=1 时向命令端口写入命令代码;

②、如果该命令具有输入数据,则在A0=0 时依次写入输入数据,每次一个字节;

③、如果该命令具有输出数据,则在A0=0 时依次读取输出数据,每次一个字节;

④、命令完成,可以暂停或者转到①继续执行下一个命令。

CH375芯片专门用于处理USB 通讯,在检测到USB 总线的状态变化时或者命令执行完成

后,CH375以中断方式通知单片机进行处理。

3.8单片机读写U盘文件

图4 单片机读写U 盘文件

一般情况下,单片机或嵌入式系统处理USB 存储设备的文件系统需要实现上图左边的4个层次,右边是USB 存储设备的内部结构层次。由于CH375 不仅是一个通用的USB-HOST 硬件接口芯片,还内置了相关的固件程序,包含了上图左边的3 个层次(标为灰色部分),所以实际的单片

机程序只需要处理FAT 文件系统层,并且即使这一层也可以由CH375 的U 盘文件级子程序库实现。

如果不需要处理文件系统,也就是不处理上图左边的最顶层,那么CH375 直接提供了数据块的读写接口,以512字节的物理扇区为基本读写单位,从而将USB存储设备简化为一种外部数据存储器,单片机可以自由读写USB 存储设备中的数据,也可以自由定义其数据结构。由于计算机将USB 存储设备组织为文件系统,为了方便单片机通过USB移动存储设备与计算机之间交换数据,单片机也可以将USB 存储设备组织为文件系统,也就是处理上图左边的最顶层。

CH375以C语言子程序库提供了USB存储设备的文件级接口,这些应用层接口API包含了常用的文件级操作,可以移植并嵌入到各种常用的单片机程序中。

CH375 的U 盘文件级子程序库具有以下特性:支持常用的FAT12、FAT16 和FAT32 文件系统,磁盘容量可达100GB 以上,支持多级子目录,支持8.3 格式的大写字母和中文文件名,可以支持小写字母或者长文件名,支持文件打开、新建、删除、读写以及搜索等。

CH375 的文件级子程序库需要大约600 字节的随机存储器RAM 作为缓冲区。以普通的MCS-51 单片机为例,文件系统的全部子程序有4KB 到8KB 代码,并且需要大约80 字节的内部RAM 和512 字节的外部RAM 作为缓冲区。

四,串口版U盘读写模块的说明

模块具有两个外部接口:P1 是USB 插座,可以直接插入U 盘或者通过USB 延长线连接U盘,当进行程序升级或者重新配置时应该通过USB 对连线连接计算机的USB 端口;P2 是16 脚的双排针或者插座,用于连接单片机系统。

图5 串口版U盘模块正反外观图

在串口方式下,单片机与模块的P2 端口相连接,只需要使用高8 脚(第9 脚到第16脚),其余引脚可以不连接。模块可以通过串行输入SIN、串行输出SOUT 连接到单片机的异步串口,除此之外,启动输入STA#还应该连接到单片机的一个I/O 引脚,而中断输出INT#可以根据需要决定是否连接到单片机的中断引脚。

模块的串口是1 位起始位、8 位数据位、1位停止位的异步串口,串口的通讯波特率可以在功能配置时设定,如果未设定那么默认是4800bps(与晶体X2 的频率有关),单片机系统可以根据需要通过CMD_BaudRate 命令设定更高的波特率。如果在功能配置时选择检查串口超时,那么在

通过串口输入命令包时,模块会检查串口数据输入超时,如果连续两个数据字节之间的间隔大于串口输入超时时间,则模块将放弃该命令包。

4+1 线串口是指GND、SIN、SOUT、STA#和可选的INT#,P2 引脚定义如下:

图6 模块引脚定义图

为了节约单片机的I/O 引脚,模块还支持三线制串口,在这种方式下,单片机与模块之间只需要连接SIN 和SOUT 两根信号线及公共地线,单片机通过串口发送两个同步码字节(57H、ABH)代替原来向模块的STA#引脚提供的启动信号,实现与模块的命令同步。在通过串口输入两个同步码字节时,模块会检查串口数据输入超时,如果连续两个数据字节之间的间隔大于串口输入超时时间,则模块将放弃该同步码及命令包。

图7 TTL电平转RS232电平经行通信的串口模块电路图

图8 串口版模块与单片机之间的电路连接图

图9 单片机系统串口与RS232借口连接电路图

图10 单片机系统和模块之间连接的实物图

六,软件设计

为了使上位PC 机能够直接读取该读写器写入U 盘的数据,数据存储按照FAT32 文件管理方式存储,其中涉及USB 和UFI 协议以及FAT32 文件存储格式。

6.1 USB协议

USB(通用串行总线)用于将USB 接口的外围设备(device)连接到主机(host),实现二者之间数据传输的外部总线结构,是一种快速、灵活的总线接口,USB 的传输类型有控制(control)、批量(bulk)、中断(interrupt)和同步(synchronous)传输4 种,它最大的特点是易于使用,即插即用,主要是用在中速和低速的外设。

控制数据用于在USB 接入总线时对其进行配置,其他的驱动软件可以根据具体的应用来选择使用控制传输,这种数据传输不会丢失数据。

典型的批量数据包括象使用打印机或扫描仪时所出现的大数据量的数据,这种批量数据是连续的,通过在硬件中实现差错检测功能,并且有选择地进行一定的应进重试操作,可以在硬件层次上保证数据的可靠交换。

由设备自发产生的数据传输是中断数据传输,这类数据传输可以由USB 设备在任意时刻发起,而且USB 总线以不低于设备说明的速率进行传输。

同步数据在产生、传送和处理过程中是连续的和实时的,在稳定的同步数据发送和接收速率中包含了相应的时钟信息,为了保持定时关系,同步数据必须按照接收的速率进行传输。

6.2 BULK_ONLY 和UFI 协议

USB 设备分为5 大类,即显示器、通信设备、音频设备、人机输入和海量存储。通常所用的U 盘、移动硬盘均属于海量存储类。海量存储类的规范中包括4 个独立的子规范,即CBI 传输、Bulk-Only 传输、ATA 命令块、UFI 命令规范。前两个协议定义了数据/命令/状态在USB 总线上的传输方法,Bulk-Only 传输协议仅仅使用Bulk 端点传送数据/命令/状态,CBI 传输协议则使用Control/bulk/interrupt 三种类型的端点进行数据/命令/状态的传送。后两个协议定义了存储介质的操作命令,ATA 协议用于硬盘,UFI 协议则针对USB 移动存储,U盘读写器的设计遵循

Bulk-Only 传输协议和UFI 命令规范。UFI 命令块规范是针对USB 移动存储而制定的,它总共定

义了19 个12 字节长度的操作命令。

Bulk-Only 事务以主机向设备发送CBW(Command Block Warp)包,并以建立相应的数据传输开始的,设备接收到CBW 包,检查并解释它,试图满足主机的要求,并通过CSW(Command State Wrap)包向主机返回状态信息。

CBW 是主机通过Bulk-Out 端点向设备发送的命令块包,在CBW 中使用方向位和数据传输长度域指明期待的传输,CBW 必须起始于包边界,并且必须以31 字节的短包传输结束,相继的数据包和CSW 包必须开始于一个新的包边界,所有的CBW 包必须按低字节在前的次序传输。

CBW包结构如图所示,各域含义如下:

图10 CBW包结构

1)命令块包标识。CBW 包标记,表明这是一个CBW 包,这个域的值为43425355H。

2)命令块标记。当设备返回相应的CSW 包时,必须使命令状态标记域的值与此值相同。

3)数据传输长度。指明命令执行期间在Bulk 端点上传数据的字节长度,如果这个域的值是0,则在CBW 和CSW 之间设备和主机不传输任何数据,并且设备将忽略在命令块标旗域中的方向位的值。

4)命令块标旗。方向位规定了Bulk 端点数据传输的方向,其他位预留。

5)逻辑单元号。指定命令块被发送到的逻辑单元号,如果设备不支持多个逻辑单元号,则主机将这个域设置为0。

6)CBWCB 长度,定义了CBWCB 的有效长度,合法值为1-16。

7)CBWCB。由设备执行的命令,由设备解释。

CSW 向主机表明来自于CBW 包的命令块的执行状态。设备收到CBW 包解析处理后将通过B

ulk-In 端点发送一个CSW 包。CSW 开始于包边界,并以13 字节的短包结束,结构如图所示,各域含义如下:

图11 命令状态包结构

1)命令状态包标识。CSW 包的标记,表明这是一个CSW 包,这个域的值为53425355H。

2)命令状态标记。次域的值域CBW 包的命令块标记相同。

3)数据残余。实际数据传输量与CBW 包中规定的数据传输长度的差值。

4)命令执行状态,表明命令成功或失败信息,如果命令执行成功,则设备将设置此域的值为0,非0 值;则表明失败或错误。

UFI 是针对USB 移动存储而制定的命令块协议,它规定了主机和设备进行信息交换所使用的命令块、数据和状态信息,Bulk-Only 传输协议定义了传输这些信息的方法,其中UFI 命令块是封装在CBW 包中的CBWCB,设备通过读取CBWCB 确定具体要执行何种操作命令(如读命令),如何完成这个命令(如从闪存的哪个地址读,需要读取的长度),设备将命令的执行状态封装成CSW 返回给主机。

UFI 用于大多数命令的12 字节命令块的描述,结构如图4 所示,其中各参数意义如下:

1)操作命令代码。指明所需要执行的操作命令;

2)逻辑单元号。指明命令将发送到哪个逻辑单元,如果设备只有一个逻辑单元,则此域的值为0。3)逻辑块地址。命令操作的起始地址。

4)传输长度,指明请求传输的数据量,通常以"扇区"作单位,但是有几个命令是以"字节"作单位的,对于这些命令,传输长度域可以以不同的名字标识,若此域的值为0,则表面没有数据需要传输。

5)参数列表长度,用于指定发送到设备的字节数,这个域典型的应用于发送到设备的参数命令块(如模式参数、诊断参数等),若此域的值为0,则表面没有数据需要传输。

6)分配长度,指明主机已经分配的用于返回数据的最大字节长度,若此值为0,则表明没有数据需要传输。

6.3 FAT32

FAT 是Microsoft 较早推出的文件系统,具有高度的兼容性,目前仍然广泛应用于个人电脑尤其是移动存储设备中,FAT 由引导扇区、FAT1 表、FAT2 表、目录和文件区组成(其中FAT2 表是FAT1 表的备份)。磁盘的管理是以扇区为单位的,而移动存储设备则是以块为单位的,FAT 将块映射成扇区,原理相同,FAT 将磁盘空间以一定数目的扇区为单位进行划分,这样的单位成为"簇"。通常情况下,每扇区512 字节的原则是不变的,簇的大小一般是2n(n 为整数)个扇区的大小。所以以簇为单位而不以扇区为单位进行磁盘的分配,是因为当区分容量较大时,采用512 字节的扇区管理,会增加FAT 表的项数和大文件存取的消耗,使文件系统效率不高。

引导扇区DBR(DOS Boot Record)通常占用分区的第0 扇区,共512 字节,FAT 表紧随其后。DBR 的第一部分是一个x86 跳转指令、厂商标志和操作系统版本号,接下来的从偏移0x0B 开始的是一段描述能够使可执行引导代码找到相关参数的消息,通常称之为BPB。最后是引导程序代码以及扇区结束标志。BPB 中记录了扇区大小、簇的扇区数、保留扇区数、FAT 表大小和文件系统类型等重要参数,用于文件的索引和定位计算。

7.4 软件系统模块

USB 读写器软件由主模块、USB 模块、BULK 模块、FAT 模块和中断处理模块组成。各模块之间相互协调调用,共同完成对U 盘文件的读写创建。

USB 模块负责检测USB 设备的移入/移出,对插入的设备进行枚举,分配设备地址端点号,配置设备接口端点描述符,建立BULK_ONLY 输入/输出通道,BULK 模块则在已建立的BULK_ONLY 输入/输出通道发送CBW 数据包,并接收CSW 数据包,通过CBW 中嵌入的CBWCB 信息确定对U 盘读/写操作的扇区位置和大小,FAT 模块主要完成簇和扇区间的索引定位,即在U 盘内寻址,利用BPB 中的参数计算给定扇区的所在簇以及进入休眠状态,等待外部中断唤醒。

中断处理模块是在中断唤醒后根据中断类型进入不同功能子模块的,也是整个软件系统的核心部分。中断模块接收到串口或并口数据后,根据内部命令字要求进行解析。串口或并口数据接收流程如图所示。

图12 UFI结构

图13 命令与数据字结构

七,总结

此次科研立项是我们从大学生活重要的一步。从最初的选题,开题到查资料、设计电路,编写程序直到完成设计。其间,查找资料,老师指导,与同学交流,反复修改电路和程序,每一个过程都是对自己能力的一次检验和充实。

通过这次实践,我了解了单片机读写U 盘的用途及工作原理,熟悉了单片机读写U 盘的设计步骤,锻炼了工程设计实践能力,培养了自己独立设计能力。此次科研立项是对我专业知识和专业基础知识一次实际检验和巩固,同时也是我为未来的单片机和嵌入式开发与应用的的一次热身。

通过这次科研立项收获很多,比如学会了查找相关资料相关标准,分析数据,提高了自己的电路设计和程序设计的能力,懂得了许多经验公式的获得是前人不懈努力的结果。同时,仍有很多课题需要后来人去努力去完善。

但是这次科研立项也暴露出自己专业基础的很多不足之处。比如缺乏综合应用专业知识的能力,对集成芯片的不了解等等。这次科研立项是对自己到现在为止大学所学的一次大检阅,使我明白自己知识还很浅薄,虽然大学生活已经过了一大半,但是自己的求学之路还很长,以后更应该在有限的大学生活学习中,努力的学习好专业文化知识和动手能力,同时也要提高自己各方面的综合素质,努力使自己成为一个对社会有所贡献的人。

参考文献:

【1】《基于单片机的智能系统设计与实现》沈红卫著,电子工业出版社

【2】《单片机技术应用》朱运利著,机械工业出版社

【3】《MCS-51 单片机开发与应用指南》孙永浩著黑龙江科学技术出版社

【4】《EZ-USB FX2单片机原理,编程及应用》钱峰著,北京航空航天大学出版社

【5】CH375中文技术手册

【6】串口版U盘读写模块中文技术手册

附录:

以下程序可以演示单片机以字节的方式读写U盘,该程序实现的功能是:打开U盘中的一个文件EXAMBYTE.TXT,再新建一个文件NEWFILE.TXT,在NEWFILE.TXT文件中写入“Note:这个程序是以字节为单位进行U盘文件读写的示例程序,首先从原文件中读出前20个字符,然后写到本说明的后面:”然后从文件EXAMBYTE.TXT中读取前20字节的数据,写入文件NEWFILE.TXT中。即可实现单片机以字节对U盘读和写的功能。

#include

#include

#include

#include

#define MAX_PATH_LEN 32

#include

unsigned char TempLength;

unsigned char idata TempBuffer[20];

CMD_PARAM idata mCmdParam;

sbit L ED_OUT = P0^4;

sbit p2_0=P2^0;

void m DelaymS( unsigned char delay )

{

unsigned char 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 m SendByte( unsigned char c )/* 发送一个字节数据给CH375模块 */

{

TI = 0;

SBUF = c;

while ( TI == 0 );

}

unsigned char mRecvByte( )/* 从CH375模块接收一个字节数据 */

{

unsigned char c;

while ( RI == 0 );

c = SBUF;

RI = 0;

return( c );

}

unsigned char ExecCommand( unsigned char cmd, unsigned char len )/* 命令函数 */ {

unsigned char i, j, status;

mSendByte( SER_SYNC_CODE1 );

m SendByte( SER_SYNC_CODE2 );

mSendByte( cmd );

mSendByte( len );

RI = 0;

if ( len ) {

for ( i = 0; i != len; i ++ ) mSendByte( mCmdParam.Other.mBuffer[ i ] ); }

while ( 1 ) {

status = mRecvByte();

if ( status == ERR_SUCCESS ){

i = mRecvByte( );

LED_OUT = 0;

if ( i ){

j = 0;

do {

mCmdParam.Other.mBuffer[ j ] = mRecvByte( );

j ++;

} while ( -- i );

}

break;

}

else if ( status == USB_INT_DISK_READ || status == USB_INT_DISK_WRITE || status == USB_INT_DISK_RETRY )

{

break;

}

else {

if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT ) mDelaymS( 100 ); break;

}

}

return( status );

}

void m StopIfError( unsigned char iError )/*错误检测函数*/

{

unsigned char led;

if ( iError == ERR_SUCCESS ) return;

led=0;

while ( 1 ) {

LED_OUT = led&1; /* LED闪烁 */

mDelaymS( 100 );

led^=1;

}

}

main( ) {

unsigned char i;

unsigned short count;

unsigned char *pStr;

mDelaymS( 500 );

p2_0=0;

LED_OUT = 0;

mDelaymS( 100 );

mDelaymS( 100 );

LED_OUT = 1;

SCON = 0x50;

PCON = 0x80;

TMOD = 0x20;

TH1 = 0xE8;/* 22.1184MHz晶振, 4800bps */

TR1 = 1;

while ( 1 ) /* 程序中使用查询方式查询模块状态,和向模块发送同步码启动操作,然后发送相关的命令 */

{

while ( 1 )

{

i = ExecCommand( CMD_QueryStatus, 0 );

mStopIfError( i );

if ( mCmdParam.Status.mDiskStatus >= DISK_CONNECT )

break;

mDelaymS( 100 );

}

mDelaymS( 500 );

LED_OUT = 0;

for ( i = 0; i < 5; i ++ )

{

mDelaymS( 100 );

if ( ExecCommand( CMD_DiskReady, 0 ) == ERR_SUCCESS ) break;

}

/* 读取原文件 */

strcpy( mCmdParam.Open.mPathName, "\\EXAMBYTE.TXT" );

i = ExecCommand( CMD_FileOpen, MAX_PATH_LEN );

TempLength = 0;

if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) /* 找不到文件或者出错 */

{

}

else {

mStopIfError( i );

mCmdParam.ByteRead.mByteCount = 20;

i = ExecCommand( CMD_ByteRead, 1 );

mStopIfError( i );

TempLength = mCmdParam.ByteRead.mByteCount;

memcpy( TempBuffer, mCmdParam.ByteRead.mByteBuffer, TempLength );

mCmdParam.Close.mUpdateLen = 0;

i = ExecCommand( CMD_FileClose, 1 );

mStopIfError( i );

/* 产生新文件 */

strcpy( mCmdParam.Create.mPathName, "\NEWFILE.TXT" );

i = ExecCommand( CMD_FileCreate, MAX_PATH_LEN );

mStopIfError( i );

pStr = "Note:这个程序是以字节为单位进行U盘文件读写的示例程序,首先从原文件中读出前20个字符,然后写到本说明的后面:";

count = strlen( pStr );

while ( count ) {

if ( count < sizeof( mCmdParam.ByteWrite.mByteBuffer ) ) i = count; else i = sizeof( mCmdParam.ByteWrite.mByteBuffer );

/* 数据较多,分多次写入 */

count -= i;

memcpy( mCmdParam.ByteWrite.mByteBuffer, pStr, i );

pStr += i;

mCmdParam.ByteWrite.mByteCount = i;

i = ExecCommand( CMD_ByteWrite, 1+i );/* 以字节为单位向文件写入数据 */ mStopIfError( i );

}

memcpy( mCmdParam.ByteWrite.mByteBuffer, TempBuffer, TempLength );

mCmdParam.ByteWrite.mByteCount = TempLength; /* 将原文件中的20个字节的数据添加到新文件的末尾 */

i = ExecCommand( CMD_ByteWrite, 1+TempLength );

mStopIfError( i );

mCmdParam.Close.mUpdateLen = 1;

i = ExecCommand( CMD_FileClose, 1 ); /* 关闭文件*/

mStopIfError( i );

p2_0=1;

LED_OUT = 1; /* LED灭 */

/* 等待U盘断开 */

while ( 1 ) {

i = ExecCommand( CMD_QueryStatus, 0 );

mStopIfError( i );

if ( mCmdParam.Status.mDiskStatus <= DISK_DISCONNECT ) break;

mDelaymS( 100 );

}

}

}

}

基于单片机的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 扮演着主机的角色。根据USB 的规范,可以看到在USB 的拓朴结构中居于核心地位的是主机,每一次的数据传输都必须由主机发起和控制。但是随着单片机产品应用领域的日益增长,USB 外设的应用范围也随之扩大,为此在单片机系统中实现对USB外设控制也变得日益迫切。因此在一些需要转存数据的设备,仪器上使用USB移动存储设备接口的芯片便相继产生了,CH375 就是其中之一,它是一个USB 总线的通用接口芯片,支持HOST 主机方式和SLAVE 设备方式。

如今的USB 就象当日的RS232,最终发展必是业界的主流外设接口技术。USB 有着其它接口不可替代的优势。随着USB 技术的发展,计算机的移动存储介质普遍采用U 盘或移动硬盘。如今,USB 技术已经越来越普及和成熟,低成本、高稳定性、较高的数据传输速率和即插即用的方便性,使其备受硬件厂商的青睐。随着数据采集和单片机用户对移动存储的需求越来越大,具有USB 接口的存储设备以其优异的性价比和灵活性常用来进行数据的存储和交换,所以在单片机系统中实现对优盘或移动硬盘的直接读写是非常有价值的。

四,研究的意义

USB是近年发展起来的一种快速、灵活的总线接口。它最大的特点是易于使用、可热插拔、接口连接灵活,并且能够提供外设电源,在嵌人式系统及智能仪表中得到广泛的应用。而51系列单片机以其优越的性能、成熟的技术、高性价比被广应用于测控仪器等自动化领域。因此用51系列单片机实现USB主机接口,进而实现对USB外设的控制,对提高整个系统的数据存储、数据传输、设备控制等性能都有很大的作用。

根据我们的调查和了解,我们发现,随着Flash Memory非易失存储技术的发展,基于USB 接口的闪存即U盘现已得到广泛应用。从理论上讲,以U盘作为便携式采集存储系统的存储载体完全能够满足长时间采集海量数据的要求。但目前所面临的问题是,U盘主要应用于PC机系统中。以单片机等微处理器为核心的嵌入式系统的应用中,尚缺少与U盘的直接接口技术。因此将单片机技术与U盘存储技术两者结合起来,利用单片机直接读写U盘,并通过总线方式与嵌入式系统的其它部分实现命令和数据的通信。采用单片机直接控制读写U盘,关键在于USB-HOST技术的实现,即单片机作为USB主机系统。

USB系统包括两部分:USB主机和USB外设,它们组合在一起就构成了完整的USB系统。USB 的拓扑结构中居于核心地位的是Host(也称为主机),任何一次USB的数据传输都必须由主机来发起和控制,所有的USB外设都只能和主机建立连接,任何两个外设之间或是两个主机之间无法直接通信。鉴于复杂的USB协议,我们觉得可以采用USB读写模块,这样只要将USB读写模块嵌入到用户单片机系统中,就可以通过单片机的串口与USB读写模块之间的通信,进而读写U 盘里面的数据,还可以方便的利用U盘储存海量的AD转换后的数据等。

三 , USB总线接口芯片CH375

3.1 概述:

CH375 是一个USB总线的通用接口芯片,支持USB-HOST主机方式和USB-DEVICE/SLAVE设备

方式。在本地端,CH375具有8位数据总线和读、写、片选控制线以及中断输出,可以方便地

挂接到单片机/DSP/MCU/MPU等控制器的系统总线上。在USB主机方式下,CH375还提供了串行

单片机EEPROM的使用函数

/******************************************************************** 这是EEROM.h文件 ********************************************************************/ #ifndef _EEPROMus_h //对EEROM进行操作 #define _EEPROMus_h #include #include extern void EEw(unsigned int m,unsigned int,unsigned char w); //将第m扇区的第n个存储空间数据改成w extern void EEr(unsigned int m,unsigned int n,unsigned char *r); //将第m扇区的第n个存储空间数据读到r extern void EEe(unsigned int m); //删除第m扇区内的内容 extern void EEwa(unsigned int m,unsigned int n,unsigned char w[]); //在m扇区,从0x00写到第n个,写数组w里的数 extern void EEra(unsigned int m,unsigned int n,unsigned char r[]); //在m扇区,从0x00读到第n个,读到数组r里 #endif /******************************************************************** 这是EEPROM.c文件 ********************************************************************/ /******************************************************************** IAP_CONTR: B7: 0:禁止IAP 1:允许IAP B6和B5配合让程序从AP区和ISP监控区复位及程序的开始 B4:当IAP_TRIG触发的5a/a5失败,则为1,且由软件清零 B3:/ B2B1B0:设置CPU等待时间 IAP_TRIG: 每次发送命令后要用此寄存器发送5a,然后a5后,命令生效 IAP_CMD: 对IAP进行命令输入: 0x00:无操作 0x01:读 0x02:写

51单片机中断程序大全

//实例42 :用定时器T0 查询方式 P2 口8 位控制LED 闪烁 //#include单片机寄存器定义的头文件 51包含 /******************************************************* *******函数功能:主函数 ******************************************************** ******/void main(void){ // EA=1;开总中断// 中断允许T0 // 定时器// ET0=1; 1的模式TMOD=0x01;// 使用定时器T0 位赋初值定时器T0 的高8 TH0=(65536-46083)/256; // 位赋初值的高8 TL0=(65536-46083)%6; // 定时器T0 T0启动定时器TR0=1;// TF0=0;P2=0xff; 无限循环等待查询while(1)// {while(TF0==0); TF0=0;P2=~P2; 位赋初值的高8 定时器TH0=(65536-46083)/256; // T0 位赋初值T0 TL0=(65536-46083)%6; //

定时器的高8 }} 1KHzT1:用定时器43 实例// 音频查询方式控制单片机发出 #include 单片机寄存器定义的头文件51 // 包含sbit sound=P3^7;将// 引脚sound P3.7 位定义为 /********************************************************** **** 函数功能:主函数 ******************************************************** ******/void main(void){// EA=1;开总中断// 中断允许ET0=1;// // 定时器T0 1的模式使用定时器// T1 TMOD=0x10; 位赋初值// TH1=(65536-921)/256; T1 定时器的高8 TL1=(65536-921)%6; // 定时器T1 的高8 位赋初值 TR1=1;// 启动定时器T1TF1=0; while(1)// 无限循环等待查询{while(TF1==0); TF1=0;

单片机中断程序大全

单片机中断程序大全公司内部编号:(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-

//实例42:用定时器T0查询方式P2口8位控制L E D闪烁#include // 包含51单片机寄存器定义的头文件void main(void) { // EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x01; //使用定时器T0的模式1 TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 TR0=1; //启动定时器T0 TF0=0; P2=0xff; while(1)//无限循环等待查询 { while(TF0==0) ; TF0=0; P2=~P2; TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 //实例43:用定时器T1查询方式控制单片机发出1KHz音频

#include // 包含51单片机寄存器定义的头文件sbit sound=P3^7; //将sound位定义为P3.7引脚 void main(void) {// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x10; //使用定时器T1的模式1 TH1=(65536-921)/256; //定时器T1的高8位赋初值 TL1=(65536-921)%256; //定时器T1的高8位赋初值 TR1=1; //启动定时器T1 TF1=0; while(1)//无限循环等待查询 { while(TF1==0); TF1=0; sound=~sound; //将P3.7引脚输出电平取反 TH1=(65536-921)/256; //定时器T0的高8位赋初值 TL1=(65536-921)%256; //定时器T0的高8位赋初值 } } //实例44:将计数器T0计数的结果送P1口8位LED显示 #include // 包含51单片机寄存器定义的头文件sbit S=P3^4; //将S位定义为P3.4引脚

51单片机中断程序大全

//实例42:用定时器T0查询方式P2口8位控制LED闪烁#include // 包含51单片机寄存器定义的头文件 /************************************************************** 函数功能:主函数 **************************************************************/ void main(void) { // EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x01; //使用定时器T0的模式1 TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 TR0=1; //启动定时器T0 TF0=0; P2=0xff; while(1)//无限循环等待查询 { while(TF0==0) ; TF0=0; P2=~P2; TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 } } //实例43:用定时器T1查询方式控制单片机发出1KHz音频#include // 包含51单片机寄存器定义的头文件 sbit sound=P3^7; //将sound位定义为P3.7引脚 /************************************************************** 函数功能:主函数 **************************************************************/ void main(void) { // EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x10; //使用定时器T1的模式1 TH1=(65536-921)/256; //定时器T1的高8位赋初值

单片机内的Flash与EEPROM作用及区别(精)

单片机内的 Flash 与 EEPROM 作用及区别 单片机运行时的数据都存在于 RAM (随机存储器中, 在掉电后 RAM 中的数据是无 法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用 EEPROM 或FLASHROM 等 存储器来实现。在传统的单片机系统中, 一般是在片外扩展存储器, 单片机与存储器之间通 过 IIC 或 SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开发上也要花 更多的心思。在 STC 单片机中内置了 EEPROM (其实是采用 IAP 技术读写内部 FLASH 来 实现 EEPROM ,这样就节省了片外资源,使用起来也更加方便。下面就详细介绍 STC 单 片机内置 EEPROM 及其使用方法。 flash 是用来放程序的,可以称之为程序存储器,可以擦出写入但是基本都是整个扇区进行的 . 一般来说单片机里的 flash 都用于存放运行代码,在运行过程中不能改; EEPROM 是用来保存用户数据,运行过程中可以改变,比如一个时钟的闹铃时 间初始化设定为 12:00,后来在运行中改为 6:00,这是保存在 EEPROM 里, 不怕掉电,就算重新上电也不需要重新调整到 6:00 下面是网上详细的说法,感觉不错:

FLASH 和 EEPROM 的最大区别是 FLASH 按扇区操作, EEPROM 则按字节操作, 二者寻址方法不同,存储单元的结构也不同, FLASH 的电路结构较简单,同样容量占芯片面积较小,成本自然比 EEPROM 低,因而适合用作程序存储器, EEPROM 则更多的用作非易失的数据存储器。当然用 FLASH 做数据存储器也行, 但操作比EEPROM 麻烦的多,所以更“人性化”的 MCU 设计会集成 FLASH 和 EEPROM 两种非易失性存储器,而廉价型设计往往只有 FLASH ,早期可电擦写型 MCU 则都是EEPRM 结构,现在已基本上停产了。 在芯片的内电路中, FLASH 和 EEPROM 不仅电路不同,地址空间也不同,操作方法和指令自然也不同, 不论冯诺伊曼结构还是哈佛结构都是这样。技术上, 程序存储器和非易失数据存储器都可以只用 FALSH 结构或 EEPROM 结构, 甚至可以用“变通”的技术手段在程序存储区模拟“数据存储区” ,但就算如此,概念上二者依然不同,这是基本常识问题。 EEPROM :电可擦除可编程只读存储器, Flash 的操作特性完全符合 EEPROM 的定义,属 EEPROM 无疑,首款 Flash 推出时其数据手册上也清楚的标明是EEPROM ,现在的多数 Flash 手册上也是这么标明的,二者的关系是“白马”和 “马” 。至于为什么业界要区分二者, 主要的原因是 Flash EEPROM 的操作方法和传统 EEPROM 截然不同,次要的原因是为了语言的简练,非正式文件和口语中Flash EEPROM 就简称为 Flash , 这里要强调的是白马的“白” 属性而非其“马” 属性以区别 Flash 和传统 EEPROM 。 Flash 的特点是结构简单, 同样工艺和同样晶元面积下可以得到更高容量且大数据量 下的操作速度更快,但缺点是操作过程麻烦,特别是在小数据量反复重写时, 所以在 MCU 中 Flash 结构适于不需频繁改写的程序存储器。 很多应用中,需要频繁的改写某些小量数据且需掉电非易失,传统结构的EEPROM 在此非常适合, 所以很多 MCU 内部设计了两种 EEPROM 结构, FLASH

Eeprom的读写

所看过的对24系列I2C读写时序描述最准确最容易理解的资料,尤其是关于主从器件的应答描述和页写描述,看完后明白了很多。关于页写的描述,网络上绝大部分范程都没提到页写时的数据地址必须是每页的首地址才能准确写入,而且如果写入超过一页的数据会循环覆盖当前页的数据。 关于IIC总线 I2C总线:i2c总线是Philips 公司首先推出的一种两线制串行传输总线。它由一根数据线(SDA)和一根时钟线(SDL)组成。i2c总线的数据传输过程如图3所示,基本过程为: 1、主机发出开始信号。 2、主机接着送出1字节的从机地址信息,其中最低位为读写控制码(1为读、0为写),高7位为从机器件地址代码。 3、从机发出认可信号。 4、主机开始发送信息,每发完一字节后,从机发出认可信号给主机。 5、主机发出停止信号。 I2C总线上各信号的具体说明: 开始信号:在时钟线(SCL)为高电平其间,数据线(SDA)由高变低,将产生一个开始信号。 停止信号:在时钟线(SCL)为高电平其间,数据线(SDA)由低变高,将产生一个停止信号。 应答信号:既认可信号,主机写从机时每写完一字节,如果正确从机将在下一个时钟周期将数据线(SDA)拉低,以告诉主机操作有效。在主机读从机时正确读完一字节后,主机在下一个时钟周期同样也要将数据线(SDA)拉低,发出认可信号,告诉从机所发数据已经收妥。(注:读从机时主机在最后1字节数据接收完以后不发应答,直接发停止信号)。 注意:在I2C通信过程中,所有的数据改变都必须在时钟线SCL为低电平时改变,在时钟线SCL为高电平时必须保持数据SDA信号的稳定,任何在时钟线为高电平时数据线上的电平改变都被认为是起始或停止信号。 作为一种非易失性存储器(NVM),24系列EEPROM使用的很普遍,一般作为数据量不太大的数据存储器。下面总结一下其应用的一些要点。从命名上看,24CXX中XX的单位是kbit,如24C08,其存储容量为8k bit,即1k Byte=1024 Byte。 一、工作条件 1.工作电压(VCC) 24CXX:4.5V-5.5V 24CXX-W:2.5V-5.5V 24CXX-R:1.8V-5.5V 2.输入电平定义(VIH,VIL) VIH:0.7VCC-VCC+1 VIL:-0.45V-0.3VCC 二、硬件连接 1.上拉电阻RP的取值 由于I2C总线电容要满足小于400pf的条件。从以下波形可以看出,上拉电阻越大,总线的电容越小,可以实现的数据传输率就越大,可达400khz。 [点击图片可在新窗口打开] 2.写保护脚 芯片写保护脚是高电平有效,即WP接高电平时禁止写入

STC单片机EEPROM读写程序

/* STC89C54RD+的flash空间从0x4000~0xf3ff 共90个扇区,每扇区512字节*/ // #define BaseAddr 0x1000 /* 51rc */ // #define EndSectoraddr 0x3d00 /* 51rc */ // #define EndAddr 0x3fff /* 51rc 12K eeprom */ #define BaseAddr 0x4000 #define EndSectoraddr 0xf200 #define EndAddr 0xf3ff #define UseAddr 0x1000 /* ------------- 定义扇区大小------------- */ #define PerSector 512 /* 用户程序需要记忆的数组, 用户实际使用了n-1个数据,数组长度规整到 2 4 8 16 32 64 上*/ uchar Ttotal[16] = { 0x55, /* 作为判别引导头使用,用户程序请不要修改它*/ /* 用户保存记忆的数据*/ 0x01, /* 用途说明....*/ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; uint timerForDelay, /* 专供延时用的变量*/ i, /* 循环变量*/ EepromPtr; /* eeprom读写指针*/ /* --------------- 命令定义--------------- */ #define RdCommand 0x01 /* 字节读*/ #define PrgCommand 0x02 /* 字节写*/

51单片机内部EEPROM的应用

用51hei-5板子学习单片机内部EEPROM的应用 STC89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPRO M,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上,先来介绍下ISP与IAP的区别和特点。 ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。 IAP:In Application Programable 是指在应用编程,就是片子提供一系列的机制(硬件/软件上的)当片子在运行程序的时候可以提供一种改变flash数据的方法。通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到存储区。大家要注意千万不要尝试去擦除这段ISP引导程序,否则恐怕以后再也下载不了程序了。STC单片机内部有几个专门的特殊功能寄存器负责管理ISP/IAP 功能的,见表1。 表1 ISP/IAP相关寄存器列表 名称地址功能描述D7D6D5D4D3D2D1D0复位值ISP_DATA E2h Flash数据寄存器1111 1111 ISP_ADDRH E3h Flash高字节地址寄 存器0000 0000 ISP_ADDRL E4h Flash低字节地址寄 存器0000 0000 ISP_CMD E5h Flash命令模式寄存 器 ----------MS2MS1MS0xxxx x000 ISP_TRIG E6h Flash命令触发寄存 器 xxxx xxxx ISP_CONTR E7h ISP/IAP 控制寄存器ISPEN SWBS SWRST----WT2WT1WT0000x x000 ISP_DATA:ISP/IAP操作时的数据寄存器。

51单片机中断程序大全

//实例42 :用定时器TO查询方式P2 口8位控制LED闪烁#include // 包含 51 单片机寄存器定义的头文件/************************************************************** 函数功能:主函数 void main(void) { // EA=1; // 开总中断 // ETO=1; // 定时器 TO 中断允许 TMOD=OxO1; // 使用定时器 TO 的模式 1 THO=(65536-46O83)/256; // 定时器 TO 的高 8 位赋初值 TLO=(65536-46O83)%256; // 定时器 TO 的高 8 位赋初值 TRO=1; // 启动定时器 TO TFO=O; P2=Oxff; while(1)// 无限循环等待查询 { while(TFO==O) TFO=O; P2=~P2; THO=(65536-46O83)/256; // 定时器 TO 的高 8 位赋初值

TL0=(65536-46083)%256; // 定时器 T0 的高 8 位赋初值 } // 实例43 :用定时器T1 查询方式控制单片机发出1KHz 音频#include // 包含 51 单片机寄存器定义的头文件 sbit sou nd=P3^7; // 将 sound 位定义为 P3.7 引脚 /************************************************************** 函数功能:主函数 **************************************************************/ void main(void) { // EA=1; // 开总中断 // ET0=1; // 定时器 T0 中断允许 TMOD=0x10; // 使用定时器 T1 的模式 1 TH1=(65536-921)/256; // 定时器 T1 的高 8 位赋初值 TL1=(65536-921)%256; // 定时器 T1 的高 8 位赋初值 TR1=1; // 启动定时器 T1 TF1=0; while(1)// 无限循环等待查询 {

STC单片机EEPROM的应用和程序

STC单片机EEPROM的应用和程序 (2009-04-22 21:58:34) 转载▼ 标签: 杂谈 分类:Program 最近,由于工作的需要,用STC89C52来开发新产品,要用天STC的Eeprom的功能,上网也找了一点资料,得到很大帮助,真的非常感谢。程序是我在网上摘录的,调试通过了,不过我产品在用动态扫描显示的,由于在Eeprom擦除时要用几十毫秒,会有一闪烁的。不过这是正常的。 单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无 法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现。在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开发上也要花更多的心思。在STC 单片机中内置了EEPROM(其实是采用IAP 技术读写内部FLASH 来 实现EEPROM),这样就节省了片外资源,使用起来也更加方便。下面就详细介绍STC 单片机内置EEPROM 及其使用方法。 STC 各型号单片机内置的EEPROM 的容量各有不同,见下表: (内部EEPROM 可以擦写100000 次以上) 上面提到了IAP,它的意思是"在应用编程",即在程序运行时程序存储器可由程序自 身进行擦写。正是是因为有了IAP,从而可以使单片机可以将数据写入到程序存储器中,使得数据如同烧入的程序一样,掉电不丢失。当然写入数据的区域与程序存储区要分开来,以使程序不会遭到破坏。 要使用IAP 功能,与以下几个特殊功能寄存器相关: ISP_DATA:ISP/IAP 操作时的数据寄存器。 ISP/IAP 从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处 ISP_ADDRH:ISP/IAP 操作时的地址寄存器高八位。 ISP_ADDRL:ISP/IAP 操作时的地址寄存器低八位。 ISP_CMD:ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效。 ISP_TRIG:ISP/IAP 操作时的命令触发寄存器。 当ISPEN(ISP_CONTR.7)=1 时,对ISP_TRIG 先写入0x46,再写入0xb9,ISP/IAP 命令才会生效。 单片机芯片型号起始地址内置EEPROM 容量(每扇区512 字节) STC89C51RC,STC89LE51RC 0x2000 共八个扇区 STC89C52RC,STC89LE52RC 0x2000 共八个扇区 STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区 STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区 STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区 寄存器标识地址名称7 6 5 4 3 2 1 0 初始值 ISP_DATA 0xE2 ISP/IAP闪存数据寄存器11111111 ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000

52单片机内部EEPROM

#include #include #define uchar unsigned char #define uint unsigned int sbit en=P2^7; sbit rs=P2^6; sbit rw=P2^5; void delay(unsigned char z) { unsigned char j,i; for (i=0;i> 8); //送地址高字节

51内部eeprom读写,实现掉电存储

主函数: #include #include"EEPROM.h" #include"smg.h" void main() { num=byte_read(DEBUG_Data_Memory_Begin_Sector_addr);//字节读(程序开始时读取EEPROM中数据) if(num>=60)num=0;//防止首次上电时读取出错?? while(1) { if(num<60) { display(num); num++;delay(5); delay1(DELAY_CONST); sector_erase(DEBUG_Data_Memory_Begin_Sector_addr);//擦出扇区 byte_program (DEBUG_Data_Memory_Begin_Sector_addr,num);//字节编程} if(num==60)num=0; } } EEPROM.h: /*STC89C51RC,STC89LE51RC 0x2000 共八个扇区 STC89C52RC,STC89LE52RC 0x2000 共八个扇区 STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区 STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区 STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区*/ #include #include //sfr定义特殊功能寄存器 sfr ISP_DA TA =0xe2;//ISP/IAP 操作时的数据寄存器,从Flash 读出的数据放在此处,向Flash 写的数据也需放在此处 sfr ISP_ADDRH =0xe3;//ISP/IAP 操作时的地址寄存器高八位 sfr ISP_ADDRL =0xe4;//ISP/IAP 操作时的地址寄存器低八位 sfr ISP_CMD =0xe5;//ISP/IAP 操作时的命令模式寄存器,须命令触发寄存器触发方可生效 sfr ISP_TRIG =0xe6;//ISP/IAP 操作时的命令触发寄存器 sfr ISP_CONTR =0xe7;//ISP/IAP 控制寄存器 /* 定义命令*/

AT24C02EEPROM读写程序

;--------------------------------------------------------------------------------------------------------------------- ;本程序是针对AT89S52单片机编制的EEPROM读写程序(2013.8.4测试通过) ;本程序在4MHZ、12MHZ和24MHZ分别测试通过 ;AT24C02的A0、A1、A2均接GND,设备地址高7位为(1010)000;WP接GND,充许对EEPROM正常读写 ;本程序仅作学习交流之用。 ;--------------------------------------------------------------------------------------------------------------------- SCl equ P2.0 ;SCL接A T89S52的P2.0端口,作为EEPROM的串行输入时钟 SDA equ P2.1 ;SDA接AT89S52的P2.1端口,作为主机与EEPROM之间信息串行传输总线WRITEDATA equ 08H;拟写入EEPROM的数据在主机中的存贮单元地址 READDATA equ 09H ;从EEPROM读取的数据存放到主机存贮单元地址EPROMADDRESS equ 0AH;拟随机读写EEPROM的存贮单元地址 ;------------------------------------------------ ORG 00H LJMP MAIN ;------------------------------------------------ ORG 50H MAIN: MOV SP,#20H;防止堆栈影响已用内存数据 ;以下为写EEPROM过程 mov EPROMADDRESS,#09H;该地址可以随意输入(00H~FFH),但读和写的地址须相同 MOV WRITEDA TA,#01010010B;该数字可以随意输入,并将读和写的数据进行比较;如读数正确则按将读出数据在P1口输出,可在P1口各位分别接LED灯直观显示出来。 LCALL WRITEEEPROMR ;以下为读EEPROM过程 mov EPROMADDRESS,#09H;该地址可以随意输入(00H~FFH),但读和写的地址须相同 LCALL READEEPROMR ;以下为EEPROM读写操作验证 MOV A,WRITEdata MOV B,A MOV A,READDATA CJNE A,B,MAIN1 MOV P1,READDATA;写入数和读出数相等时,读出的数据在P1口输出并按位分别控制LED灯直观显示 sJMP $ MAIN1: MOV P1,#00H;写入数和读出数相等时,LED灯全亮 ;以下可接其它主程序,此处暂为死循环 SJMP $ ;--------------------------------------------------------------------------------------------------------------------- ;WRITEEEPROMR是随机写EEPROM(AT24C02)子程序 ;入口1:EEPROMADRESS(拟读写EEPROM存贮单元地址,00~FFH) ;入口2:WRITEDATA(拟写入EEPROM的字节数据在主机的存放地址)

51单片机中断程序大全

( //实例42:用定时器T0查询方式P2口8位控制LED闪烁 #include<> // 包含51单片机寄存器定义的头文件 void main(void) { // EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x01; //使用定时器T0的模式1 TH0=(65536-46083)/256; //定时器T0的高8位赋初值 : TL0=(65536-46083)%256; //定时器T0的高8位赋初值 TR0=1; //启动定时器T0 TF0=0; P2=0xff; while(1)//无限循环等待查询 { while(TF0==0) ; ] TF0=0; P2=~P2; TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值 //实例43:用定时器T1查询方式控制单片机发出1KHz音频 #include<> // 包含51单片机寄存器定义的头文件 sbit sound=P3^7; //将sound位定义为引脚 void main(void) ( {// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 TMOD=0x10; //使用定时器T1的模式1 TH1=(65536-921)/256; //定时器T1的高8位赋初值 TL1=(65536-921)%256; //定时器T1的高8位赋初值 TR1=1; //启动定时器T1 TF1=0; while(1)//无限循环等待查询 — { while(TF1==0); TF1=0;

IC读写EEPROM问题总结

I C读写E E P R O M问题 总结 文件管理序列号:[K8UY-K9IO69-O6M243-OL889-F88688]

2017年6月30日星期五 目的:利用TMS320F2801芯片上外设I2C(2线串口)读写EEPROM数据(24LC128) 关键点1:24LC时钟频率400KHz,寄存器设置如下: I2caRegs.I2CPSC.all = 9; // Prescaler - need 7-12 Mhz on module clk I2caRegs.I2CCLKL = 10; // NOTE: must be non zero I2caRegs.I2CCLKH = 5; // NOTE: must be non zero 时钟频率也可设为200KHz,三个参数分别为9、20、20(CPU时钟频率为100MHz)(未测试?) 关键点2:波形分析 问题:I2C模块是不是只有I2CCNT 减到0才会发出停止信号 I2C模块是硬件的,当检测到发送完了就会发结束自动发信号,不需要人为干预 问题1:字节写操作正常,但是字节读函数出错 原因:写EEPROM是在七位器件地址后添加写标志,而读EEPROM需要在七位器件地址后添加写标志。 关键点:读EEPROM数据需要发送两次命令。第一次为写地址(此地址会被赋值给EEPROM内的地址指针),因此需要添加写标志;第二次为读数据,将写标志改为读标志。

问题2:主机接收时,SDA数据线上有数据传输,且I2CDRR接收数据寄存器有数据更新,但寄存器显示不可读,即CPU认为一直没接收到数据,一直停在下面语句 while 关键点:初始化设置时采用的是FIFO接收方式,因此无效,应查询FIFO 接收中断位while方式查询位。 此位只有在非FIFO中断接收方式时才有效。 问题3:断续单字节读写正常,但是采用连续的单字节读写出错。 原因:EEPROM写过程的结束并不是I2C总线写结束就结束,实际上I2C 总线的写入数据先被保存到了EEPROM内部的缓冲区,当遇到I2C结束条件后,EEPROM才启动内部写过程,这个过程才是保存数据的过程。非常悲哀的是这个过程比较长,官方文档标注为5ms。如果在这5ms以内对EEPROM芯片访问将被忽略。 关键点:读写EEPROM应延时至少5ms,软件延时10ms do{}while(EEPROM_Timer <= 10); //10ms 问题4:查询EEPROM写过程是否结束造成死机,只能查询EEPROM读过程。 官方文档说EEPROM内部写周期最长为5ms,在很多情况下是远远低于 5ms的,为了节约时间,官方给出一个解决办法。当写周期完毕后就开始进行应答查询,来确定EEPROM写周期何时结束。所谓应答查询官方解释为:就是向EEPROM发送一个I2C起始条件后发送器件地址和一个读写标

51单片机外部中断实验

实验6 外部中断实验 (仿真部分) 一、实验目的 1. 学习外部中断技术的基本使用方法。 2. 学习中断处理程序的编程方法。 二、实验内容 在INT0和INT1上分别接了两个可回复式按钮,其中INT0上的按钮每按下一次则计数加一,其中INT1上的按钮每按下一次则计数减一。P1.0~ P1.3接LED灯,以显示计数信号。 三、实验说明 编写中断处理程序需要注意的问题是: 1.保护进入中断时的状态,并在退出中断之前恢复进入时的状态。 2.必须在中断处理程序中设定是否允许中断重入,即设置EX0位。 3.INT0和INT1分别接单次脉冲发生器。P1.0~ P1.3接LED灯,以查看计数信号. 四、硬件设计 利用以下元件:AT89C51、BOTTON、CAP、CAP-POL、CRYSTAL、RES、NOT、LED-Yellow。设计出如下的硬件电路。晶振频率为12MHz。 五、参考程序框图 设置P1.0~ 3初始状态

主程序框图 INT0中断处理程序框图 实验6 外部中断实验 (实验箱部分) 1.实验目的 认识中断的基本概念 学会外部中断的基本用法 学会asm和C51的中断编程方法 2.实验原理 图按键中断 【硬件接法】 控制LED,低电平点亮 INT1接按键,按下时产生低电平 【运行效果】 程序工作于中断方式,按下按键K2后,LED点亮,秒后自动熄灭。

8051单片机有/INT0和/INT1两条外部中断请求输入线,用于输入两个外部中断源的中断请求信号,并允许外部中断源以低电平或下降沿触发方式来输入中断请求信号。/INT0和/INT1中断的入口地址分别是0003H和0013H。 TCON寄存器(SFR地址:88H)中的IT0和IT1位分别决定/INT0和/INT1的触发方式,置位时为下降沿触发,清零时为低电平触发。实际应用时,如果外部的中断请求信号在产生后能够在较短时间内自动撤销,则可以选择低电平触发。在中断服务程序里要等待其变高后才能返回主程序,否则会再次触发中断,产生不必要的麻烦。 如果外部的中断请求信号产生后可能长时间后才能撤销,则为了避免在中断服务程序里长时间无谓等待,可以选择下降沿触发。下降沿触发是“一次性”的,每次中断只会有1个下降沿,因此中断处理程序执行完后可以立即返回主程序,而不必等待中断请求信号恢复为高电平,这是一个重要的技巧。 3. 实验步骤 参考实验例程,自己动手建立Keil C51工程。注意选择CPU类型。Philips半导体的P89V51RB2。 编辑源程序,编译生成HEX文件。 ISP下载开关扳到“00”,用Flash Magic软件下载程序HEX文件到MCU BANK1,运行。 运行Flash Magic软件。各步骤操作如下: Step 1: COM Port:选择实际使用的串行口,通常为COM1; Baud Rate:波特率不可设置得过高,推荐用9600; Device:请选择正确的型号89V51RB2; Interface:选择None(ISP)。 Step 2:请勾中“Erase blocks used by Hex File”。 Step 3:装入你的程序文件,注意必须为HEX格式。 Step 4: 请勾中“Verify after programming”(编程后校验); 对其它几项如果不了解,请不要勾中。 Step 5: 请先给电路板上电,同时按住复位键不松手,然后点击Flash Magic软件的“Start”按

IIC读写EEPROM

u32 ulTimeOut_Time; /* ******************************************************************************* ************************** * I2C_EE_WriteStr() * * Description : 将一个数据块写入EEPROM 的指定的地址 * * Argument(s) : xChip - 从器件地址 * xAddr - EEPROM存储空间地址 * xpBuf - 数据缓冲区指针 * xLen - 数据长度 * * Return(s) : none. * * Caller(s) : Application. * * Note(s) : (1) *------------------------------------------------------------------------------------------------------- * Modified by : * Modified date : * Description : *------------------------------------------------------------------------------------------------------- ******************************************************************************* ************************** */ void I2C_EE_WriteStr(u8 xChip, u16 xAddr, u8 *xpBuf, u16 xLen) { u8 *pbuf; u8 err; u8 retry; u16 addr; u16 len; // pbuf = xpBuf; addr = xAddr; len = xLen; I2C_EE_Drv_BusEn(); // 允许总线,写允许

相关主题
文本预览
相关文档 最新文档