高中生
最后登录1970-1-1
在线时间 小时
注册时间2019-8-12
|
5火花
遇到一个很奇怪的问题,在读取Flash存储器SST26VF064的时候,读取到的数据如图1所示,原理图如图2所示,引脚引出去直接接的stm32f103vct6引脚。
头文件如下[mw_shl_code=c,true]#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
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); //写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
[/mw_shl_code].c文件如下:
[mw_shl_code=c,true]#include "spi_flash.h"
#include "delay.h"
#include "usart1.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
功 能 : 写一个字节
参 数 : 无
返 回 值 : 无
*************************************************/
void SPI_WriteByte(uint8_t txdata)
{
uint8_t cnt;
// uint8_t testdata=0;
for(cnt =0;cnt <8;cnt ++)
{
SST_SCLK_LOW;
delay_us (2);
if((txdata&0x80)==0x80)
SST_MOSI_HIGH;
else
SST_MOSI_LOW;
txdata<<=1;
/*********************************/
// testdata<<=1;
// if(SST_MISO_READ)
// {
// testdata |=0x01;
// }
/*********************************/
SST_SCLK_HIGH;
delay_us(2);
}
// return testdata ;
}
/************************************************
函数名称 : SPI_ReadByte
功 能 : 读取一个字节
参 数 : 无
返 回 值 : 读取的字节
*************************************************/
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;
}
uint32_t SFLASH_ReadDevice_ID(void)
{
uint32_t ID = 0;
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_JEDEC_ID); //《JEDEC_ID》指令
SPI_WriteByte(0); //读取ID
SPI_WriteByte(0);
SPI_WriteByte(0);
ID |= SPI_ReadByte();
SST_CE_DISABLE; //失能器件
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_WriteEnable
功 能 : SPI_FLASH写使能,将WEL置位
参 数 : 无
返 回 值 : 无
*************************************************/
static void SFLASH_WriteEnable(void)
{
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_WRITE_ENABLE); //《写使能》指令06
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : SFLASH_WriteDisable
功 能 : SPI_FLASH写禁止,将WEL清零
参 数 : 无
返 回 值 : 无
*************************************************/
static void SFLASH_WriteDisable(void)
{
SST_CE_ENABLE; //使能器件
SPI_WriteByte(SFLASH_WRITE_DISABLE); //《写失能》指令
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_WriteSR
功 能 : 写SFLASH状态寄存器
参 数 : SR --- 写状态寄存器命令
返 回 值 : 无
*************************************************/
void SFLASH_WriteSR(uint8_t SR)
{
SFLASH_WriteEnable(); //写使能
SST_CE_ENABLE;
SPI_WriteByte(SFLASH_WRITE_STATUS_REG); //《写状态寄存器》指令
SPI_WriteByte(SR); //写入一个字节
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)
{
uint16_t i;
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));
for(i=0;i<nByte;i++)
{
*(pBuffer+i)=SPI_ReadByte();
}
// while(nByte--) //循环读数
// {
// *pBuffer = SPI_ReadByte();
// pBuffer++;
// }
SST_CE_DISABLE; //失能器件
}
/************************************************
函数名称 : 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();
}
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); //写地址低位
while (nByte--)
{
SPI_WriteByte(*pBuffer); //写入数据
//delay_us(1);
pBuffer++;
}
SST_CE_DISABLE;
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~127
返 回 值 : 无
*************************************************/
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;
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~511)
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<SecRemain; i++) //校验数据,是否需要擦除
{
if(SectorBuf[SecOff + i] != 0xFF) //存储数据不为0xFF 则需要擦除
break;
}
if(i < SecRemain) //需要擦除
{
SFLASH_EraseSector(SecPos); //擦除该扇区
for(i=0; i<SecRemain; i++) //保存写入的数据(第1次时,是写入那扇区后面剩余的空间)
{
SectorBuf[SecOff + i] = pBuffer;
}
SFLASH_WriteNoCheck(SectorBuf, SecPos*4096, 4096); //写入整个扇区(扇区 = 老数据 + 新写入数据)
}
else
SFLASH_WriteNoCheck(pBuffer, WriteAddr, SecRemain); //不需要擦除,直接写入扇区剩余空间
if(nByte == SecRemain) //写入结束
{
SFLASH_WriteDisable(); //写失能, 退出写
break;
}
else //写入未结束
{
SecPos++; //扇区地址增1
SecOff = 0; //偏移位置归零
pBuffer += SecRemain; //指针偏移
WriteAddr += SecRemain; //写地址偏移
nByte -= SecRemain; //待写入字节数递减
if(nByte > 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; //失能器件
}
[/mw_shl_code]
然后设置的1秒读取发送一次,代码如下:
[mw_shl_code=c,true]/************************************************
函数名称 : Spi_Flash_WriteTest
功 能 : 存储器写入测试
参 数 : 无
返 回 值 : 无
*************************************************/
void Spi_Flash_WriteTest(void)
{
uint8_t SFlash_ReadArray[100]; //将从存储器中读取的数据存入此数组中
uint8_t SFlash_WriteArray[10]; //将要写入存储器中的数据暂存在此数组中
uint8_t Flash_Readcount,Flash_Writecount;
uint8_t i=0;
SFLASH_EraseSector(0x10000); //擦除要写入的扇区
for(Flash_Writecount=0;Flash_Writecount<10;Flash_Writecount++)
{
SFlash_WriteArray[Flash_Writecount]=0x10;
}
SFLASH_WritePage(SFlash_WriteArray, 0x10000, 10);//从地址0,连续写入6字节数据(ABCDEF)
delay_ms (1);
SFLASH_ReadNByte(SFlash_ReadArray,0x10000,100);
printf ("本存储器芯片的前100个字节数据为:\n");
for(Flash_Readcount=0;Flash_Readcount<100;Flash_Readcount++)
{
i++;
printf ("0x%x ",SFlash_ReadArray[Flash_Readcount]);
if(i==10)
{
i=0;
printf ("\n");
}
}
}[/mw_shl_code]
奇怪的就是在这个板子上面就有问题,然后我把程序刷到野火的F429挑战者上面读取的数据就没有问题。
|
-
图1:读取的数据
-
图2:原理图
|