华邦W25Q16存储器颗粒SPI编程_第1页
华邦W25Q16存储器颗粒SPI编程_第2页
华邦W25Q16存储器颗粒SPI编程_第3页
华邦W25Q16存储器颗粒SPI编程_第4页
华邦W25Q16存储器颗粒SPI编程_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

-.z.华邦W25Q16存储器颗粒SPI编程W25*16、W25*32和W25*64系列FLASH存储器可以为用户提供存储解决方案,具有“PCB板占用空间少〞、“引脚数量少〞、“功耗低〞等特点。与普通串行FLASH相比,使用更灵活,性能更出色。它非常适合做代码下载应用,例如存储声音,文本和数据。工作电压在2.7V-3.6V之间,正常工作状态下电流消耗0.5毫安,掉电状态下电流消耗1微安。所有的封装都是"节省空间"型的。W25*16、W25*32和W25*64分别有8192、16384和32768可编程页,每页256字节。用"页编程指令"每次就可以编程256个字节。用"扇区(sector)擦除指令"每次可以擦除16页,用“块(block)擦除指令〞每次可以擦除256页,用“整片擦除指令〞即可以擦除整个芯片。W25*16、W25*32和W25*64分别有512、1024和2048个可擦除"扇区"或32、64和128个可擦除“块〞。W25*16、W25*32和W25*64支持标准的SPI接口,传输速率最大75MHz。四线制:①:串行时钟引脚CLK;②:芯片选择引脚CS;③:串行数据输出引脚DO;④:串行数据输入输出引脚DIO。(注意:第④引脚“串行数据输入输出引脚DIO〞的解释:在普通情况下,这根引脚是“串行输入引脚(DI),当使用了快读双输出指令(FastReadDualOutputinstruction)时,这根引脚就变成了DO引脚,这种情况下,芯片就有了两个DO引脚了,所以叫做双输出,这时,如果与芯片通信的速率相当于翻了一倍,所以传输速度更快。)另外,芯片还具有保持引脚(HOLD)、写保护引脚(WP)、可编程写保护位(位于状态存放器bit1)、顶部和底部块的控制等特征,使得控制芯片更具灵活性。芯片支持JEDEC工业标准。引脚排布:原理图:控制和状态存放器说明S7S6S5S4S3S2S1S0SPRd)TBP2P1P0ELBY通过"读状态存放器指令"读出的状态数据可以知道芯片存储器阵列是否可写或不可写,或是否处于写保护状态。通过"写状态存放器指令"可以配置芯片写保护特征。状态存放器:忙位(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、写使能时序图〔指令:0*06〕:“写使能〞指令将会使“状态存放器〞WEL位置位。在执行每个“页编程〞、“扇区擦除〞、“块区擦除〞、“芯片擦除〞、和“写状态存放器〞命令之前,都要先置位WEL。/CS引脚先拉低之后,“写使能〞指令代码06h从DI引脚输入,在CLK上升沿采集,然后再拉高/CS引脚。程序设计流程:使能片选位,拉低CS引脚;CLK起始状态或高电平或低平,配置数据采集从CLK第一个上升沿开场;等待发送缓冲区是否为空,SPI_SR的T*E位;将数据赋值给SPI_DR存放器;等待接收缓冲区是否为空,SPI_SR的R*NE位;返回接收到的数据;禁能片选位,拉高CS引脚。例程:unsignedcharSPI_SendByte(unsignedcharbyte){while(!(SPI_SR&0*02)); //等待发送缓冲区为空SPI_DR=byte; //送值到数据存放器whlie(!(SPI_SR&0*01)); //等待接收缓冲区为空returnSPI_DR; //返回接收的容}unsignedcharSPI_WriteEnable(){Flash_CS=0; //使能CS引脚SPI_SendByte(0*06) //写使能指令Flash_CS=1; //禁能片选引脚}2、写禁能时序图〔指令:0*04〕:“写能〞指将使EL位变为0。CS脚低之,把04h从DO脚送芯片之,拉高CS就完了这指令在执完“写状存放器〞、“编程〞扇擦除〞、“块擦芯擦指令后EL位会动为0。程序设计流程:使能片选位,拉低CS引脚;CLK起始状态或高电平或低平,配置数据采集从CLK第一个上升沿开场;等待发送缓冲区是否为空,SPI_SR的T*E位;将数据赋值给SPI_DR存放器;等待接收缓冲区是否为空,SPI_SR的R*NE位;返回接收到的数据;禁能片选位,拉高CS引脚。例程:unsignedcharSPI_SendByte(unsignedcharbyte){Flash_CS=0; //使能CS引脚while(!(SPI_SR&0*02)); //等待发送缓冲区为空SPI_DR=byte; //送值到数据存放器whlie(!(SPI_SR&0*01)); //等待接收缓冲区为空returnSPI_DR; //返回接收的容Flash_CS=1; //禁能片选引脚}unsignedcharSPI_WriteEnable(){Flash_CS=0; //使能CS引脚SPI_SendByte(0*04) //写禁能指令Flash_CS=1; //禁能片选引脚}3、读状态时序〔指令:0*05〕:当CS拉之把5h从DO脚到片在CK的上升沿据片采,当芯认采到数时05h时芯就状态值从O引脚出数据在CK的下降沿出位在。“读态令任何候可用甚在编擦和写态器程中也以,样就以从态的UY位判编、除写态存放器期有没完毕而我知道片否以收一条令果S拉高状存放器值一从O脚输。S高后读指完毕。程序设计流程:使能片选,拉低CS引脚;发送读取指令0*04; 循环发送读伪指令0*FF,等待非忙时跳出循环; 禁能片选,拉高CS引脚。例程:voidSPI_ReadStatus(){unsignedcharFlash_Status;FLASH_CS=0; //使能片选引脚SPI_SendByte(0*05); //发送读状态指令do{Flash_Status=SPI_SendByte(0*FF); //发送伪指令维持时钟等待非空跳出循环,伪指令任意写。}while(!(Flash_Status&0*01));FLASH_CS=1; //禁能片选引脚}4、写状态时序〔指令:0*01〕在执行“写状态存放器〞指令之前,需要先执行“写使能〞指令。先拉低/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引脚拉低,就可以实现制止写入状态存放器的功能。程序设计流程:使能片选,CS引脚拉低;发送写状态指令0*01;发送读取指令0*04禁能片选,CS引脚拉高。例程:voidSPI_FLASH_WriteStatus(){FLASH_CS=0; //使能片选引脚SPI_SendByte(0*06); //写使能指令SPI_SendByte(0*01); //写状态指令SPI_SendByte(0*00); //写入状态的数据FLASH_CS=1; //禁能片选引脚}5、读数据时序图〔指令:0*03〕:“读数据〞指令允许读出一个字节或一个以上的字节被读出。先把/CS引脚拉低,然后把03h通过DIO引脚送到芯片,之后再送入24位的地址,这些数据在CLK的上升沿被芯片采集。芯片接收完24位地址之后,就会把相应地址的数据在CLK引脚的下降沿从DO引脚送出去,高位在前。当读完这个地址的数据之后,地址自动增加,然后通过DO引脚把下一个地址的数据送出去,形成一个数据流。也就是说,只要时钟在工作,通过一条读指令,就可以把整个芯片存储区的数据读出来。把/CS引脚拉高,“读数据〞指令完毕。当芯片在执行编程、擦除和读状态存放器指令的周期,“读数据〞指令不起作用。程序设计流程〔指令:0*03〕:使能片选,拉低CS引脚;发送读数据指令0*03,紧接着发送24位地址;读以SPI_DR存放器数据禁能片选,拉高CS引脚例程:voidSPI_FLASH_BufferRead(unsignedchar*pBuffer,unsignedintReadAddr,unsignedlongintNumByteToRead){FLASH_CS=0; //拉低片选线选中芯片SPI_SendByte(READ);//发送读数据命令SPI_SendByte((ReadAddr&0*FF0000)>>16); //发送24位FLASH地址,先发高8位SPI_SendByte((ReadAddr&0*00FF00)>>8); //再发中间8位SPI_SendByte(ReadAddr&0*0000FF); //最后发低8位while(NumByteToRead--)//计数{*pBuffer=SPI_SendByte(Dummy_Byte); //读一个字节的数据pBuffer++; //指向下一个要读取的数据}FLASH_CS=1; //拉高片选线不选中芯片}6、快读时序图〔指令:0*0B〕:“快读〞指令和“读数据〞指令很相似,不过,“快读〞指令可以运行在更高的传输速率下。先把/CS引脚拉低,然后把0Bh通过引脚DIO送到芯片,然后把24位地址通过DIO引脚送到芯片,接着等待8个时钟,之后数据将会从DO引脚送出去。程序设计流程〔指令:0*0B〕:使能片选,拉低CS引脚;发送快读数据指令0*0B,紧接着发送24位地址;发送8个字节伪指令等待8个时钟读以SPI_DR存放器数据禁能片选,拉高CS引脚例程:voidSPI_FLASH_BufferRead(unsignedchar*pBuffer,unsignedintReadAddr,unsignedlongintNumByteToRead){FLASH_CS=0; //拉低片选线选中芯片SPI_SendByte(READ);//发送读数据命令SPI_SendByte((ReadAddr&0*FF0000)>>16); //发送24位FLASH地址,先发高8位SPI_SendByte((ReadAddr&0*00FF00)>>8); //再发中间8位SPI_SendByte(ReadAddr&0*0000FF); //最后发低8位SPI_SendByte(0*FF); //发送8个字节伪指令,等待8个时钟。while(NumByteToRead--) //计数{*pBuffer=SPI_SendByte(Dummy_Byte); //发送伪指令读出一个字节的数据pBuffer++; //指向下一个要读取的数据} FLASH_CS=1; //拉高片选线不选中芯片}7、快速读双输出〔指令:0*3B〕:“快读双输出〞指令和“快读〞指令很相似,不过,“快读双输出〞指令是从两个引脚上输出数据:DI和DIO。这样,传输速率就相当于两倍于标准的SP看传输速率了。这个指令特别适合于需要在一上电就把代码从芯片下载到存中的情况或者缓存代码段到存中运行的情况。“快读双输出〞指令和“快读〞指令的时序差不多。先把/CS引脚拉低,然后把3Bh通过引脚DIO送到芯片,然后把24位地址通过DIO引脚送到芯片,接着等待8个时钟,之后数据将会分别从DO引脚和DIO引脚送出去,DIO送偶数位,DO送寄数位。程序设计流程:使能片选,拉低CS引脚;写快读双输出指令0*3B,紧接着写24位地址;写1个字节的伪指令,等待8个时钟;读取SPI_DR存放器禁能片选,拉高CS引脚例程〔参考完整例程〕:暂无。8、页编程时序图〔指令:0*02〕:执行“页编程〞指令之前,需要先执行“写使能〞指令,而且要求待写入的区域位都为1,也就是需要先把待写入的区域擦除。先把/CS引脚拉低,然后把代码02h通过DIO引脚送到芯片,然后再把24位地址送到芯片,然后接着送要写的字节到芯片。在写完数据之后,把/CS引脚拉高。写完一页(256个字节)之后,必须把地址改为0,不然的话,如果时钟还在继续,地址将自动变为页的开场地址。在*些时候,需要写入的字节缺乏256个字节的话,其它写入的字节都是无意义的。如果写入的字节大于了256个字节,多余的字节将会加上无用的字节覆盖刚刚写入的的256个字节。所以需要保证写入的字节小于等于256个字节。在指令执行过程中,用“读状态存放器〞可以发现BUSY位为1,当指令执行完毕,BUSY位自动变为0。如果需要写入的地址处于“写保护〞状态,“页编程〞指令无效。程序设计流程:写使能指令0*06,将芯片WEL位置0;擦除芯片需要写入的区域,可以用扇区、块、芯片擦除指令;使能片选,拉低CS引脚;发送“页编程〞指令0*02,接着发送24位地址、发送要写入的数据;发读状态指令0*05检查芯片BUSY位操作是否完毕禁能片选,拉高CS引脚。例程:voidSPI_FLASH_PageWrite(unsignedchar*pBuffer,unsignedlongintWriteAddr,unsignedintNumByteToWrite){SPI_FLASH_WriteEnable(); //先使能对FLASH芯片的操作FLASH_CS=0; //拉低片选线选中芯片SPI_SendByte(WRITE);//发送页写命令SPI_SendByte((WriteAddr&0*FF0000)>>16); //发送24位FLASH地址,先发高8位SPI_SendByte((WriteAddr&0*FF00)>>8); //再发中间8位SPI_SendByte(WriteAddr&0*FF); //最后发低8位while(NumByteToWrite--) //发送地址后紧跟欲写入数据{SPI_SendByte(*pBuffer); //发送欲写入FLASH的数据pBuffer++; //指向下一个要写入的数据}FLASH_CS=1; //拉高片选线不选中芯片SPI_FLASH_WaitForWriteEnd(); //等待写操作完毕}程序说明:*pBuffer是一个指针,是读取数据后的存储区,通常指向一个数组;WriteAddr是24位芯片地址,需要把数据写到芯片什么位置就靠它了。NumByteToWrite是写入字节的数量,例如需要写入50个字节,这里就给50。写入的数据不可以大于256Byte,否则页地址会溢出,地址会从0开场,最前面写入的数据会被破坏,写入的数据大于256Byte时,重新用下一页的起始地址来写剩余的数据〔处理翻页问题请在本章末尾查看完整例程〕。页编程完整流程图:W25Q16总共有16Mbit空间,合计2MByte,共8192个页,每页256Byte。因为每页是一个独立的单元,所以在写入数据时不支持自动翻页,如果写入的数据超出256Byte,则页地址就溢出归零,数据又从零开场写,也就是说最先写入的数据会被破坏。数据写入时可能碰到有几种情况,一种情况是:页地址对齐的情况,就是页地址可以被256整除,且写入的数据不够256Byte,这种情况直接写入即可,不需要考虑翻页问题;第二种情况是:写入的数据刚好是256Byte或者多一点点,这种情况写完一整页的数据后,就要把页地址加256跳到下一页的开场位置写剩余的数据;第三种情况是:页地址不对齐情况,也就是页地址不能被256整除,这种情况说明,*页被用掉一局部,现在从剩余的空间继续向下写,如果空间够写就直接写入,不需要考虑翻页问题,如果空间不够写就要将页地址加上剩余空间的数跳转到下一页写剩余的数据,如果剩余的数据等于或大于256Byte,页地址还需要加256再向下进展翻页。9、扇区擦除时序图〔指令:0*20〕:“扇区擦除〞指令将一个扇区C4K字节)擦除,擦除后扇区位都为1,扇区字节都为FFh。在执行“扇区擦除〞指令之前,需要先执行“写使能〞指令,保证WEL位为1。先拉低属CS引脚,然后把指令代码20h通过DIO引脚送到芯片,然后接着把24位扇区地址送到芯片,然后拉高属CS引脚。如果没有及时把属CS引脚拉高,指令将不会起作用。在指令执行期间,BUSY位为1,可以通过“读状态存放器〞指令观察。当指令执行完毕,BUSY位变为0,WEL位也会变为0。如果需要擦除的地址处于只读状态,指令将不会起作用。程序设计流程:先执行写使能指令;使能片选,拉低CS引脚;发送扇区擦除指令0*20,紧接着发送擦除的24位地址;等待擦除指令完毕,发送读状态指令查看BUSY位状态是否为0;禁能片选,拉高CS引脚。例程:voidSPI_FLASH_BlockErase(unsignedlongintBlockAddr){SPI_FLASH_WriteEnable(); //FLASH写使能〔该函数请查阅完整例程〕FLASH_CS=0; //拉低片选线选中芯片SPI_SendByte(0*D8); //发送块或扇区〔0*20〕擦除命令 SPI_SendByte((BlockAddr&0*FF0000)>>16);//发送24位FLASH擦除地址,先发高8位SPI_SendByte((BlockAddr&0*00FF00)>>8); //再发中间8位SPI_SendByte(BlockAddr&0*0000FF); //最后发低8位FLASH_CS=1; //拉高片选线不选中芯片SPI_FLASH_WaitForWriteEnd(); //等待块去除操作完成〔该函数请查阅完整例程〕}10、芯片擦除时序图〔指令:0*C7〕:“芯片擦除〞指令将会使整个芯片的存储区位都变为1,即字节都变位FFh。在执行“芯片擦除〞指令之前需要先执行"写使能"指令。先把/CS引脚拉低,然后再把指令代码C7h通过DIO引脚送到芯片,然后拉高/CS引脚。如果没有及时拉高/CS引脚,指令无效。在“芯片擦除〞指令执行周期,可以执行“读状态存放器〞指令访问BUSY位,这时BUSY位为1,当“芯片擦除〞指令执行完毕,BUSY变为0,WEL位也变为0。任何一个块区处于保护状态(BP2\BP1\BP0),指令都会失效。程序设计流程:发送0*06写使能;使能片选,拉低CS引脚;发送擦除指令0*C7,紧接着发送24位擦除地址;禁能片选,拉高CS引脚等待操作完成。例程:voidSPI_FLASH_ChipErase(void){SPI_FLASH_WriteEnable(); //FLASH写使能FLASH_CS=0; //拉低片选线选中芯片SPI_SendByte(Chip_E); //发送芯片擦除命令FLASH_CS=1; //拉高片选线不选中芯片SPI_FLASH_WaitForWriteEnd(); //等待写操作完成}11、“释放掉电/器件ID〞指令〔命令:0*AB〕:这个指令有两个作用。一个是“释放掉电〞,一个是读出“器件ID〞。当只需要发挥“释放掉电〞用途时,指令时序是:先把/CS引脚拉低,然后把代码“ABh〞通过DIO引脚送到芯片,然后拉高/CS引脚。然后经过tRES1时间间隔,芯片恢复正常工作状态。在编程、擦除和写状态存放器指令执行周期,执行该指令无效。程序设计流程:暂无例程:暂无12、掉电指令(指令:0*B9):尽管在待机状态下的电流消耗己经很低了,但“掉电〞指令可以使得待机电流消耗更低。这个指令很适合在电池供电的场合。先把属CS引脚拉低,然后把指令代码

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论