1 概述
Flash存储器可分为串行和并行两类。Flash大多数存储器使用I2C接口或SPI读写界面;并行Flash与存储器相比,引脚少,体积小,易于扩展,与单片机或控制器连接简单,工作可靠,因此串行Flash存储器越来越多地用于各种电子产品和工业测控系统。
DataFlash是美国Atmel公司新推出的大容量串行Flash采用存储产品NOR可用于存储数据或程序代码的技术制造,其产品型号为AT45DBxxxx。该系列存储容量较大,从1Mb~256Mb;封装尺寸小,包装型号最小(CBGA)尺寸为6mm×8mm;采用SPI读写界面,硬件连接少;内页尺寸小,8Mb页面尺寸为264字节,16Mb和32Mb页面尺寸为512字节,64Mb页面尺寸为1056字节,128Mb容量和256Mb容量的页面尺寸为 2112字节。另外,AT45DBxxxx两个与主存页面相同大小的系列存储器集成在一起SRAM缓存大大提高了整个系统的灵活性,简化了数据的读写过程。另外,AT45DBxxxx两个与主存页面相同大小的系列存储器集成在一起SRAM缓存大大提高了整个系统的灵活性,简化了数据的读写过程。AT45DBxxxx系列存储器工作电压低,只需2.7~3.6V;整个芯片的功耗也很小,典型的读取电流是4mA,待机电流仅为2μA。所有这些特性使该系列的存储器非常适合构成微、低功耗的测控系统。笔者就使用 AT45DB161B存储器和PIC16LC73B单片机和微压传感器由两个按钮电池驱动,其形状尺寸仅为φ10mm×20mm。
2 芯片简介
2.1 引脚排列及功能
AT45DB161B为DataFlash单片容量为16的中档产品Mb。引脚排列如图1所示,引脚功能如表1所示。 表1 AT45DB161B引脚功能
引脚名称 功能描述
CS 片选
SCK 串行时钟
SI 串行输入
SO 串行输出
WP 页面写保护
RESET 复位
RDY/BUSY 准备好/忙
NC 未使用
2.2 芯片内部逻辑结构
AT45DB161B的内部逻辑结构分为三个部分:存储器页阵列(主存)、缓存与I/O接口。 AT45DB161B存储页面大小为528字节,整个存储器分为 4096页,两个528字节集成在电影中SRAM缓存,内部逻辑结构如图2所示。
3 存储器读写接口
3.1 SPI接口及操作模式
AT45DB161B存储器采用SPI读写界面。SPI接口是与外部设备一起使用的通用串行接口总线,字长为8位EEPROM、A/D通信转换器等)。SPI接口利用SCK、SI和SO数据读写三条线。其中,SCK时钟信号,SI和SO数据输入输出线。 AT45DB161B的SCK引脚时钟信号必须由外部单片机或控制器输入,读写命令字由SI引脚输入,数据由SO引脚输出。
SPI界面有0、1、2、3四种操作模式。SPI操作模式决定了设备接收和发送数据时的时钟相位和极性,即时钟信号沿数据流行方向的上下关系,如图3所示。
DataFlash只支持使用最广泛的系列存储器SPI模式0和3。SCK沿触发数据输入和沿触发数据输出下降。两者的区别在于SCK信号的起始电平不同。
3.2 存储器命令接口和状态机
除基本存储单元外,DataFlash还包括命令用户接口CUI(Command User Interface)和状态机。CUI接收用户软件的操作命令,将其翻译成状态机的内部操作代码,并检查命令的有效性。状态机控制存储器的所有内部操作,包括8位状态寄存器(status register),用于指示设备的操作状态。将状态寄存器命令输入到存储器中,可以从最高水平依次读取状态寄存器的数据。状态寄存器的意义如表2所列。 表2 定义状态寄存器
位7 位6 位5 位4 位3
准备好/忙 比较 容 量
位2 位1 位0
将来使用
3.3 存储操作命令及其模式
为了使存储器进行所需的操作,如阅读、写作、擦除等,必须从SI引脚输入相应的操作命令,然后从SO或SI读取或写入引脚数据。除读取状态寄存器命令外,所有命令格式为:1字节操作码 三字节地址码。操作代码指示所需的操作,DataFlash用于搜索存储器页阵列或缓存的系列节地址码。图4为 AT45DB161B阅读/写命令格式。
4 存储器与单片机接口的实例
4.1 硬件电路
DataFlash系列存储器几乎可以和任何类型的单片机接口,无论单片机是否有SPI接口。当然,如果单片机有SPI接口,那么存储器读/写程序就相对简单些;如果单片机没有SPI接口,则可以用软件仿真SPI接口与存储器通信。
图5为微型压力测量系统的一部分。存储器采用 AT45DB161B-TC,TSOD封装;单片机为美国 Microchip公司的PIC16LC73B-04/SS,SSOP封装。单片机采用软件仿真SPI接口的方式与存储器通信,存储器工作于SPI模式0。
4.2 AT45DB161B存储器读/写子程序
DataFlash系列存储器可以按地址从低到高顺序读写,也可以随机读写任一字节的数据。对于顺序读数据,可以使用连续读主存页阵列命令(操作码68H或E8H)从给定的起始地址开始连续读出,中间不需用户干预,也可使用读单页主存命令(操作码52H或D2H),自行提供页地址读取数据。对于顺序写数据,可以使用通过缓存写主存页命令(操作码82H或85H),直接将数据写入主存;也可以先使用写缓存命令(操作码84H或87H),将数据写入缓存,在适当的时刻再使用缓存写主存页命令(操作码83H或86H),将缓存中的数据写入主存,如图6所示。使用何种方式读写取决于特定的应用场合与要求。
下面的子程序为顺序读/写存储器的例子。子程序spiwt采用了通过缓存写主存页的方法,向存储器写入1字节数据。顺序读存储器子程序spicrd采用了边疆读主存页阵列命令。从给定地址处连续读出数据,用图5所示的PIC16LC73B单片机汇编语言编写,使用MPLAB5.4.00编译器编译通过并烧写入单片机,按图5所示系统实测通过。     ;顺序写子程序,用spiwt名称调用
spiwt bcf STATUS,RP0
bcf PORTB,SCK ;模式0
bcf PORTB,cs ;片选
movlw 82H ;加载操作码
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出操作码
movf PA1,w ;加载第一字节地址
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf BA1,w
xorwf PA2,w ;获得第二字节地址
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf BA2,w ;加载第三字节地址
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf spi_wt,w ;加载待写数据
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
bsf PORTB,cs ;触发写入操作
nop ;延时
retlw 0 ;从子程序返回
;输出子程序,用spiout名称调用
spiout movlw 0x08 ;加载输出位数
movwf spi_cnt ;置入寄存器
nspiout rlf spi_out ;先输出最高位
btfsc STATUS,C ;是否为1
bsf PORTB,SDO ;输出1
btfss STATUS,C ;是否为0
bcf PORTB,SDO ;输出0
nop ;延时
bsf PORTB,SCK ;时钟信号上升沿
nop ;延时
bcf PORTB,SCK ;时钟信号下降沿
decfsz spi_cnt ;检查输出位数
goto nspiout ;输出下一位
retlw 0 ;从子程序返回
;顺序读子程序,用名称spicrd调用
spicrd bcf STATUS,RP0
bcf PORTB,cs ;片选
bcf PORTB,SCK ;模式0
movlw E8H ;加载操作码
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf PA1,w ;加载第一字节地址
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf BA1,w
xorwf PA2,w ;获得第二字节地址
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf BA2,w ;加载第三字节地址
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf DCRE,w ;加载任意位字节
movwf spi_out ;置入寄存器
call spiout ;调用子程序输出
movf DCRE,w ;共需4个任意位字节
movwf spi_out
call spiout
movf DCRE,w
movwf spi_out
call spiout
movf DCRE,w
movwf spi_out
call spiout
retlw 0 ;从子程序返回