STM32 对W25Q64的操作过程

#include "includes.h"
/*
W25Q64
8M×Ö½Ú
128¿é
ÿ¿éÊÇ64K
ÿ¿éÓÖÓÐ16¸öÉÈÇø
ÿ¸öÉÈÇø4k
ÿ¸öÉÈÇø·ÖΪ16Ò³
1Ò³ÊÇ256¸ö×Ö½Ú
8M = 128*64K= 2048*4K = 2048*16*256byte
        ¿é       ÉÈÇø       Ò³
*/

/*
1.GPIO¿Ú³õʼ»¯
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
2.STM32 SPI¿ØÖÆÆ÷³õʼ»¯
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
*/
void FLASH_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
    //MOSI -- PB15 SCK -- PB13
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    //CS
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    //MISO
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    
    //SPIЭÒéµÄ³õʼ»¯
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2,&SPI_InitStructure);

    SPI_Cmd(SPI2,ENABLE);
}

/*
ͨ¹ýSPI·¢ËÍÊý¾Ý
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
ͨ¹ýSPI½ÓÊÜÊý¾Ý
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
ÅжϷ¢ËͼĴæÆ÷ÊÇ·ñ·¢Ëͳɹ¦
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1.µÈ´ý·¢ËÍÇøΪ¿Õ
2.
*/

u8 SPI2_Send_Receive_Byte(u8 data)
{
    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI2,data);
    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);
    return SPI_I2S_ReceiveData(SPI2);
}
//дʹÄÜ
void FLASH_WriteEnable(void)
{
  /*!< Select the FLASH: Chip Select low */
  FLASH_CS_LOW();

  /*!< Send "Write Enable" instruction */
  SPI2_Send_Receive_Byte(CMD_WRITE_ENABLE);

  /*!< Deselect the FLASH: Chip Select high */
  FLASH_CS_HIGH();
}
//ÅжÏFLASHÊÇ·ñBUSY
void FLASH_WaitForWriteEnd(void)
{
  uint8_t flashstatus = 0;

  /*!< Select the FLASH: Chip Select low */
  FLASH_CS_LOW();

  /*!< Send "Read Status Register" instruction */
  SPI2_Send_Receive_Byte(CMD_READ_REGISTER1);

  /*!< Loop as long as the memory is busy with a write cycle */
  do
  {
    /*!< Send a dummy byte to generate the clock needed by the FLASH
    and put the value of the status register in FLASH_Status variable */
    flashstatus = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);

  }
  while ((flashstatus & 0x01) == SET); /* Write in progress */

  /*!< Deselect the FLASH: Chip Select high */
  FLASH_CS_HIGH();
}
/*
ÍùFLASHÖÐдÊý¾Ý£¨Ð´Ò»´ÎµÄÊý¾Ý´óСΪСÓÚ256£©
1.ÅжÏFLASHÊÇ·ñ´¦ÓÚæ״̬ 1 æ  0 ²»Ã¦
2.дʹÄÜ
3.ƬѡCSÀ­µÍ
4.·¢ËÍдÃüÁî
5.·¢ËÍ24λµØÖ·
6.ÍùSPIÖÐдСÓÚ4K³¤¶ÈµÄÊý¾Ý
7.CSÀ­¸ß
8.ÅжÏFLASH״̬ÊÇ·ñæ
*/
void FLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
  /*!< Enable the write access to the FLASH */
  FLASH_WriteEnable();

  /*!< Select the FLASH: Chip Select low */
  FLASH_CS_LOW();
  /*!< Send "Write to Memory " instruction */
  SPI2_Send_Receive_Byte(CMD_PAGE_PROGRAM);
  /*!< Send WriteAddr high nibble address byte to write to */
  SPI2_Send_Receive_Byte((WriteAddr & 0xFF0000) >> 16);
  /*!< Send WriteAddr medium nibble address byte to write to */
  SPI2_Send_Receive_Byte((WriteAddr & 0xFF00) >> 8);
  /*!< Send WriteAddr low nibble address byte to write to */
  SPI2_Send_Receive_Byte(WriteAddr & 0xFF);

  /*!< while there is data to be written on the FLASH */
  while (NumByteToWrite--)
  {
    /*!< Send the current byte */
    SPI2_Send_Receive_Byte(*pBuffer);
    /*!< Point on the next byte to be written */
    pBuffer++;
  }

  /*!< Deselect the FLASH: Chip Select high */
  FLASH_CS_HIGH();

  /*!< Wait the end of Flash writing */
  FLASH_WaitForWriteEnd();
}

