zoukankan      html  css  js  c++  java
  • stm32之W25Q

       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";   //发送的内容
      uint8_t Rx_Buffer[64];      //接收的内容
      __IO uint32_t FlashID = 0;            //ID地址

    ·(1)读ID ---FlashID = sFLASH_ReadID();

     (2)判断ID是否正确if (FlashID == sFLASH_W25Q16_ID)

     (3)正确的话;printf("ID 正确 ");

     (4)擦除的内存空间0x00001364

      /* Erase SPI FLASH Sector to write on */
       sFLASH_EraseSector(0x00001364);

     (5)写数据

      /* Write Tx_Buffer data to SPI FLASH memory */
      sFLASH_WriteBuffer(Tx_Buffer, 0x032100, sizeof(Tx_Buffer));
      printf("tx_buff =%s ",Tx_Buffer);

     (6)读数据

      /* Read data from SPI FLASH memory */
      sFLASH_ReadBuffer(Rx_Buffer, 0x032100, sizeof(Tx_Buffer));
      printf("rx_buff =%s ",Rx_Buffer);

      (7)ID不正确的话:printf("验证ID失败 ");

    .........无论是读还是写操作,都是先进行busy判断在进行片选拉高,busy的判断在判断写完成函数里sFLASH_WaitForWriteEnd();,但是在有的函数里会出现

        

     这样可以理解为两个函数可以合并成一个,其过程也可以这样理解:就是先拉低选择芯片,写入数据,拉高芯片,在查询芯片的状态,拉低,查看busy,在拉高
       

    二。指令

      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 */
                sFLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
                /*!< Send SectorAddr medium nibble address byte */
                sFLASH_SendByte((SectorAddr & 0xFF00) >> 8);

                /*!< Send SectorAddr low nibble address byte */
                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 */
        sFLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
        /*!< Send WriteAddr medium nibble address byte to write to */
        sFLASH_SendByte((WriteAddr & 0xFF00) >> 8);
        /*!< Send WriteAddr low nibble address byte to write to */
        sFLASH_SendByte(WriteAddr & 0xFF);

      (5)判断写的数据大小-----状态位:

        while (NumByteToWrite--)    //NumByteToWrite--这个是写的字节数,有多少个数据写入
        {
          /*!< Send the current byte */
          sFLASH_SendByte(*pBuffer);
          /*!< Point on the next byte to be written */
          pBuffer++;
        }

      (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 */
        sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
        /*!< Send ReadAddr medium nibble address byte to read from */
        sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
        /*!< Send ReadAddr low nibble address byte to read from */
        sFLASH_SendByte(ReadAddr & 0xFF);

      (//判断busy位)

      (4)判断要读的数据大小: while (NumByteToRead--)//判断busy位

      (5)while里读数据位

          /*!< Read a byte from the FLASH */
          *pBuffer = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
          /*!< Point to the next location where the byte read will be saved */
          pBuffer++;

      (6)片选拉高

  • 相关阅读:
    网页HTML到8.20前
    数据库SQLServer
    构建之法读后感
    VS2013 生成安装文件
    工大助手(自动化部署)
    工大助手(用户名、密码错误提示)
    工大助手(验证码错误提示)
    工大助手(加权成绩计算)
    Wireshark插件编写
    微软认知服务——人脸识别
  • 原文地址:https://www.cnblogs.com/juan-4-14/p/12701616.html
Copyright © 2011-2022 走看看