
华邦W25Q16存储器颗粒SPI编程2.docx
29页华邦W25Q16存储器颗粒SPI编程2引脚排布:原理图:控制和状态寄存器阐明S7S6S5S4S3S2S1S0SRP(Reservd)TBBP2BP1BP0WELBUSY通过"读状态寄存器指令"读出的状态数据可以懂得芯片存储器阵列与否可写或不可写,或与否处在写保护状态通过"写状态寄存器指令"可以配备芯片写保护特性状态寄存器:忙位(BUSY)BUSY 位是个只读位,位于状态寄存器中的 S0当器件在执行"页编程"、"扇区擦除"、 "块区擦除"、"芯片擦除"、"写状态寄存器"指令时,该位自动置 1这时,除了"读状态寄 存器"指令,其他指令部忽视当编程、擦除和写状态寄存器指令执行完毕之后,该位自动 变为 0,表达芯片可以接受其他指令了写保护位(WEL)WEL 位是个只读位,位于状态寄存器中的 S1执行完"写使能"指令后,该位置 1 当芯片处在"写保护状态"下,该位为0在下面两种状况下,会进入"写保护状态" • 掉电后• 执行如下指令后写禁能、页编程、扇区擦除、块区擦除、芯片擦除和写状态寄存器块区保护位(BP2,BP1,BP0)BP2\BP1\BP0 位是可读可写位,分别位于状态寄存器的 S4\S3\S2。
可以用"写状态寄存器"命令置位这些块区保护位在默认状态下,这些位都为 0,即块区处在未保护状态下 可以设立块区没有保护、部分保护或者是所有处在保护状态下当 SPR 位为 1 或/WP 引脚 为低的时候,这些位不可以被更改底部和顶部块区保护位(TB)TB 位是可读可写位,位于状态寄存器的 S5该位默觉得 0,表白顶部和底部块区处在未被保护状态下可以用"写状态寄存器"命令置位该位当 SPR 位为 1 或/WP 引脚为低 的时候,这些位不可以被更改保存位状态寄存器的 S6 为保存位,读出状态寄存器值时,该位为 0建议读状态寄存器值用于测试时将该位屏蔽状态寄存器果护位(SRP)SRP 位是可读可写位,位于状态寄存器的 S7该位结合/WP 引脚可以实现禁能写状态寄存器功能该位默认值为 0当 SRP 位=0 时,/WP 引脚不能控制状态寄存器的"写禁能"当 SRP 位=1,/WP 引脚=0 时,"写状态寄存器"命令失效当 SRP 位=1,/WP 引脚=1 时,可以执行"写状态寄存器"命令状态寄存器存储保护模块:1、写使能时序图(指令:0x06):“写使能”指令将会使“状态寄存器”WEL位置位在执行每个“页编程”、“扇区擦除”、“块区擦除”、“芯片擦除”、和“写状态寄存器”命令之前,都要先置位 WEL。
/CS 引脚先拉低之后,“写使能”指令代码06h 从DI引脚输入,在CLK 上升沿采集,然后再拉高/CS 引脚 程序设计流程:1、 使能片选位,拉低CS引脚;2、 CLK起始状态或高电平或低平,配备数据采集从CLK第一种上升沿开始;3、 等待发送缓冲区与否为空,SPI_SR的TXE位;4、 将数据赋值给SPI_DR寄存器;5、 等待接受缓冲区与否为空,SPI_SR的RXNE位;6、 返回接受到的数据;7、 禁能片选位,拉高CS引脚例程:unsigned char SPI_SendByte(unsigned char byte){while(!(SPI_SR&0x02)); //等待发送缓冲区为空SPI_DR=byte; //送值到数据寄存器whlie(!(SPI_SR&0x01)); //等待接受缓冲区为空return SPI_DR; //返回接受的内容}unsigned char SPI_WriteEnable(){Flash_CS=0; //使能CS引脚SPI_SendByte(0x06) //写使能指令Flash_CS=1; //禁能片选引脚}2、写禁能时序图(指令:0x04):“写禁能”指令将会使WEL位变为0。
/CS引脚拉低之后,把04h 从DIO引脚送到芯片之后,拉高/CS,就完毕了这个指令在执行完“写状态寄存器”、“页编程”、“ 扇区擦除”、“块区擦除”、“芯片擦除”指令之后,WEL位就会自动变为0程序设计流程:1、 使能片选位,拉低CS引脚;2、 CLK起始状态或高电平或低平,配备数据采集从CLK第一种上升沿开始;3、 等待发送缓冲区与否为空,SPI_SR的TXE位;4、 将数据赋值给SPI_DR寄存器;5、 等待接受缓冲区与否为空,SPI_SR的RXNE位;6、 返回接受到的数据;7、 禁能片选位,拉高CS引脚例程:unsigned char SPI_SendByte(unsigned char byte){Flash_CS=0; //使能CS引脚while(!(SPI_SR&0x02)); //等待发送缓冲区为空SPI_DR=byte; //送值到数据寄存器whlie(!(SPI_SR&0x01)); //等待接受缓冲区为空return SPI_DR; //返回接受的内容Flash_CS=1; //禁能片选引脚}unsigned char SPI_WriteEnable(){Flash_CS=0; //使能CS引脚SPI_SendByte(0x04) //写禁能指令Flash_CS=1; //禁能片选引脚}3、读状态时序(指令:0x05):当/CS 拉低之后,开始把 05h 从DIO引脚送到芯片,在 CLK 的上升沿数据被芯片采集,当芯片认出采集到的数据时05h 时,芯片就会把“状态寄存器”的值从DO引脚输出,数据在CLK 的下降沿输出,高位在前。
读状态寄存器”指令在任何时候都可以用,甚至在编程、擦除和写状态寄存器的过程中也可以用,这样,就可以从状态寄存器的BUSY位判断编程、擦除和写状态寄存器周期有无结束,从而让我们懂得芯片与否可以接受下一条指令了如果/CS 不被拉高,状态寄存器的值将始终从DO引脚输出/CS 拉高之后,读指令结束程序设计流程:1、 使能片选,拉低CS引脚; 2、 发送读取指令0x04; 3、 循环发送读伪指令0xFF,等待非忙时跳出循环; 4、 禁能片选,拉高CS引脚例程:void SPI_ReadStatus(){unsigned char Flash_Status;FLASH_CS=0; //使能片选引脚SPI_SendByte(0x05); //发送读状态指令do{Flash_Status=SPI_SendByte(0xFF); //发送伪指令维持时钟等待非空跳出循环,伪指令任意写}while(!(Flash_Status&0x01));FLASH_CS=1; //禁能片选引脚}4、写状态时序(指令:0x01)在执行“写状态寄存器”指令之前,需要先执行“写使能”指令。
先拉低/CS 引脚,然 后把 01h 从 DIO 引脚送到芯片,然后再把你想要设立的状态寄存器值通过 DIO 引脚送到芯 片,拉高/CS 引脚,指令结束,如果此时没有把/CS 引脚拉高,或者是拉的晚了,值将不会 被写入,指令无效只有“状态寄存器”当中的“SRP、TB、BP2、BP1、BP0 位”可以被写入,其他“只读位”值不会变在该指令执行的过程中,状态寄存器中的 BUSY 位为 1,这时候可以用“读状态寄存器”指令读出状态寄存器的值判断,当指令执行完毕,BUSY 位将自动变为 0, WEL位也自动变为 0通过对“TB”、“BP2”、“BP1”、“BP0”位写 1,就可以实现将芯片的部分或所有存储区域 设立为只读通过对“SRP 位”写 1,再把/WP引脚拉低,就可以实现严禁写入状态寄存器的功能程序设计流程:1、 使能片选,CS引脚拉低;2、 发送写状态指令0x01;3、 发送读取指令0x044、 禁能片选,CS引脚拉高例程:void SPI_FLASH_WriteStatus(){FLASH_CS=0; //使能片选引脚SPI_SendByte(0x06); //写使能指令SPI_SendByte(0x01); //写状态指令SPI_SendByte(0x00); //写入状态的数据FLASH_CS=1; //禁能片选引脚}5、读数据时序图(指令:0x03):“读数据”指令容许读出一种字节或一种以上的字节被读出。
先把/CS 引脚拉低,然后把03h通过DIO引脚送到芯片,之后再送入24位的地址,这些数据在CLK的上升沿被芯片采集芯片接受完24位地址之后,就会把相应地址的数据在 CLK 引脚的下降沿从 DO 引脚送出去,高位在前当读完这个地址的数据之后,地址自动增长,然后通过DO引脚把下一种地址的数据送出去,形成一种数据流也就是说,只要时钟在工作,通过一条读指令,就可 以把整个芯片存储区的数据读出来把/CS 引脚拉高,“读数据”指令结束当芯片在执行编程、擦除和读状态寄存器指令的周期内,“读数据”指令不起作用程序设计流程(指令:0x03):1、 使能片选,拉低CS引脚;2、 发送读数据指令0x03,紧接着发送24位地址; 3、 读以SPI_DR寄存器数据4、 禁能片选,拉高CS引脚例程:void SPI_FLASH_BufferRead(unsigned char* pBuffer, unsigned int ReadAddr, unsigned long int NumByteToRead){ FLASH_CS=0; //拉低片选线选中芯片 SPI_SendByte(READ);//发送读数据命令 SPI_SendByte((ReadAddr & 0xFF0000)>>16); //发送24位FLASH地址,先发高8位 SPI_SendByte((ReadAddr & 0x00FF00)>>8); //再发中间8位 SPI_SendByte(ReadAddr &0x0000FF); //最后发低8位 while(NumByteToRead--)//计数 { *pBuffer = SPI_SendByte(Dummy_Byte); //读一种字节的数据 pBuffer++; //指向下一种要读取的数据 } FLASH_CS=1; //拉高片选线不选中芯片}6、快读时序图(指令:0x0B):“快读”指令和“读数据”指令很相似,但是,“快读”指令可以运营在更高的传播速率下。
先把/CS 引脚拉低,然后把 0Bh 通过引脚 DIO 送到芯片,然后把 24 位地址通过 DIO 引脚送到芯片,接着等待8个时钟,之后数据将会从 DO 引脚送出去程序设计流程(指令:0x0B):1、 使能片选,拉低CS引脚;2、 发送快读数据指令0x0B,紧接着发送24位地址; 3、 发送8个字节伪指令等待8个时钟4、 读以SPI_DR寄存器数据5、 禁能片选,拉高CS引脚例程:void SPI_FLASH_BufferRead(unsig。