//ÏòFLASHÖз¢ËÍbufferµÄÊý¾Ý
void FLASH_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
  uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;

  Addr = WriteAddr % FLASH_SPI_PAGESIZE;//´ú±í´ÓÒ»Ò³ÖÐÄĸöµØÖ·¿ªÊ¼Ð´Êý¾Ý
  count = FLASH_SPI_PAGESIZE - Addr;//´ú±í¸ÃÒ³»¹¿ÉÒÔд¶àÉÙÊý¾Ý
  NumOfPage =  NumByteToWrite / FLASH_SPI_PAGESIZE;//´ú±íÒª´æÈëµÄÊý¾Ý³¤¶È¿ÉÒÔд¶àÉÙÒ³
  NumOfSingle = NumByteToWrite % FLASH_SPI_PAGESIZE;//´ú±í³ýÁËÕûÒ³Êý¾ÝÍ⣬»¹¿ÉÒÔдµÄÊý¾Ý³¤¶È

  if (Addr == 0) /*!< WriteAddr is sFLASH_PAGESIZE aligned  */
  {
    if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
    {
      FLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
    }
    else /*!< NumByteToWrite > sFLASH_PAGESIZE */
    {
      while(NumOfPage--)
      {
        FLASH_WritePage(pBuffer, WriteAddr, FLASH_SPI_PAGESIZE);
        WriteAddr +=  FLASH_SPI_PAGESIZE;
        pBuffer += FLASH_SPI_PAGESIZE;
      }
      FLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
    }
  }
  else /*!< WriteAddr is not sFLASH_PAGESIZE aligned  */
  {
    if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
    {
      if (NumOfSingle > count) /*!< (NumByteToWrite + WriteAddr) > sFLASH_PAGESIZE */
      {
        temp = NumOfSingle - count;

        FLASH_WritePage(pBuffer, WriteAddr, count);
        WriteAddr +=  count;
        pBuffer += count;

        FLASH_WritePage(pBuffer, WriteAddr, temp);
      }
      else
      {
        FLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
      }
    }
    else /*!< NumByteToWrite > sFLASH_PAGESIZE */
    {
      NumByteToWrite -= count;
      NumOfPage =  NumByteToWrite / FLASH_SPI_PAGESIZE;
      NumOfSingle = NumByteToWrite % FLASH_SPI_PAGESIZE;

      FLASH_WritePage(pBuffer, WriteAddr, count);
      WriteAddr +=  count;
      pBuffer += count;

      while (NumOfPage--)
      {
        FLASH_WritePage(pBuffer, WriteAddr, FLASH_SPI_PAGESIZE);
        WriteAddr +=  FLASH_SPI_PAGESIZE;
        pBuffer += FLASH_SPI_PAGESIZE;
      }

      if (NumOfSingle != 0)
      {
        FLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
      }
    }
  }
}
//´ÓFLASHÖжÁÊý¾Ý
void FLASH_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
  /*!< Select the FLASH: Chip Select low */
  FLASH_CS_LOW();

  /*!< Send "Read from Memory " instruction */
  SPI2_Send_Receive_Byte(CMD_READ_DATA);

  /*!< Send ReadAddr high nibble address byte to read from */
  SPI2_Send_Receive_Byte((ReadAddr & 0xFF0000) >> 16);
  /*!< Send ReadAddr medium nibble address byte to read from */
  SPI2_Send_Receive_Byte((ReadAddr& 0xFF00) >> 8);
  /*!< Send ReadAddr low nibble address byte to read from */
  SPI2_Send_Receive_Byte(ReadAddr & 0xFF);

  while (NumByteToRead--) /*!< while there is data to be read */
  {
    /*!< Read a byte from the FLASH */
    *pBuffer = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);
    /*!< Point to the next location where the byte read will be saved */
    pBuffer++;
  }

  /*!< Deselect the FLASH: Chip Select high */
  FLASH_CS_HIGH();
}

