- #include "W25Q64.h"
- void W25Q64_Config(void)
- {
- W25Q64_CS_OUT_H();
- }
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] W25164C在发送数据的同时接收指定长度的数据
- * @param dat —— 接收数据缓冲区首地址
- * @param recv_buf —— 接收数据缓冲区首地址
- * @param —— 要发送/接收数据的字节数
- * @retval 成功返回HAL_OK
- */
- uint8_t SPI_FLASH_SendByte(uint8_t byte)
- {
- uint8_t recv_buf = 0;
- HAL_SPI_TransmitReceive(&hspi1, &byte, &recv_buf, 1, 10000);
- return recv_buf;
- }
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] 读取FLASH Device ID
- * @param 无
- * @retval FLASH Device ID
- */
- uint32_t SPI_FLASH_ReadDeviceID(void)
- {
- uint32_t flash_id;
- //使能W25Q64_CS,拉低CS
- W25Q64_CS_OUT_L();
- SPI_FLASH_SendByte(W25X_JedecDeviceID);
- //SPI_Receive(recv_buf,3);
-
- flash_id=SPI_FLASH_SendByte(Dummy_Byte);
- flash_id <<=8;
- flash_id|=SPI_FLASH_SendByte(Dummy_Byte);
- flash_id <<=8;
- flash_id|=SPI_FLASH_SendByte(Dummy_Byte);
-
- //W25Q64_CS,拉高CS
- W25Q64_CS_OUT_H();
- return flash_id;
- }
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] 擦除FLASH扇区
- * @param SectorAddr:要擦除的扇区地址
- * @retval 无
- */
- void SPI_FLASH_SectorErase(uint32_t SectorAddr)
- {
- /* 发送FLASH写使能命令 */
- SPI_FLASH_WriteEnable();
- SPI_FLASH_WaitForWriteEnd();
- //使能W25Q64_CS,拉低CS
- W25Q64_CS_OUT_L();
- SPI_FLASH_SendByte(W25X_SectorErase);
- /** 发送地址 **/
- SPI_FLASH_SendByte((SectorAddr>>16)&0xff);
- SPI_FLASH_SendByte((SectorAddr>>8)&0xff);
- SPI_FLASH_SendByte((SectorAddr)&0xff);
- //W25Q64_CS,拉高CS
- W25Q64_CS_OUT_H();
-
- SPI_FLASH_WaitForWriteEnd();
- }
- /**
- * @brief 等待WIP(BUSY)标志被置0,即等待到FLASH内部数据写入完毕
- * @param none
- * @retval none
- */
- void SPI_FLASH_WaitForWriteEnd(void)
- {
- uint8_t status_reg=0;
- //使能W25Q64_CS,拉低CS
- W25Q64_CS_OUT_L();
- SPI_FLASH_SendByte(W25X_ReadStatusReg);
-
- do
- {
- status_reg = SPI_FLASH_SendByte(Dummy_Byte);
- }while((status_reg & 0x01)== 1); //
-
- //W25Q64_CS,拉高CS
- W25Q64_CS_OUT_H();
-
- }
- /**
- * @brief 读取FLASH数据
- * @param pBuffer,存储读出数据的指针
- * @param ReadAddr,读取地址
- * @param NumByteToRead,读取数据长度
- * @retval 无
- */
- void SPI_FLASH_BufferRead(uint32_t ReadAddr,uint8_t* pBuffer, uint16_t NumByteToRead)
- {
- //使能W25Q64_CS,拉低CS
- W25Q64_CS_OUT_L();
- SPI_FLASH_SendByte(W25X_ReadData);
- /** 发送地址 **/
- SPI_FLASH_SendByte((ReadAddr>>16)&0xff);
- SPI_FLASH_SendByte((ReadAddr>>8)&0xff);
- SPI_FLASH_SendByte((ReadAddr)&0xff);
-
- while(NumByteToRead--)
- {
- *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
- pBuffer++;
- }
-
- //W25Q64_CS,拉高CS
- W25Q64_CS_OUT_H();
- }
- /**
- * @brief 向FLASH发送 写使能 命令
- * @param none
- * @retval none
- */
- void SPI_FLASH_WriteEnable(void)
- {
- //使能W25Q64_CS,拉低CS
- W25Q64_CS_OUT_L();
- SPI_FLASH_SendByte(W25X_WriteEnable);
- //W25Q64_CS,拉高CS
- W25Q64_CS_OUT_H();
- }
- /**
- * @brief 对FLASH按页写入数据,调用本函数写入数据前需要先擦除扇区
- * @param pBuffer,要写入数据的指针
- * @param WriteAddr,写入地址
- * @param NumByteToWrite,写入数据长度,必须小于等于SPI_FLASH_PerWritePageSize
- * @retval 无
- */
- void SPI_FLASH_PageWrite( uint32_t WriteAddr,uint8_t* pBuffer, uint16_t NumByteToWrite)
- {
- /* 发送FLASH写使能命令 */
- SPI_FLASH_WriteEnable();
- //使能W25Q64_CS,拉低CS
- W25Q64_CS_OUT_L();
- SPI_FLASH_SendByte(W25X_PageProgram);
- /** 发送地址 **/
- SPI_FLASH_SendByte((WriteAddr>>16)&0xff);
- SPI_FLASH_SendByte((WriteAddr>>8)&0xff);
- SPI_FLASH_SendByte((WriteAddr)&0xff);
-
- while(NumByteToWrite--)
- {
- SPI_FLASH_SendByte(*pBuffer);
- pBuffer++;
- }
-
- //W25Q64_CS,拉高CS
- W25Q64_CS_OUT_H();
- /* 等待写入完毕*/
- SPI_FLASH_WaitForWriteEnd();
- }
- /**
- * @brief 对FLASH写入数据,调用本函数写入数据前需要先擦除扇区
- * @param pBuffer,要写入数据的指针
- * @param WriteAddr,写入地址
- * @param NumByteToWrite,写入数据长度
- * @retval 无
- */
- void SPI_FLASH_BufferWrite( uint32_t WriteAddr,uint8_t* pBuffer, uint16_t NumByteToWrite)
- {
- uint8_t addr=0,NumOfPage = 0, NumOfSingle = 0,count = 0,temp = 0;
-
- /*mod运算求余,若writeAddr是SPI_FLASH_PageSize(256)整数倍,运算结果Addr值为0*/
- addr = WriteAddr%SPI_FLASH_PageSize;
-
- /*差count个数据值,刚好可以对齐到页地址*/
- count = SPI_FLASH_PageSize - addr;
-
- /*计算出要写多少整数页*/
- NumOfPage = NumByteToWrite /SPI_FLASH_PageSize;
- /*mod运算求余,计算出剩余不满一页的字节数*/
- NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
-
- /* addr=0,则WriteAddr 刚好按页对齐 aligned */
- if(addr==0)
- {
- /* NumByteToWrite < SPI_FLASH_PageSize 数据长度小于256,直接写入*/
- if(NumOfPage == 0)
- {
- SPI_FLASH_PageWrite(WriteAddr,pBuffer,NumByteToWrite);
- }
-
- else/* NumByteToWrite > SPI_FLASH_PageSize数据长度大于256, */
- {
- /*先把整数页都写了*/
- while(NumOfPage--)
- {
- SPI_FLASH_PageWrite(WriteAddr,pBuffer,SPI_FLASH_PageSize);
- WriteAddr+= SPI_FLASH_PageSize;
- pBuffer += SPI_FLASH_PageSize;
- }
- if(NumOfSingle != 0)
- {
- /*若有多余的不满一页的数据,把它写完*/
- SPI_FLASH_PageWrite(WriteAddr,pBuffer,NumOfSingle);
- }
-
- }
- }
- /* 若地址与 SPI_FLASH_PageSize 不对齐 */
- else
- {
- /* NumByteToWrite < SPI_FLASH_PageSize数据长度小于256,直接写入 */
- if(NumOfPage == 0)
- {
- /*当前页剩余的count个位置比NumOfSingle小,一页写不完*/
- if (NumOfSingle > count)
- {
- temp = NumOfSingle - count;
- /*先写满当前页*/
- SPI_FLASH_PageWrite( WriteAddr,pBuffer, count);
-
- WriteAddr += count;
- pBuffer += count;
-
- /*再写剩余的数据*/
- SPI_FLASH_PageWrite(WriteAddr,pBuffer,temp);
- }
- else /*当前页剩余的count个位置能写完NumOfSingle个数据*/
- {
- SPI_FLASH_PageWrite(WriteAddr,pBuffer, NumByteToWrite);
- }
- }
- /* NumByteToWrite > SPI_FLASH_PageSize 数据长度大于256*/
- else
- {
- /*地址不对齐多出的count分开处理,不加入这个运算*/
- NumByteToWrite -= count;
- NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
- NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
-
- /* 先写完count个数据,为的是让下一次要写的地址对齐 */
- SPI_FLASH_PageWrite( WriteAddr,pBuffer, count);
-
- /* 接下来就重复地址对齐的情况 */
- WriteAddr += count;
- pBuffer += count;
- /*把整数页都写了*/
- while (NumOfPage--)
- {
- SPI_FLASH_PageWrite(WriteAddr,pBuffer, SPI_FLASH_PageSize);
- WriteAddr += SPI_FLASH_PageSize;
- pBuffer += SPI_FLASH_PageSize;
- }
-
- /*若有多余的不满一页的数据,把它写完*/
- if (NumOfSingle != 0)
- {
- SPI_FLASH_PageWrite( WriteAddr,pBuffer, NumOfSingle);
- }
- }
- }
- }
- /***********************end***************************************/