PIC单片机与串行闪存的SPI接口设计

引 言
pic单片机以性能稳定、品种众多等特点在工业控制、仪器仪表、家电、通信等领域得到广泛应用。虽然很多型号自身集成了存储器,但在很多情况下难以满足系统对大容量存储的要求,需要外扩非易失性的存储器。与并行flash存储器相比,串行flash存储器占用mcu引脚少,体积小,易于扩展,接线简单,工作可靠,故而越来越多地应用在各类电子产品和工业测控系统中。本文主要讨论pic16f877a单片机与串行闪存m25p16之间的spi通信,在要求大容量数据存储且mcu引脚资源有限的情况下具有实用价值。
1 spi工作原理
spi(serial peripheral interface)是一种常用的串行通信协议,用于mcu系统与外围设备的通信,可用来连接存储器、a/d转换器、d/a转换器、实时时钟、lcd驱动器、传感器,甚至其他处理器。spi主要使用4个信号:mosi(主机输出/从机输人)、miso(主机输入/从机输出)、sck(串行时钟)和cs(片选)。其中,sck由主机产生,作为传输的同步时钟,控制所有数据传输。主机通过触发从设备的cs决定二者之间的spi传输是否能够进行。主机和外设都包含1个串行移位寄存器。主机通过向自己的spi串行寄存器写入1个字节来发起1次传输,然后通过mosi信号线将数据传给外设,同时外设将自己移位寄存器中的内容通过miso信号线返回给主机,如图1所示。这样,两个移位寄存器中的内容就交换了。也就是说,外设的写操作和读操作是同步完成的。在实际应用中,如果只进行写操作,则主机只需忽略收到的字节即可;如果主机要读外设的数据,必须发送1个字节来引发从机的传输,发送的这个字节可以是任意数据。
2 m25p16简介
m25p16是16 mb的串行闪存,具有先进的写保护机制,支持速度高达50 mhz的spi总线的存取操作。该存储器有32个扇区,每个扇区256页,每页256字节。工作电压范围2.7~3.6 v,工作温度范围-40~+85℃。数据保存长达20年,每个扇区可擦写/编程100 000次。
m25p16支持的操作指令共有12条。指令格式为:
其中,8位的命令字是必需的,地址、哑元以及数据字节的有无和长度会因指令的不同而有所差别,详情如表1所列。所有的命令码、地址、串行输入/输出的数据,均是高位在前,低位在后。
对m25p16操作时,先选中芯片(即片选信号s拉低),然后串行输入操作指令字节,紧接着串行输入地址字节(0或3字节),必要时还要加入哑读字节,最后串行输入/输出数据字节,然后把片选信号拉高,之后m25p16启动内部控制逻辑,自行完成相应的操作。
3 spi硬件设计
pic16f877a单片机具有非常完善的spi接口(rc3/sck、rc4/sdi、rc5/sdo、ra5/ss),只有pic16f877a作为从机时,ra5/ss引脚才作为spi脚,pic16f877a为主机时,ss可作为普通i/o使用。通过该接口,可比较容易地实现pic16f877a与spi flash的通信。pic16f877a与m25p16的硬件接口如图2所示。其中,sck、sdi、sdo为mcu的spi专用引脚,分别与存储器的对应引脚相连,可选mcu的任意i/o脚作为存储器的片选信号,图中选取rc2脚与存储器的片选s相连,这样,在spi通信时只涉及mcu的c口,便于操作。m25p16的hold和w直接接高电平,表示不允许在s有效的情况下暂停spi通信且整个存储区都没有写保护。
图2中,vdd为+5 v,由于pic16f877a工作在5 v电压下,而m25p16的工作电压范围为2.7~3.6 v,二者不能直接相连。这里采用电阻分压的方式,保证输入m25p16的s、c、d脚的电压在存储器能承受且能识别的范围内,通过在m25p16向pic16f877a输入数据的sdo脚加上拉电阻,保证mcu可以识别m25p16输出的高电压,从而保证正常的spi通信。如果mcu工作于3.3 v,则直接将二者的对应引脚相连即可。
4 spi软件设计
在硬件连线正确的基础上,要进行spi通信,还要对m25p16编写驱动程序,包括spi初始化、读m25p16的数据、向m25p16写人数据、数据的擦除等,这里使用c语言编程,编译器选择picc,开发环境为mplab ide8.10。
pic16f877a的spi通信涉及4个寄存器:控制寄存器sspcon、状态寄存器sspstat串行接收/发送缓冲器sspbuf和移位寄存器sspsr。其中,sspcon的8位都是可读可写的,用于设置ssp处于主/从模式、时钟频率、时钟极性、ssp使能以及写冲突检测;sspstat只有高2位可读写,低6位是只读的。pic16f877a处于接收模式时,sspsr和sspbuf构成2级缓冲的接收器,sspsr每收到1个完整的字节,就将该字节传给sspbuf,并将中断标志位sspif置1,可通过读sspbuf得到数据;877a处于发送模式时,写sspbuf操作会同时将数据写入sspsr,触发传输。下面结合具体的代码进行详细阐述。
(1)spi初始化与读写函数
从sendbyte和rcvbyte函数的代码中,可以看出数据发送和接收是否完成,都是通过判断stat_bf标志位(sspstat寄存器的bf位,stat_bf是在头文件pic1687x.h中定义的名称)来实现的,而数据手册中关于bf位的描述仅用于接收模式。这是由于pic16f877a通过sdo发送数据的同时,会通过sdi读人数据,当1字节发送完成时,刚好接收1字节到sspbuf,这时sspbuf满,by被置为1,故可通过stat_bf标志判断1字节是否发送完成。
(2)连续写函数
m25p16的pp指令允许1次连续写入不超过1页(256字节)的数据。写人数据之前,首先要发出写允许命令,然后才能执行数据写入操作。数据写入函数参数包括address(32位地址)、block(写入数据缓冲区指针)、n(一次连续写入的字节数,n<256)。如果address的低8位不全为0,即不是从页起始处写,并且需要写入的数据超出该页剩余空间,则超出部分被丢弃。代码如下:
其中,delay()为延时子函数,参数为ms级,delay(1)即延时1ms。加入延时,是为了保证存储器在准备好的情况下才进行读写操作。
(3)连续读函数
m25p16允许发出读指令后,连续读取数据,这一模式极大提高了总线效率。数据读取函数的参数包括address:32位地址;block:读数据缓冲区指针;n:一次连续读取的字节数,代码如下:
m25p16的连续读操作与连续写不同的是,无论read还是fast_read,在起始地址处1字节的数据读出后,会自动寻址更高地址处的数据,故程序中无需address++语句。
除了对m25p16的初始化、读写之外,经常还要对其进行擦除操作,擦除有扇区擦除和整体擦除2种方式,执行数据擦除将使内部所有数据变为ffh。擦除操作与写操作类似,在此不再赘述。
结 语
本文介绍的m25p16与pic16f877a的接口已应用于自来水流量数据采集的本地存储中。运行稳定可靠,未发现数据丢失现象,对其他应用有一定的参考价值。

人工智能系统对甲状腺病灶检出率高达98%
赛灵思AI方案三大重点
AR技术将成为汽车制造商的下一个关注点吗
运放稳定性问题简析
伺服电机规格选用步骤
PIC单片机与串行闪存的SPI接口设计
Epic和苹果的战局进一步扩大
Keil MDK下的NOR Flash下载算法
监控摄像机如何保证家庭的安全
打击盗窃行为出新招,苹果新专利远程操控被盗智能设备“变砖”
新唐科技W567C120控制器介绍
pcb单层板、双层板、四层板、六层板、八层板、十层板、十二层板图文解释
大功率升压转换器可自动切换模式并保持轻负载效率
传统产业数字化转型升级亟待进一步提速 疫情进一步刺激企业审视自身数字化水平
富士康在天津成立新公司,拓展车用领域布局
有保障的虚拟货币投资不再只是理想 - 马来西亚发起的新募资模式ACO(合格通证发行)
使用MAX6951/MAX6950 LED显示驱动器与MAXQ2000微控制器通信
开放式FPGA实现仪器的各种特性
长虹陷“增收不增利”怪圈 电视业务不足营收五分之一
英特尔酷睿十一代+惠普战66,商务办公新利器