转载:W25Q64操作

发布时间 2023-11-13 09:51:02作者: okyihu

W25Q64

 

W25Q64

容量:总容量64Mbit    分为128Block (64KB/Block)  一个Block又分为16个Sector(4KB/Sector)一个Sector分为16个Page(256B/Page)

24位地址

最小擦除单元:Sector

连续写入最多一页数据,超过时回到页首覆盖写入,写入后芯片进入忙状态

SPI读写W25Q64函数

#include "main.h"
#include "W25Q64.h"
#include "spi.h"





#define S_Choose_W25Q64      HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET)
#define S_DeChoose_W25Q64    HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_SET)

/*SPI数据发送与接收*/
uint8_t S_W25Q64_Exchange_Data(uint8_t ByteSend)
{
    uint8_t GetByteSend = ByteSend;
    uint8_t ByteReceive;
    HAL_SPI_TransmitReceive(&hspi2,&GetByteSend,&ByteReceive,1,100);
    return ByteReceive;
}


/*读取芯片ID*/
void S_W25Q64_ReadID(uint8_t *MID,uint16_t *DID)
{
    S_Choose_W25Q64;
    S_W25Q64_Exchange_Data(0x9F);
    *MID = S_W25Q64_Exchange_Data(0xFF);
    *DID = S_W25Q64_Exchange_Data(0xFF);
    *DID <<= 8;
    *DID |= S_W25Q64_Exchange_Data(0xFF);
    S_DeChoose_W25Q64;
}
/*写使能*/
void S_W25Q64_WriteEnable(void)
{
    S_Choose_W25Q64;
    S_W25Q64_Exchange_Data(W25Q64_WRITE_ENABLE);
    S_DeChoose_W25Q64;
}
/*等待芯片忙状态结束*/
void S_W25Q64_WaitNoBusy(void)
{
    uint32_t TimeOut;
    S_Choose_W25Q64;
    S_W25Q64_Exchange_Data(W25Q64_READ_STATUS_REGISTER_1);
    TimeOut = 100000;
    //判断状态寄存器Busy位
    while((S_W25Q64_Exchange_Data(0xFF)&0x01) == 0x01)
    {
        TimeOut--;
        if(TimeOut <= 9)
        {
            break;
        }
    }
    S_DeChoose_W25Q64;
}
//写数据
void S_W25Q64_PageProgram(uint32_t Address,uint8_t *DataArray,uint16_t Count)
{
    S_W25Q64_WaitNoBusy();
    S_W25Q64_WriteEnable();
    S_Choose_W25Q64;
    uint16_t i = 0;
    S_W25Q64_Exchange_Data(W25Q64_PAGE_PROGRAM);
    S_W25Q64_Exchange_Data(Address >> 16);
    S_W25Q64_Exchange_Data(Address >> 8);
    S_W25Q64_Exchange_Data(Address >> 0);
    for(i = 0;i<Count;i++)
    {
        S_W25Q64_Exchange_Data(DataArray[i]);
    }
    S_DeChoose_W25Q64;
}

//擦除数据
void S_W25Q64_SectorErase(uint32_t Address)
{
    S_W25Q64_WaitNoBusy();
    S_W25Q64_WriteEnable();
    S_Choose_W25Q64;

    S_W25Q64_Exchange_Data(W25Q64_SECTOR_ERASE_4KB);
    S_W25Q64_Exchange_Data(Address >> 16);
    S_W25Q64_Exchange_Data(Address >> 8);
    S_W25Q64_Exchange_Data(Address >> 0);

    S_DeChoose_W25Q64;

}


//读数据
void S_W25Q64_ReadData(uint32_t Address,uint8_t *DataArray,uint16_t Count)
{
    S_W25Q64_WaitNoBusy();
    S_Choose_W25Q64;
    uint16_t i = 0;
    S_W25Q64_Exchange_Data(W25Q64_READ_DATA);
    S_W25Q64_Exchange_Data(Address >> 16);
    S_W25Q64_Exchange_Data(Address >> 8);
    S_W25Q64_Exchange_Data(Address >> 0);
    for(i = 0;i<Count;i++)
    {
        DataArray[i] = S_W25Q64_Exchange_Data(0xFF);
    }
    S_DeChoose_W25Q64;
}

函数测试

/*读取ID*/
  uint8_t MID;
  uint16_t DID;
  S_W25Q64_ReadID(&MID,&DID);
  HAL_UART_Transmit(&huart2,&MID,1,1000);
  uint8_t DID0 = DID;
  uint8_t DID1 = DID>>8;
  HAL_UART_Transmit(&huart2,&DID1,1,1000);
  HAL_UART_Transmit(&huart2,&DID0,1,1000);
  
  HAL_Delay(20);
 /*写入数据*/
  uint8_t ArrayOrigin[]={0x01,0x03,0x05};
  uint8_t ArrayDestination[3] = {0};
  S_W25Q64_SectorErase(0x000000);
  S_W25Q64_PageProgram(0x000000,ArrayOrigin,3);
  S_W25Q64_ReadData(0x000000,ArrayDestination,3);
  HAL_UART_Transmit(&huart2,ArrayDestination,3,1000);

测试结果