程序没什么好说的,软件模拟SPI驱动的网上也是挺多的,不过要说一下的就是SST26VF064这款芯片与其他FLASH不同的是,它上电之后有写保护位,搞了好一阵子都没有发现这个原因,后面还是我师傅发现要首先取消掉它的写保护位。
代码如下:
#ifndef _SPI_FLASH_H_
#define _SPI_FLASH_H_
#include "stm32f10x.h"
#define SST_GPIO_RCC_CONFIG RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC //flash芯片时钟
#define SST_HOLD_GPIOx GPIOA //HOLD引脚
#define SST_HOLD_PIN GPIO_Pin_7
#define SST_WP_GPIOx GPIOA //WP引脚
#define SST_WP_PIN GPIO_Pin_4
#define SST_CE_GPIOx GPIOA //片选引脚
#define SST_CE_PIN GPIO_Pin_6
#define SST_SCLK_GPIOx GPIOC //时钟
#define SST_SCLK_PIN GPIO_Pin_4
#define SST_MOSI_GPIOx GPIOC //MOSI
#define SST_MOSI_PIN GPIO_Pin_5
#define SST_MISO_GPIOx GPIOA //配置成输入模式 MISO
#define SST_MISO_PIN GPIO_Pin_5
/* 指令表 */
#define SFLASH_WRITE_ENABLE 0x06 //写使能
#define SFLASH_WRITE_DISABLE 0x04 //写失能
#define SFLASH_READ_STATUS_REG 0x05 //读状态寄存器
#define SFLASH_WRITE_STATUS_REG 0x01 //写状态寄存器
#define SFLASH_READ_DATA 0x03 //读数据
#define SFLASH_FAST_READ 0x0B //快读数据
#define SFLASH_FAST_READ_DUAL 0x3B //快读数据(双数据线输出)
#define SFLASH_WRITE_PAGE 0x02 //页编程
#define SFLASH_ERASE_BLOCK 0xD8 //擦除块
#define SFLASH_ERASE_SECTOR 0x20 //擦除扇区
#define SFLASH_ERASE_CHIP 0xC7 //擦除芯片
#define SFLASH_POWER_DOWN 0xB9 //掉电
#define SFLASH_RELEASE_POWER_DOWN 0xAB //释放掉电
#define SFLASH_DEVICE_ID 0x90 //设备ID
#define SFLASH_JEDEC_ID 0x9F //Jedec ID
extern void Sensor_StateCheck(void); //传感器状态轮询
extern void BJ_Action(void); //报警动作
void SPI_FLASH_config(void); //spi的GPIO引脚初始化
void SPI_Initconfig(void); //SPI初始化
uint32_t SFLASH_ReadJEDEC_ID(void); //读取JEDEC-ID
void SPI_WriteByte(uint8_t txdata);
uint8_t SPI_ReadByte(void);
uint8_t SFLASH_ReadSR(void); //读取SFLASH状态寄存器
void SFLASH_WriteSR(uint8_t SR,uint8_t CR); //写SFLASH状态寄存器
void SFLASH_ReadBlockProtectSR(uint8_t *pBuff); //读取块保护
void SFLASH_DeleteBlockProtectSR(void); //取消块保护状态寄存器
void SFLASH_ClearAllBlockProtect(void); //清除所有的块保护状态寄存器
uint8_t SFLASH_ReadConfigRegSR(void); //读取SFLASH配置状态寄存器
/****从ReadAddr地址开始连续读取SFLASH的nByte*********************************/
void SFLASH_ReadNByte(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t nByte);
/*****从ReadAddr地址开始连续快速读取SFLASH的nByte
******最多读取65535B***************************/
void SFLASH_FastReadNByte(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t nByte);
void SFLASH_WaitForNoBusy(void); // 等待不忙
/*****在SFLASH内写入少于1页(256个字节)的数据************************************/
void SFLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t nByte);
/*********无检验写SFLASH
*必须确保所写的地址范围内的数据全部为0xFF,否则在非0xFF处写入的数据将失败!
*具有自动换页功能**********/
void SFLASH_WriteNoCheck(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t nByte);
void SFLASH_EraseBlock(uint32_t BlockAddr); //擦除块
void SFLASH_EraseSector(uint32_t SectorAddr); //擦除扇区
void SFLASH_EraseChip(void); //擦除整个芯片(整片擦除时间较长)
/**从ReadAddr地址开始连续写入nByte到SFLASH中
***pBuffer ----- 写入数据区首地址
*** WriteAddr --- 要写入Flash的地址
**** nByte ------- 要写入的字节数(最大65535B = 64K 块)**********************/
void SFLASH_WriteNByte(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t nByte);
uint32_t SFLASH_ReadDevice_ID(void); //读取设备ID
void SFLASH_WriteoneBytetest(void); //写一个字节,用于测试
uint8_t SFLASH_ReadoneBytetest(void); //读一个字节,用于测试
void SFLASH_ReleasePowerDown(void); //释放掉电
#endif //_SPI_FLASH_H
#include "spi_flash.h"
#include "delay.h"
#include "usart1.h"
#include "can.h"
#define SST_HOLD_HIGH GPIO_SetBits(SST_HOLD_GPIOx,SST_HOLD_PIN)
#define SST_HOLD_LOW GPIO_ResetBits(SST_HOLD_GPIOx,SST_HOLD_PIN)
#define SST_WP_HIGH GPIO_SetBits(SST_WP_GPIOx,SST_WP_PIN)
#define SST_WP_LOW GPIO_ResetBits(SST_WP_GPIOx,SST_WP_PIN)
#define SST_CE_DISABLE GPIO_SetBits(SST_CE_GPIOx,SST_CE_PIN) //失能
#define SST_CE_ENABLE GPIO_ResetBits(SST_CE_GPIOx,SST_CE_PIN) //使能
#define SST_SCLK_HIGH GPIO_SetBits(SST_SCLK_GPIOx,SST_SCLK_PIN)
#define SST_SCLK_LOW GPIO_ResetBits(SST_SCLK_GPIOx,SST_SCLK_PIN)
#define SST_MOSI_HIGH GPIO_SetBits(SST_MOSI_GPIOx,SST_MOSI_PIN)
#define SST_MOSI_LOW GPIO_ResetBits(SST_MOSI_GPIOx,SST_MOSI_PIN)
#define SST_MISO_READ GPIO_ReadInputDataBit(SST_MISO_GPIOx,SST_MISO_PIN)
/************************************************
函数名称 : SPI_FLASH_config
功 能 : Flash引脚配置
参 数 : 无
返 回 值 : 无
*************************************************/
void SPI_FLASH_config(void)
{
GPIO_InitTypeDef GPIO_initStructure;
RCC_APB2PeriphClockCmd(SST_GPIO_RCC_CONFIG,ENABLE);
GPIO_initStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_initStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_initStructure.GPIO_Pin = SST_HOLD_PIN;
GPIO_Init (SST_HOLD_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = SST_WP_PIN;
GPIO_Init (SST_WP_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = SST_CE_PIN;
GPIO_Init (SST_CE_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = SST_SCLK_PIN;
GPIO_Init (SST_SCLK_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = SST_MOSI_PIN;
GPIO_Init (SST_MOSI_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_initStructure.GPIO_Pin = SST_MISO_PIN;
GPIO_Init (SST_MISO_GPIOx,&GPIO_initStructure);
}
/************************************************
函数名称 : SPI_Initconfig
功 能 : SPI_Flash初始化
参 数 : 无
返 回 值 : 无
*************************************************/
void SPI_Initconfig(void)
{
SPI_FLASH_config(); //GPIO引脚配置
SST_CE_DISABLE; //失能
SST_SCLK_HIGH; //初始拉高
SST_MOSI_HIGH;
SST_HOLD_HIGH;
SST_WP_HIGH;
}
/************************************************
函数名称 : SPI_WriteByte
功 能 : 写一个字节
参 数 : 无
返 回 值 : 无
*************************************************/
#if 1
void SPI_WriteByte(uint8_t txdata)
{
uint8_t cnt;
// uint8_t testdata=0;
for(cnt =0;cnt <8;cnt ++)
{
SST_SCLK_LOW;
//delay_us (1);
if((txdata&0x80)==0x80)
SST_MOSI_HIGH;
else
SST_MOSI_LOW;
txdata<<=1;
/*********************************/
// testdata<<=1;
// if(SST_MISO_READ)
// {
// testdata |=0x01;
// }
/*********************************/
delay_us(1); //-------------
SST_SCLK_HIGH;
delay_us(1);
}
// return testdata ;
}
#else
void SPI_WriteByte(uint8_t txdata)
{
uint8_t cnt;
// uint8_t testdata=0;
for(cnt =0;cnt <8;cnt ++)
{
//delay_us (1);
if((txdata&0x80)==0x80)
SST_MOSI_HIGH;
else
SST_MOSI_LOW;
txdata<<=1;
SST_SCLK_LOW;
/*********************************/
// testdata<<=1;
// if(SST_MISO_READ)
// {
// testdata |=0x01;
// }
/*********************************/
delay_us(1); //-------------
SST_SCLK_HIGH;
delay_us(1);
}
// return testdata ;
}
#endif
/************************************************
函数名称 : SPI_ReadByte
功 能 : 读取一个字节
参 数 : 无
返 回 值 : 读取的字节
*************************************************/
#if 1
uint8_t SPI_ReadByte(void)
{
uint8_t cnt;
uint8_t rxdata=0;
for(cnt =0;cnt <8;cnt++)
{
SST_SCLK_LOW;
delay_us (1);
rxdata<<=1;
if(SST_MISO_READ)
{
rxdata |=0x01;
}
SST_SCLK_HIGH;
delay_us (1);
}
return rxdata;
}
#else
uint8_t SPI_ReadByte(void)
{
uint8_t cnt;
uint8_t rxdata=0;
SST_SCLK_HIGH;
delay_us (1);
for(cnt =0;cnt <8;cnt++)
{
SST_SCLK_LOW;
delay_us (1);
rxdata<<=1;
if(SST_MISO_READ)
{
rxdata |=0x01;
}
SST_SCLK_HIGH;
delay_us (1);
}
return rxdata;
}
#endif
/************************************************
函数名称 : SFLASH_ReadDevice_ID
功 能 : 读取芯片Device_ID
参 数 : 无
返 回 值 : ID --- 24位ID号
*************************************************/
uint32_t SFLASH_ReadDevice_ID(void)
{
uint32_t ID1 = 0,ID2 = 0,ID;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_DEVICE_ID); //《SFLASH_DEVICE_ID》指令
// SPI_WriteByte(0); //读取ID
// SPI_WriteByte(0);
// SPI_WriteByte(0x01);
ID1 |= SPI_ReadByte();
ID2 |= SPI_ReadByte();
SST_CE_DISABLE; //失能器件
ID = (ID1<<8)|ID2;
return ID;
}
/************************************************
函数名称 : SFLASH_ReadJEDEC_ID
功 能 : 读取芯片JEDEC_ID
参 数 : 无
返 回 值 : ID --- 24位ID号
*************************************************/
uint32_t SFLASH_ReadJEDEC_ID(void)
{
uint32_t ID = 0;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_JEDEC_ID); //《JEDEC_ID》指令
ID |= SPI_ReadByte()<<16; //读取ID
ID |= SPI_ReadByte()<<8;
ID |= SPI_ReadByte();
SST_CE_DISABLE; //失能器件
return ID;
}
/************************************************
函数名称 : SFLASH_WrStatusRegEnable
功 能 : SPI_FLASH写状态寄存器使能
参 数 : 无
返 回 值 : 无
*************************************************/
//static void SFLASH_WrStatusRegEnable(void)
//{
// SST_CE_ENABLE; //使能器件
// SPI_WriteByte(0x50); //写状态寄存器使能
// SST_CE_DISABLE; //失能器件
//// delay_us(2); //----------------
//}
/************************************************
函数名称 : SFLASH_WriteEnable
功 能 : SPI_FLASH写使能,将WEL置位
参 数 : 无
返 回 值 : 无
*************************************************/
static void SFLASH_WriteEnable(void)
{
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_WRITE_ENABLE); //《写使能》指令06
SST_CE_DISABLE; //失能器件
// delay_us(2); //----------------
}
/************************************************
函数名称 : SFLASH_WriteDisable
功 能 : SPI_FLASH写禁止,将WEL清零
参 数 : 无
返 回 值 : 无
*************************************************/
static void SFLASH_WriteDisable(void)
{
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_WRITE_DISABLE); //《写失能》指令
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_ReadBlockProtectSR
功 能 : 读取块保护状态寄存器
参 数 : 无
返 回 值 : Byte --- 读取字节
*************************************************/
void SFLASH_ReadBlockProtectSR(uint8_t *pBuff)
{
uint8_t data_tmp;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(0x72); //《读状态寄存器》指令
for(data_tmp=0;data_tmp<18;data_tmp++)
{
*pBuff = SPI_ReadByte(); //读取一个字节
pBuff++;
}
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_ReadSR
功 能 : 读取SFLASH状态寄存器
参 数 : 无
返 回 值 : Byte --- 读取字节
*************************************************/
uint8_t SFLASH_ReadSR(void)
{
uint8_t data_tmp;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_READ_STATUS_REG); //《读状态寄存器》指令
data_tmp = SPI_ReadByte(); //读取一个字节
SST_CE_DISABLE; //失能器件
return data_tmp;
}
/************************************************
函数名称 : SFLASH_ReadSR
功 能 : 读取SFLASH配置状态寄存器
参 数 : 无
返 回 值 : Byte --- 读取字节
*************************************************/
uint8_t SFLASH_ReadConfigRegSR(void)
{
uint8_t data_tmp;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(0x35); //《读状态寄存器》指令
data_tmp = SPI_ReadByte(); //读取一个字节
SST_CE_DISABLE; //失能器件
return data_tmp;
}
/************************************************
函数名称 : SFLASH_DeleteBlockProtectSR
功 能 : 取消块保护状态寄存器
参 数 : 无
返 回 值 : 无
*************************************************/
void SFLASH_DeleteBlockProtectSR(void)
{
uint8_t i;
SFLASH_WriteEnable(); //写状态寄存器使能
delay_us(2); //-------------------------
SST_CE_ENABLE;
SPI_WriteByte(0x42); //《写状态寄存器》指令
for(i=0;i<18;i++)
{SPI_WriteByte(0x00);} //写入一个字节
// SPI_WriteByte(SR); //---------------------------
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_DeleteAllBlockProtect
功 能 : 清除所有的块保护状态寄存器
参 数 : 无
返 回 值 : 无
*************************************************/
void SFLASH_ClearAllBlockProtect(void) //执行uLBPR(98)
{
SFLASH_WriteEnable(); //写状态寄存器使能
delay_us(2); //-------------------------
SST_CE_ENABLE;
SPI_WriteByte(0x98); //《写状态寄存器》指令
// for(i=0;i<18;i++)
// SPI_WriteByte(0); //写入一个字节
// SPI_WriteByte(SR); //---------------------------
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_WriteSR
功 能 : 写SFLASH状态寄存器
参 数 : SR --- 写状态寄存器命令
返 回 值 : 无
*************************************************/
void SFLASH_WriteSR(uint8_t SR,uint8_t CR)
{
SFLASH_WriteEnable(); //写使能
delay_us(2); //-------------------------
SST_CE_ENABLE;
SPI_WriteByte(SFLASH_WRITE_STATUS_REG); //《写状态寄存器》指令
SPI_WriteByte(SR); //写入一个字节
SPI_WriteByte(CR); //---------------------------
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_ReadNByte
功 能 : 从ReadAddr地址开始连续读取SFLASH的nByte
参 数 : pBuffer ---- 数据存储区首地址
ReadAddr --- 要读取SFLASH Flash的首地址地址
nByte ------ 要读取的字节数(最大65535B = 64K 块)
返 回 值 : 无
*************************************************/
void SFLASH_ReadNByte(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t nByte)
{
// SST_CE_DISABLE;
// delay_us (2);
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_READ_DATA); //《读数据》指令
SPI_WriteByte((uint8_t)((ReadAddr>>16)&0xff)); //发送24bit地址
SPI_WriteByte((uint8_t)((ReadAddr>>8)&0xff));
SPI_WriteByte((uint8_t)(ReadAddr&0xff));
while(nByte--) //循环读数
{
*pBuffer = SPI_ReadByte();
pBuffer++;
}
SST_CE_DISABLE; //失能器件
// delay_us (2);//-------------
}
/************************************************
函数名称 : SFLASH_FastReadNByte
功 能 : 从ReadAddr地址开始连续快速读取SFLASH的nByte
参 数 : pBuffer ---- 数据存储区首地址
ReadAddr --- 要读取SFLASH Flash的首地址地址
nByte ------ 要读取的字节数(最大65535B = 64K 块)
返 回 值 : 无
*************************************************/
void SFLASH_FastReadNByte(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t nByte)
{
// SST_CE_DISABLE;
// delay_us (2);
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_FAST_READ); //《快读数据》指令
SPI_WriteByte((uint8_t)(((ReadAddr)>>16)&0xff)); //发送24bit地址
SPI_WriteByte((uint8_t)(((ReadAddr)>>8)&0xff));
SPI_WriteByte((uint8_t)(ReadAddr&0xff));
SPI_WriteByte(0xFF); //等待8个时钟
while(nByte--) //循环读数
{
*pBuffer = SPI_ReadByte();
pBuffer++;
}
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_WaitForNoBusy
功 能 : 等待不忙
参 数 : 无
返 回 值 : 无
*************************************************/
void SFLASH_WaitForNoBusy(void)
{
u8 FLASH_Status = 0;
/* 选择 FLASH: CS 低 */
SST_CE_ENABLE;
/* 发送 读状态寄存器 命令 */
SPI_WriteByte(SFLASH_READ_STATUS_REG);
/* 若FLASH忙碌,则等待 */
do
{
/* 读取FLASH芯片的状态寄存器 */
FLASH_Status = SPI_ReadByte();
Sensor_StateCheck(); //传感器状态轮询
BJ_Action(); //报警动作
// printf ("忙状态FLASH_Status=%d\n",FLASH_Status);
}
while ((FLASH_Status & 0x01) == 0x01); /* 正在写入标志 */
/* 停止信号 FLASH: CS 高 */
SST_CE_DISABLE;
}
/************************************************
函数名称 : SFLASH_WritePage
功 能 : 在SFLASH内写入少于1页(256个字节)的数据
参 数 : pBuffer ----- 写入数据区首地址
WriteAddr --- 要写入Flash的地址
nByte ------- 要写入的字节数(最大1页)
返 回 值 : 无
*************************************************/
void SFLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t nByte)
{
SFLASH_WriteEnable(); //写使能
delay_us(1);
//SFLASH_WaitForNoBusy(); //等待空闲(等待写入结束)----------------------
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_WRITE_PAGE); //《页编程》指令02
SPI_WriteByte((WriteAddr & 0xFF0000) >> 16); //写地址高位 //((uint8_t)(((WriteAddr)>>16)&0xff)); //发送24bit地址
SPI_WriteByte((WriteAddr & 0xFF00) >> 8); //写地址中位
SPI_WriteByte(WriteAddr & 0xFF); //写地址低位
// SST_MOSI_HIGH; //--------------------------
while (nByte--)
{
SPI_WriteByte(*pBuffer); //写入数据
//delay_us(1);
pBuffer++;
}
SST_CE_DISABLE;
// delay_us (2); //--------------------------
// SST_MOSI_HIGH; //--------------------------
SFLASH_WaitForNoBusy(); //等待空闲(等待写入结束)
}
void SFLASH_WriteoneBytetest(void)
{
// uint8_t testdat;
SFLASH_WriteEnable(); //写使能
SFLASH_WaitForNoBusy(); //等待空闲(等待写入结束)--------------
delay_us(1);
SST_CE_ENABLE;
SPI_WriteByte(SFLASH_WRITE_PAGE);
// printf ("这是SFLASH_WriteoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x00);
// printf ("这是SFLASH_WriteoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x20);
// printf ("这是SFLASH_WriteoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x00);
// printf ("这是SFLASH_WriteoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x3b);
// printf ("这是SFLASH_WriteoneBytetest函数中的testdat=0x%x\n",testdat);
SST_CE_DISABLE;
SFLASH_WaitForNoBusy(); //等待空闲(等待写入结束)
}
uint8_t SFLASH_ReadoneBytetest(void)
{
// uint8_t testdat;
uint8_t ID = 0;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(0x03); //《读字节》指令
// printf ("这是SFLASH_ReadoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x00);
// printf ("这是SFLASH_ReadoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x20);
// printf ("这是SFLASH_ReadoneBytetest函数中的testdat=0x%x\n",testdat);
SPI_WriteByte(0x00);
// printf ("这是SFLASH_ReadoneBytetest函数中的testdat=0x%x\n",testdat);
ID |= SPI_ReadByte();
printf ("读出的数据为ID=0X%x\n",ID);
SST_CE_DISABLE; //失能器件
return ID;
}
/************************************************
函数名称 : SFLASH_WriteNoCheck
功 能 : 无检验写SFLASH
必须确保所写的地址范围内的数据全部为0xFF,否则在非0xFF处写入的数据将失败!
具有自动换页功能
在指定地址开始写入指定长度的数据,但是要确保地址不越界!
参 数 : pBuffer ----- 写入数据区首地址
WriteAddr --- 要写入Flash的地址
nByte ------- 要写入的字节数
返 回 值 : 无
*************************************************/
void SFLASH_WriteNoCheck(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t nByte)
{
uint16_t PageRemain = 256 - WriteAddr%256; //单页剩余可写的字节数
if(nByte <= PageRemain)
PageRemain = nByte; //不大于256个字节
while(1)
{
SFLASH_WritePage(pBuffer, WriteAddr, PageRemain);
if(nByte == PageRemain) //写入结束
break;
else //写入未结束
{
pBuffer += PageRemain; //下一页写入数据
WriteAddr += PageRemain; //下一页写入数据地址
nByte -= PageRemain; //待写入字节数递减
if(nByte > 256)
PageRemain = 256; //待写入1页(256字节)的数据
else
PageRemain = nByte; //待写入少于1页(256字节)的数据
}
}
SFLASH_WaitForNoBusy(); //等待空闲(等待写入结束)
}
/************************************************
函数名称 : SFLASH_EraseBlock
功 能 : 擦除块
擦除块需要一定时间
参 数 : BlockAddr --- 块地址 0~135
返 回 值 : 无
*************************************************/
void SFLASH_EraseBlock(uint32_t BlockAddr)
{
BlockAddr *= 65536; //块首地址
SFLASH_WriteEnable(); //写使能
SFLASH_WaitForNoBusy();
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_ERASE_BLOCK); //《擦除块》指令
SPI_WriteByte((uint8_t)(((BlockAddr)>>16)&0xff)); //擦除地址
SPI_WriteByte((uint8_t)(((BlockAddr)>>8)&0xff));
SPI_WriteByte((uint8_t)(BlockAddr&0xff));
SST_CE_DISABLE;
SFLASH_WaitForNoBusy(); //等待擦除完成
}
/************************************************
函数名称 : SFLASH_EraseSector
功 能 : 擦除扇区
参 数 : SectorAddr --- 扇区地址 0~511
返 回 值 : 无
*************************************************/
void SFLASH_EraseSector(uint32_t SectorAddr)
{
SectorAddr *= 4096; //扇区首地址
SFLASH_WriteEnable(); //写使能
SFLASH_WaitForNoBusy();
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_ERASE_SECTOR); //《擦除扇区》指令
SPI_WriteByte((uint8_t)(((SectorAddr)>>16)&0xff)); //擦除地址
SPI_WriteByte((uint8_t)(((SectorAddr)>>8)&0xff));
SPI_WriteByte((uint8_t)(SectorAddr&0xff));
SST_CE_DISABLE;
//delay_us (2);//-------------------------
SFLASH_WaitForNoBusy(); //等待擦除完成
}
/************************************************
函数名称 : SFLASH_EraseChip
功 能 : 擦除整个芯片(整片擦除时间较长)
参 数 : 无
返 回 值 : 无
*************************************************/
void SFLASH_EraseChip(void)
{
SFLASH_WriteEnable(); //写使能
SFLASH_WaitForNoBusy();
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_ERASE_CHIP); //《擦除芯片》指令
SST_CE_DISABLE;
SFLASH_WaitForNoBusy(); //等待芯片擦除结束
}
/************************************************
函数名称 : SFLASH_WriteNByte
功 能 : 从ReadAddr地址开始连续写入nByte到SFLASH中
参 数 : pBuffer ----- 写入数据区首地址
WriteAddr --- 要写入Flash的地址
nByte ------- 要写入的字节数(最大65535B = 64K 块)
返 回 值 : 无
*************************************************/
void SFLASH_WriteNByte(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t nByte)
{
static uint8_t SectorBuf[4096]; //扇区buf
uint32_t SecPos; //扇区位置
uint16_t SecOff; //扇区偏移
uint16_t SecRemain; //剩余扇区
uint16_t i;
SFLASH_WriteEnable(); //写使能
SecPos = WriteAddr/4096; //地址所在扇区(0~2048)
SecOff = WriteAddr%4096; //地址所在扇区的偏移
SecRemain = 4096-SecOff; //地址所在扇区剩余字节数(扇区大小4096B=4KB)
if(nByte <= SecRemain)
SecRemain = nByte; //写入数据大小 < 剩余空间大小 (即剩余空间够保存这些数据)
while(1)
{
/* 第1步·校验 */
SFLASH_ReadNByte(SectorBuf, SecPos*4096, 4096); //读出整个扇区的内容
for(i=0; i 4096)
SecRemain = 4096; //待写入1扇区(4096字节)的数据
else
SecRemain = nByte; //待写入少于1扇区(4096字节)的数据
}
}
SFLASH_WaitForNoBusy(); //等待芯片擦除结束
}
/************************************************
函数名称 : SFLASH_ReleasePowerDown
功 能 : 释放掉电
参 数 : 无
返 回 值 : 无
*************************************************/
void SFLASH_ReleasePowerDown(void)
{
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_RELEASE_POWER_DOWN); //《释放掉电》指令
SST_CE_DISABLE; //失能器件
}