野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16191|回复: 1

Spi_Flash存储器读取问题

[复制链接]
发表于 2019-8-13 14:58:07 | 显示全部楼层 |阅读模式
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:读取的数据

图1:读取的数据

图2:原理图

图2:原理图
回复

使用道具 举报

发表于 2019-8-14 17:28:53 | 显示全部楼层
:):):):):):):):):)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-7 09:52 , Processed in 0.033353 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表