你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32之W25Q

[复制链接]
STMCU小助手 发布时间:2022-2-4 22:00
  W25Q是一款flash存储芯片。可以进行写数据、读数据、擦除。通过通信接口与MCU进行通信。其片选引脚,低电平有效
  其使用配合着SPI使用--可以单独配置spi底层函数,读取数据函数,也可以使用W25Q提供的stm32_eval_spi_flash.c里void sFLASH_Init(void)初始化配置。
其特点是:先擦除后写入。
  存储芯片大小:16M-bit  --2M Byte
    1页           --256字节
  1个扇区---16页        ---4K
  1块       ----16个扇区 --64K
  一个芯片 --32块      --2M
如何从一个字节空间存一个数据:第1块中第一个扇区的第一页第100个字节写一个数:0xAA
               0000 0000 0KKK KKKK SSSS PPPP BBBB BBBB
               0x0      0  0      1     1    64
                0x00001364 
MCU通过SPI给W25Q发送指令
  2.WQ25的编写---可以直接引用该芯片本身写好的程序---比如stm32_eval_spi_flash.c
  uint8_t Tx_Buffer[] = "I Love China";   //发送的内容
: u4 @8 m7 R" ]) w2 z0 x: Y8 o  uint8_t Rx_Buffer[64];      //接收的内容( K  ]& t+ q1 t6 F; K8 T0 a) w
  __IO uint32_t FlashID = 0;            //ID地址
·(1)读ID ---FlashID = sFLASH_ReadID();
(2)判断ID是否正确if (FlashID == sFLASH_W25Q16_ID)
(3)正确的话;printf("ID 正确\r\n");
(4)擦除的内存空间0x00001364
  /* Erase SPI FLASH Sector to write on */' K0 Y# e( W+ t4 B5 a
  sFLASH_EraseSector(0x00001364);
(5)写数据
  /* Write Tx_Buffer data to SPI FLASH memory */9 [4 G& t, y2 F4 i
  sFLASH_WriteBuffer(Tx_Buffer, 0x032100, sizeof(Tx_Buffer));) k& S: Z1 j; s
  printf("tx_buff =%s\r\n",Tx_Buffer);
(6)读数据
  /* Read data from SPI FLASH memory */
