STM32驱动W24Q16

W24Q16FLASH存储芯片,容量为16Mbit。注意是16Mbit,其实就是2M-byteW24Q16采用的是spi总线。但是这个spi总线有三种方式。

首先列下该芯片的管脚图:

clip_image001clip_image003

第一种是标准spiStandard)。即传统的四根线,CS片选信号,clk时钟信号,DI数据输入信号,DO数据输出信号。这个时候,WPHOLD有自己的功能。

第二种是双SPI模式(Dual SPI)。这个时候还是用到4根线,CS片选信号,clk时钟信号,不过这里的DIDO变成双向的IO线了,即用到了IO1IO2。这个时候,WPHOLD还是有自己的功能。

第三种是四SPI模式(Quad SPI)。这个时候会用到6根线,即所有信号线都使用了。CS片选信号,clk时钟信号,这个还是一样,不过变化的是,数据线用到了4个,IO0-IO3。所以这个时候,WPHOLD本身的功能就没有了。

 

看看这三种模式的传输有什么区别。

其实三个都是用的SPI协议,即首先要CS片选有效,然后在clk的时钟下,发送数据和接收数据,不同的只是信号线的使用。

看看时序图,以读数据为例

第一种

clip_image005

第二种

clip_image007

第三种:

clip_image009

从时序图,就可以看出区别了吧。

在读数据的时候,发命令和发地址都是一样的,都是DI这个管脚接收。但是在读数据的时候,就不一样了。

对于第一种,只有DO一个管脚输出,所以需要8个时钟周期输出一个字节的值。

对于第二种,有两个管脚输出,所以只需要4个时钟周期就输出一个字节的值,

对于第三种,就更快了,有4个管脚,所以只需要两个时钟周期就输出一个字节的值。

 

所以,看出,其实就是读取数据的快慢而已,同样的时间下,第三种读取最快。但是用的管脚多,第一种最慢,但是用的管脚少。至于命令,地址,这些都是一样的。

 

写数据也是差不多的。 

 

看看芯片的内存地址是怎么排布的。

在芯片中,最大的单位是块,然后是扇区,最后是页。

看图:

clip_image011

这图就说明很清楚了,

一个块64KB,包括16个扇区,而一个扇区是4KB大。一个扇区又包括16页。而一个页是256字节大。

为什么要定义这么复杂的结构,那是为了以后的操作使用。这个讲到指令的时候就知道了。

 

然后就是芯片的内部寄存器。芯片有两个内部寄存器,这两个内部寄存器记录了一些信息。

clip_image013

第一个寄存器,

0位:记录了芯片是否忙状态。因为在写入数据和擦除数据的时候,是需要时间的。你不能在上一个数据还没有写成功之前,又马上写入下一个数据。所以这个位就指示了,现在是否在写状态,如果为1的话,说明,现在还在写,所以在这个时候就不能写入数据。为0的话,说明现在芯片空闲,可以写入数据了。

1位:指示是否可写。该芯片是有保护数据功能的,即写数据不能你想写就能写。你必须要这位为1,指示芯片可写,然后才能写入数据。否则芯片是不响应你写数据的命令的。所以在写入数据和擦除数据之前,需要把这位给置1。另外还要注意的是:每当写完数据或者擦除数据后,该位会自动为0。即变成不可写。所以在每次写之前都要将这位置1.而不能就初始化的时候置1就行了。否则会发现,只写了一次数据,后面在写数据就不行了。

7-2位和寄存器2的第0位:这几位是指示保护的。上面的写保护,是保护数据不能随意更改,如果要写入数据的话,必须要将写保护取消。而这里的几位,是指示在写数据的过程,哪些位置的数据是要保护的,不允许更改的。因为有时候,需要某一部分的数据需要保持不变,写数据或者擦除的时候忽略这一部分。这个就干这个功能的。具体看看数据手册就知道了,很简单的。

第二个寄存器

1位:这个事用来指示现在的操作是否是第三种SPI模式。1的话,是第三种SPI模式,否则不是。

这里为什么只有指示第三种模式,而没有指示第二种模式了,因为第二种模式其实是在第一种模式的变形,所以是通过不同的命令来实现的。

 

下面就是重要的命令了。

我们知道,对于SPI协议来说,第一个数据,肯定是命令,表示你要对芯片进行什么操作。所以一切的操作都是基于命令的。

这个芯片的命令特别多:

首先是读器件的一些信息的命令。

clip_image015

通过上面这些命令,可以读出器件的一些信息。

 

下面才是重点了

clip_image017

看上面的,命令是不是特别多。

第一个命令:写使能,这个就是之前说的,将内部寄存器位1的值给置1,使能写数据或者擦除数据。

第二个命令,写取消。这个看名字就知道了,将内部寄存器位1的值给置0,禁止写数据和擦除数据。

第三个命令:读状态寄存器1的值。刚刚说了,内部有两个状态寄存器,这里是读取第一个。发完命令后读取的第一个字节值就是寄存器数据。

第四个命令:读状态寄存器2的值。这里是读取第二个。发完命令后读取的第一个字节值就是寄存器数据。

第五个命令:写状态寄存器。这里就是写那两个状态寄存器的值。配置芯片的工作模式。发完命令后接着发送写入的值。不过注意寄存器的顺序。

第六个命令:页写入。FLASH和一般的存储芯片不一样,是不能随意写的,是要按页写的,即从页的首地址开始写。不能从其他位置写。写入的数据最多是256字节。超过256字节,就把超过的数据从页的首地址从新开始写。而且,在写数据之前,是要将写数据的地方给擦除的。即只有擦除过的地方,写的数据才正确,没有擦除过的地方,写的数据就不正确。因为页地址是256字节。所以这里的命令后面跟着的3个字节的地址,对256取余是要为0的。即页对齐。

第七个命令: SPI方式页写入。和页写入一样的,只是数据由4根线传输。

8-11命令:是擦除数据命令。这里就可以看出,为什么之前看到的芯片的地址那么复杂,需要块,扇区,页。就是方便擦写的。因为在写数据之前,是要擦写数据的。那么怎么擦写,这就是关键了。这里从命令可以看出,配置了4种擦写。后面跟着的就是擦写的地址。

后面的命令就不介绍了。

 

然后是读命令了

clip_image019

这里读命令,就分有哪种SPI模式读了。这个也很简单,就不介绍了。

 

以上的dummy,是说明,这个数据是什么不重要。一般设为0xff

 

搞定了这些基础知识后,编程那就很简单了。

首先是封装stm32自带的spi库函数。封装为发一个数据,同时把数据读取回来。但是要注意库函数是只有标准SPI模式的。如果要用两种模式的话,需要自己写了。

uint8_t spi_write_byte(uint8_t data)

{

   while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);

   SPI_I2S_SendData(SPI1,data);

   while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET);

   return SPI_I2S_ReceiveData(SPI1);

}

代码如上,就是调用了stm32SPI库函数。发送的是data值,函数返回读取的值。

 

剩下的就是封装命令,写数据,读数据就可以了。代码这里就不介绍了。因为最低层的SPI发送函数已经写好了,上层就只要不断的调用这个函数就行了。

 

 

 

 

此条目发表在ARM嵌入式, STM32分类目录,贴了, 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。