STM32 W25Q256驱动源码(使用SPI接口)
主控:STM32H7B0VBT6
平台:STM32CubeIDE
W25Q256一片,使用SPI驱动

SPI配置(软件CS)

W25Q256最高时钟速率能达到50MHz,但是由于使用的是软件CS,自己测试大概只能跑到15MHz
现在给出c文件h文件:
W25Q256.c:
// @file W25Q256.c
/********************************Copyright (c)**********************************\
**
** (c) Copyright 2023, Main, China, 被钢琴支配的悲惨大学生.
** All Rights Reserved
**
** By(被钢琴支配的悲惨大学生 personally owned)
** https://blog.csdn.net/m0_71226271?type=blog
**
**----------------------------------文件信息------------------------------------
** 文件名称: W25Q256.c
** 创建人员: 被钢琴支配的悲惨大学生
** 创建日期: 2023-07-30
** 文档描述:
**
**----------------------------------版本信息------------------------------------
** 版本代号: V1.0
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------
\********************************End of Head************************************/#include "W25Q256.h"
#include "SPI.h"
/*************************************************************************************************
* 函 数 名: W25Q256_Read_JEDECID
* 入口参数: 无
* 返回值:无
* 函数功能: 读取W25Q256 JEDEC ID
* 说 明: W25Q256Q读取到的JEDEC ID是0XEF4019,如果不对请检查硬件接口
*************************************************************************************************/
void W25Q256_Read_JEDECID(uint8_t *JEDECID)
{uint8_t SPI_Transmit_Data[1];SPI_Transmit_Data[0]=W25Q256_Command_Read_JEDECID;W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,1,HAL_MAX_DELAY);HAL_SPI_Receive(&hspi1,JEDECID,3,HAL_MAX_DELAY);W25Q256_CS_H;
}
/*************************************************************************************************
* 函 数 名: W25Q256_Write_Enable
* 入口参数: 无
* 返回值:无
* 函数功能: 使能W25Q256写和擦除的权限
* 说 明: 无
*************************************************************************************************/
void W25Q256_Erase_Write_Enable()
{uint8_t SPI_Transmit_Data[1];SPI_Transmit_Data[0]=W25Q256_Command_Write_Enable;W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,1,HAL_MAX_DELAY);W25Q256_CS_H;
}
/*************************************************************************************************
* 函 数 名: W25Q256_Waiting_For_Erase_Write_End
* 入口参数: 无
* 返回值:无
* 函数功能: 等待擦除和写完成
* 说 明: 这是一个阻塞函数,直到擦除和写完成停止等待
*************************************************************************************************/
void W25Q256_Waiting_For_Erase_Write_End()
{uint8_t SPI_Transmit_Data[1];SPI_Transmit_Data[0]=W25Q256_Command_Read_Status_Register_1;uint8_t SPI_Receive_Data[1];while(1)//一直阻塞轮询{W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,1,HAL_MAX_DELAY);HAL_SPI_Receive(&hspi1,SPI_Receive_Data,1,HAL_MAX_DELAY);W25Q256_CS_H;if((SPI_Receive_Data[0]&0x01)==0)//最后一位等于0代表写、擦除完成,退出循环{break;}}
}
/*************************************************************************************************
* 函 数 名: W25Q256_Write_Data
* 入口参数: WriteData 写入数据的首地址、StartAddress 要写入的起始地址 WriteDataSize要写入的长度
* 返回值:无
* 函数功能: 向W25Q256特定地址写入特定长度数据
* 说 明: WriteDataSize最小是256,且是256的整数倍。并且StartAddress+WriteDataSize必须小于等于33554432(32MB)
*************************************************************************************************/
void W25Q256_Write_Data(uint8_t *WriteData,uint32_t StartAddress,uint32_t WriteDataSize)
{uint8_t SPI_Transmit_Data[5];uint32_t Number=WriteDataSize/256;//获取写入数据量是一页(256字节)的多少倍uint32_t i;for(i=0;i> 24);SPI_Transmit_Data[2] = (uint8_t)((StartAddress+256*i) >> 16);SPI_Transmit_Data[3] = (uint8_t)((StartAddress+256*i )>> 8);SPI_Transmit_Data[4] = (uint8_t)(StartAddress+256*i );//告知写入地址W25Q256_Erase_Write_Enable();//写使能W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,5,HAL_MAX_DELAY);HAL_SPI_Transmit(&hspi1,WriteData+i*256,256,HAL_MAX_DELAY);//传入数据,传入数量固定256字节W25Q256_CS_H;W25Q256_Waiting_For_Erase_Write_End();//阻塞等待写入完成}}
/*************************************************************************************************
* 函 数 名: W25Q256_Read_Data
* 入口参数: ReceiveData 读取数据存放的首地址、StartAddress 要读取的起始地址 ReceiveDataSize要读取数据的长度
* 返回值:无
* 函数功能: 向W25Q256特定地址读出特定长度数据
* 说 明: StartAddress+ReceiveDataSize必须小于等于33554432(32MB)
*************************************************************************************************/
void W25Q256_Read_Data(uint8_t *ReceiveData,uint32_t StartAddress,uint32_t ReceiveDataSize)
{uint8_t SPI_Transmit_Data[6];SPI_Transmit_Data[0] = W25Q256_Command_Fast_Read_Data;SPI_Transmit_Data[1] = (uint8_t)(StartAddress >> 24);SPI_Transmit_Data[2] = (uint8_t)(StartAddress >> 16);SPI_Transmit_Data[3] = (uint8_t)(StartAddress >> 8);SPI_Transmit_Data[4] = (uint8_t)(StartAddress);SPI_Transmit_Data[5] =0x00;//Dummy字节W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,6,HAL_MAX_DELAY);HAL_SPI_Receive(&hspi1,ReceiveData,ReceiveDataSize,HAL_MAX_DELAY);W25Q256_CS_H;
}
/*************************************************************************************************
* 函 数 名: W25Q256_Sector_Erase
* 入口参数:StartAdress 要擦除的地址
* 返回值:无
* 函数功能: 向W25Q256特定地址擦除所在的Sector
* 说 明: StartAddress必须小于等于33554432(32MB),比如擦除第一Sector(0-4095),那么StartAddress写入0或者是4095都是擦第一个Sector
*************************************************************************************************/
void W25Q256_Sector_Erase(uint32_t StartAddress)
{uint8_t SPI_Transmit_Data[5];SPI_Transmit_Data[0] = W25Q256_Command_Sector_Erase;SPI_Transmit_Data[1] = (uint8_t)(StartAddress >> 24);SPI_Transmit_Data[2] = (uint8_t)(StartAddress >> 16);SPI_Transmit_Data[3] = (uint8_t)(StartAddress >> 8);SPI_Transmit_Data[4] = (uint8_t)(StartAddress);W25Q256_Erase_Write_Enable();W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,5,HAL_MAX_DELAY);W25Q256_CS_H;W25Q256_Waiting_For_Erase_Write_End();
}
/*************************************************************************************************
* 函 数 名: W25Q256_Chip_Erase
* 入口参数:无
* 返回值:无
* 函数功能: 全片擦除
* 说 明: 耗时大概一分钟
*************************************************************************************************/
void W25Q256_Chip_Erase()
{uint8_t SPI_Transmit_Data[1];SPI_Transmit_Data[0] = W25Q256_Command_Chip_Erase;W25Q256_Erase_Write_Enable();W25Q256_CS_L;HAL_SPI_Transmit(&hspi1,SPI_Transmit_Data,1,HAL_MAX_DELAY);W25Q256_CS_H;W25Q256_Waiting_For_Erase_Write_End();
}
W25Q256.h:
// @file W25Q256.h
/********************************Copyright (c)**********************************\
**
** (c) Copyright 2023, Main, China, 被钢琴支配的悲惨大学生.
** All Rights Reserved
**
** By(被钢琴支配的悲惨大学生 personally owned)
** https://blog.csdn.net/m0_71226271?type=blog
**
**----------------------------------文件信息------------------------------------
** 文件名称: W25Q256.h
** 创建人员: 被钢琴支配的悲惨大学生
** 创建日期: 2023-07-30
** 文档描述:
**
**----------------------------------版本信息------------------------------------
** 版本代号: V1.0
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------\********************************End of Head************************************/
#include
#define W25Q256_CS_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET)
#define W25Q256_CS_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET)//使用PA15作为软件片选,记得使用SWD调试,不然PA15被占用#define W25Q256_Command_Read_JEDECID 0X9F //读取JEDECID指令
#define W25Q256_Command_Write_Enable 0X06 //写使能指令
#define W25Q256_Command_Read_Status_Register_1 0X05//读取Status Register 1指令
#define W25Q256_Command_Fast_Read_Data 0X0C//快速读取指令
#define W25Q256_Command_Page_Program 0X12//页编程指令
#define W25Q256_Command_Sector_Erase 0x21//扇区擦除指令
#define W25Q256_Command_Chip_Erase 0XC7//全片擦除指令void W25Q256_Read_JEDECID(uint8_t *JEDECID);
void W25Q256_Write_Data(uint8_t *WriteData,uint32_t StartAddress,uint32_t WriteDataSize);
void W25Q256_Read_Data(uint8_t *ReceiveData,uint32_t StartAdress,uint32_t ReceiveDataSize);
void W25Q256_Sector_Erase(uint32_t StartAdress);
void W25Q256_Chip_Erase();
全片擦除后插上USB进行格式化

格式化完毕:

注意事项:本代码使用的是全阻塞模式,如果遇到卡死请检查:
1.硬件接口是否对应
2.降低SPI时钟频率
3.断电重启W25Q256
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