//¶ÁID
uint32_t FLASH_ReadID(void)
{
  uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;

  /*!< Select the FLASH: Chip Select low */
  FLASH_CS_LOW();

  /*!< Send "RDID " instruction */
  SPI2_Send_Receive_Byte(CMD_READ_ID);

  /*!< Read a byte from the FLASH */
  Temp0 = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);

  /*!< Read a byte from the FLASH */
  Temp1 = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);

  /*!< Read a byte from the FLASH */
  Temp2 = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);

  /*!< Deselect the FLASH: Chip Select high */
  FLASH_CS_HIGH();

  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;

  return Temp;
}
//ÉÈÇø²Á³ý
void FLASH_EraseSector(uint32_t SectorAddr)
{
  /*!< Send write enable instruction */
  FLASH_WriteEnable();

  /*!< Sector Erase */
  /*!< Select the FLASH: Chip Select low */
  FLASH_CS_LOW();
  /*!< Send Sector Erase instruction */
  SPI2_Send_Receive_Byte(CMD_SECTOR_ERASE);
  /*!< Send SectorAddr high nibble address byte */
  SPI2_Send_Receive_Byte((SectorAddr & 0xFF0000) >> 16);
  /*!< Send SectorAddr medium nibble address byte */
  SPI2_Send_Receive_Byte((SectorAddr & 0xFF00) >> 8);
  /*!< Send SectorAddr low nibble address byte */
  SPI2_Send_Receive_Byte(SectorAddr & 0xFF);
  /*!< Deselect the FLASH: Chip Select high */
  FLASH_CS_HIGH();

  /*!< Wait the end of Flash writing */
  FLASH_WaitForWriteEnd();
}

u8 flash_buffer[256] = "i love you my girl -- hl\n\r";
void Test_Flash(void)
{
    u32 i;
    u32 flash_ID;
    u8 flash_flag = 0;
//    DMA_Start(26);
    do
    {
        if(flash_flag)
        {
            printf("¶ÁÈ¡µ½µÄID²»ÕýÈ·!\n\r");
            Delay_ms(500);
        }
        flash_ID = FLASH_ReadID();
        printf("%x\n\r",flash_ID);
        flash_flag = 1;
    }while(flash_ID != FLASH_W25Q64_ID);
    FLASH_EraseSector(0x645000);
//    DMA_Start(26);
    for(i=0;i<256;i++)
    {
        flash_buffer[i] = i;
    }
    printf("¿ªÊ¼Ð´FLASH\n\r");
    printf("ÕýÔÚд¡­¡­\n\r");
    FLASH_WritePage(flash_buffer,0x645500,256);
    printf("д³É¹¦£¡\n\r");
    Clear_buffer(flash_buffer);
    printf("¿ªÊ¼¶ÁFLASH\n\r");
    printf("ÕýÔÚ¶Á¡­¡­\n\r");

    FLASH_ReadBuffer(flash_buffer,0x645505,10);
    
    printf("¶Á³É¹¦\n\r");
    Display_buffer(flash_buffer);
//    DMA_Start(256);
}


void Clear_buffer(u8 *buffer)
{
    u32 i = 0;
    for(i=0;i<256;i++)
    {
        buffer[i] = 0;
    }
}

void Display_buffer(u8 *buffer)
{
    u32 i,j;
    for(i=0;i<16;i++)
    {
        for(j=0;j<16;j++)
        {
            printf("%x\t",*buffer++);
        }
        printf("\n\r");
    }
}





 

你可能感兴趣的:(STM32 对W25Q64的操作过程)