170 lines
8.3 KiB
C
170 lines
8.3 KiB
C
#include "main.h"
|
||
|
||
/*-------------------------------------------------*/
|
||
/*函数名:初始化W25Qxx */
|
||
/*参 数:无 */
|
||
/*返回值:0:正确 */
|
||
/*-------------------------------------------------*/
|
||
uint8_t W25Qxx_Init(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_Initure;
|
||
|
||
GPIOD_RCC_ENABLE; //使能端口D时钟
|
||
|
||
GPIO_Initure.Pin=GPIO_PIN_12; //设置PD0
|
||
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推免输出
|
||
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
|
||
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速模式
|
||
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //设置
|
||
CS_DISENABLE; //CS无效信号
|
||
|
||
SPI2_Init(); //初始化SPI2接口
|
||
if(W25Qxx_ReadID()==W25QxxID){ //读取ID,正确进入if
|
||
W25Qxx_Write_Enable(); //写使能
|
||
}else return 1; //读取ID错误,返回1
|
||
|
||
return 0; //正确 返回0
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx擦写使能 */
|
||
/*参 数:无 */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25Qxx_Write_Enable(void)
|
||
{
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_WriteByte(W25Qxx_WriteEnable); //发送写使能
|
||
CS_DISENABLE; //CS无效信号
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx擦写禁止 */
|
||
/*参 数:无 */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25QXX_Write_Disable(void)
|
||
{
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_WriteByte(W25Qxx_WriteDisable); //发送写禁止
|
||
CS_DISENABLE; //CS无效信号
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:读取W25Qxx芯片ID */
|
||
/*参 数:无 */
|
||
/*返回值:0XEF17 是W25Qxx的ID */
|
||
/*-------------------------------------------------*/
|
||
uint16_t W25Qxx_ReadID(void)
|
||
{
|
||
uint8_t wdata[6] = {0x90,0x00,0x00,0x00,0x00,0x00}; //读取ID指令数据
|
||
uint8_t rdata[6]; //接收数据缓冲区
|
||
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_WriteRead(wdata,rdata,6); //发送并接收数据
|
||
CS_DISENABLE; //CS无效信号
|
||
return (rdata[4]*256 + rdata[5]); //返回ID
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx等待空闲 */
|
||
/*参 数:无 */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25Qxx_Wait_Busy(void)
|
||
{
|
||
uint8_t res;
|
||
|
||
do{
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_WriteByte(W25Qxx_ReadStatusReg1); //发送读取状态寄存器1命令
|
||
res = SPI2_ReadByte(); //读取状态寄存器1
|
||
CS_DISENABLE; //CS无效信号
|
||
}while((res&0x01)==0x01); //等待BUSY位清空,表示空闲
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx擦除一个扇区(4KB) */
|
||
/*参 数:NBsector:第几个扇区 (0~4095) */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25Qxx_Erase_Sector(uint16_t NBsector)
|
||
{
|
||
uint8_t wdata[4]; //指令数据缓冲区
|
||
|
||
wdata[0] = W25Qxx_SectorErase; //扇区擦除指令
|
||
wdata[1] = (NBsector*4096)>>16; //A23~A16地址位
|
||
wdata[2] = (NBsector*4096)>>8; //A15~A8地址位
|
||
wdata[3] = (NBsector*4096)>>0; //A7~A0地址位
|
||
|
||
W25Qxx_Write_Enable(); //写使能
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_Write(wdata,4); //发送数据
|
||
CS_DISENABLE; //CS无效信号
|
||
W25Qxx_Wait_Busy(); //等待擦除完成
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx擦除一个块(64KB) */
|
||
/*参 数:NBsector:第几个块 (0~255) */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25Qxx_Erase_Block(uint8_t NBBlock)
|
||
{
|
||
uint8_t wdata[4]; //指令数据缓冲区
|
||
|
||
wdata[0] = W25Qxx_BlockErase; //块擦除指令
|
||
wdata[1] = (NBBlock*16*4096)>>16; //A23~A16地址位
|
||
wdata[2] = (NBBlock*16*4096)>>8; //A15~A8地址位
|
||
wdata[3] = (NBBlock*16*4096)>>0; //A7~A0地址位
|
||
|
||
W25Qxx_Write_Enable(); //写使能
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_Write(wdata,4); //发送数据
|
||
CS_DISENABLE; //CS无效信号
|
||
W25Qxx_Wait_Busy(); //等待擦除完成
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx写入一页数据(256字节) */
|
||
/*参 数:wdata:待写入数据 */
|
||
/*参 数:NBPage:第几个页(0~65535) */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25Qxx_Write_Page(uint8_t* wbuff, uint16_t NBPage)
|
||
{
|
||
uint8_t wdata[4]; //指令数据缓冲区
|
||
|
||
wdata[0] = W25Qxx_PageProgram; //页(256B)写入指令
|
||
wdata[1] = (NBPage*256)>>16; //A23~A16地址位
|
||
wdata[2] = (NBPage*256)>>8; //A15~A8地址位
|
||
wdata[3] = (NBPage*256)>>0; //A7~A0地址位
|
||
|
||
W25Qxx_Write_Enable(); //写使能
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_Write(wdata,4); //发送数据
|
||
SPI2_Write(wbuff,256); //发送数据
|
||
CS_DISENABLE; //CS无效信号
|
||
}
|
||
/*-------------------------------------------------*/
|
||
/*函数名:W25Qxx读取数据 */
|
||
/*参 数:rdata:存放数据缓冲区 */
|
||
/*参 数:rAddr:读取的开始地址 */
|
||
/*参 数:len:读取多少字节数据 */
|
||
/*返回值:无 */
|
||
/*-------------------------------------------------*/
|
||
void W25Qxx_Read(uint8_t* rdata,uint32_t rAddr,uint32_t len)
|
||
{
|
||
uint8_t wdata[4]; //指令数据缓冲区
|
||
|
||
wdata[0] = W25Qxx_ReadData; //读数据指令
|
||
wdata[1] = rAddr>>16; //A23~A16地址位
|
||
wdata[2] = rAddr>>8; //A15~A8地址位
|
||
wdata[3] = rAddr>>0; //A7~A0地址位
|
||
|
||
W25Qxx_Wait_Busy(); //等待空闲
|
||
CS_ENABLE; //CS有效信号
|
||
SPI2_Write(wdata,4); //发送数据
|
||
SPI2_Read(rdata,len); //接收数据
|
||
CS_DISENABLE; //CS无效信号
|
||
}
|