: }2 l( Y: n7 L1 F  sFLASH_ReadBuffer(Rx_Buffer, 0x032100, sizeof(Tx_Buffer));5 Q* s+ n3 ?- ?! u/ O" }" k
  printf("rx_buff =%s\r\n",Rx_Buffer);
  (7)ID不正确的话:printf("验证ID失败\r\n");
.........无论是读还是写操作,都是先进行busy判断在进行片选拉高,busy的判断在判断写完成函数里sFLASH_WaitForWriteEnd();,但是在有的函数里会出现
   1979749-20200528152851231-1027233621.png   

  T& T; y/ `7 c& G) G
这样可以理解为两个函数可以合并成一个,其过程也可以这样理解:就是先拉低选择芯片,写入数据,拉高芯片,在查询芯片的状态,拉低,查看busy,在拉高% r+ T8 z# B- a5 n" k
   
1979749-20200528153235235-1416712899.png
5 j0 n/ F( \% i3 T. T2 V% @9 E  k7 E( u8 T: P
7 [( v+ B! P3 h& E1 @% ]5 j& B$ ?
二。指令
  1.读ID
  (1)片选拉低: sFLASH_CS_LOW();
  (2)发送读ID指令:sFLASH_SendByte(0x9F);
  (3)发送数据: Temp0 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
  (4)片选拉高:sFLASH_CS_HIGH();
  (5)返回读的值:Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
  2.扇区擦除
  (1)发送写使能指令:sFLASH_WriteEnable();//写使能
  (2)片选拉低
  (3)发送扇区擦除指令:sFLASH_SendByte(0x20);
  (4)发送扇区擦除地址:
            /*!< Send SectorAddr high nibble address byte */! X' }4 z8 M- g( O8 S  j
            sFLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
" ~% o9 s6 c9 Z- Y% |) Z/ o2 D            /*!< Send SectorAddr medium nibble address byte */% [: y, p: s' X% ^0 j7 I4 E! r( c" t2 I
            sFLASH_SendByte((SectorAddr & 0xFF00) >> 8);
            /*!< Send SectorAddr low nibble address byte */
- D/ @1 ?7 p9 b2 d            sFLASH_SendByte(SectorAddr & 0xFF);
  (判断busy位)
  (5)片选拉高
  (6)等待写完成:sFLASH_WaitForWriteEnd();//里面含有判断busy,写入数据是需要时间的,W25Q通过busy的进行判断是否写完的
   3.写操作-------1~256字节空间--页编程
  (1)写使能:sFLASH_WriteEnable();
  (2)片选拉低
  (3)发送页写指令:sFLASH_SendByte(0x02);
  (4)发送页写地址--24位
    /*!< Send WriteAddr high nibble address byte to write to */, m; o% j* O3 \
    sFLASH_SendByte((WriteAddr & 0xFF0000) >> 16);2 @/ Z: y7 s9 G/ L4 b* b  x
    /*!< Send WriteAddr medium nibble address byte to write to */; X0 j/ K+ \. m/ a3 _$ [" `
    sFLASH_SendByte((WriteAddr & 0xFF00) >> 8);
  K, t$ R. U' O9 m' G* K% t3 n, |    /*!< Send WriteAddr low nibble address byte to write to */
- ~' \9 u4 q( {: ~+ N9 M    sFLASH_SendByte(WriteAddr & 0xFF);
  (5)判断写的数据大小-----状态位:
    while (NumByteToWrite--)    //NumByteToWrite--这个是写的字节数,有多少个数据写入
3 s9 l0 q0 |, e" X# \2 A7 F    {# m; ^: X! ~4 b5 @+ F
      /*!< Send the current byte */
7 K* y% O# h+ k; e7 x      sFLASH_SendByte(*pBuffer);
6 k3 n  u; `/ {1 K      /*!< Point on the next byte to be written */
: K. D8 _3 [4 D: ~      pBuffer++;. ?3 v/ j" `8 B2 a% e+ _
    }
  (6)片选拉高
  (5)等待写完成:sFLASH_WaitForWriteEnd();
  4.写操作---写buff
  (1)判断 Writedaddr 是 sflash pagesize 对齐
    if(Addr == 0)//页内地址
  (2)是的话,判断页数大小:if (NumOfPage == 0)
  (2.1)是的话:页编程
  (2.2)不是的话 ,while (NumOfPage--)->页编程sFLASH_WritePage(pBuffer, WriteAddr, sFLASH_SPI_PAGESIZE);--->WriteAddr += sFLASH_SPI_PAGESIZE;pBuffer += sFLASH_SPI_PAGESIZE;
  (3)不是的话,,类似
  5.读操作--读buff
  (1)片选拉低
  (2)发送读指令: sFLASH_SendByte(0x03);
  (3)发送读地址--24位:21位地址,3个字节
    /*!< Send ReadAddr high nibble address byte to read from */2 U6 h- k; I$ Q4 Z; L0 m4 Z* q
    sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);# H" e- [3 i7 _& O
    /*!< Send ReadAddr medium nibble address byte to read from */
/ v: P# E- t, J1 B, {    sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
! v" u8 B3 q% V2 c' N" F( Q: Q. I    /*!< Send ReadAddr low nibble address byte to read from */; }0 d% l9 M3 _7 \
    sFLASH_SendByte(ReadAddr & 0xFF);
  (//判断busy位)
  (4)判断要读的数据大小: while (NumByteToRead--)//判断busy位
  (5)while里读数据位
      /*!< Read a byte from the FLASH */& j0 K! l5 j! K5 t; r! u! Z
      *pBuffer = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
0 {! b, x  Z$ \8 u/ c  F% `      /*!< Point to the next location where the byte read will be saved */
3 G; L4 {. ?  S+ Y3 `) ~      pBuffer++;
  (6)片选拉高

" B  k- G) e& T' R
赞 收藏 评论0 发布时间:2022-2-4 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版