OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4217|回复: 13

求一个flash存储和读写的方案

[复制链接]

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
发表于 2016-11-17 08:59:18 | 显示全部楼层 |阅读模式
20金钱
我已经调通了flash。
现在我的需求是这样:
我每隔1分钟存储一次信息,包括:时间,应力,信号幅值。。。。。大概100字节。
这样存最多可以存半个月的信息吧。

会有上位机软件不定期向我获取flash里的信息。它的指令里会给我两个时间参数,我要把这段时间内的历史数据发给上位机。

我的问题是这样:
1,如何把指令里的时间段和我的FLASH存储地址对应起来
2,考虑到停电的情况,flash里存储的信息并不是连续的。也就是说我要知道上位机想要获取的时间段内我自身有没有掉电。
3,半个月后我会用新的信息把最老的信息覆盖掉,这就导致flash最早的有效信息不一定在哪个地址上。


因为以前没做过这样的事,感觉有点思路但还是很乱。
请有经验的前辈指点一下。

最佳答案

查看完整内容[请看2#楼]

是外部FLASH。 多谢你的建议,确实硬件设计没经验,根本不知掉电识别电路。 不过掉电只是意外情况,一般是不会掉电的。但是我写程序的时候却不得不考虑这种情况。 我现在是想在现有基础上先把程序写出来。以后PCB再改版。
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2016-11-17 09:24:42 | 显示全部楼层
你的FLASH是指STM32内部FLASH还是外接的?STM32的FLASH写次数咱按10W次来算(10W次是比较高了),能写多少天??写RAM吧,数据量由太大,,我觉得你们的规划还是有欠思考的地方。一般规定固定写多少条记录。记录满后往前覆盖(左移右移的过程),正常暂存在RAM里,加入掉电识别电路,断电时把记录写入FLASH..
shop60994719.taobao.com
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2016-11-17 08:59:19 | 显示全部楼层
密耳 发表于 2016-11-17 09:24
你的FLASH是指STM32内部FLASH还是外接的?STM32的FLASH写次数咱按10W次来算(10W次是比较高了),能写多少 ...

是外部FLASH。
多谢你的建议,确实硬件设计没经验,根本不知掉电识别电路。
不过掉电只是意外情况,一般是不会掉电的。但是我写程序的时候却不得不考虑这种情况。
我现在是想在现有基础上先把程序写出来。以后PCB再改版。
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2016-11-18 09:56:57 | 显示全部楼层
我搞错了,3楼的密耳才是最佳答案,我手滑把自己的回复设为最佳了。
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

5

主题

266

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1526
金钱
1526
注册时间
2016-7-20
在线时间
155 小时
发表于 2016-11-18 09:59:36 | 显示全部楼层
我现在在调W25Q128,刚刚拿到板子,求分享代码。215801622@qq.com
我是可以什么都不说 ,但不可以什么都不做。
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2016-12-5
在线时间
51 小时
发表于 2017-1-5 13:58:20 | 显示全部楼层
我正在调试stm32l151的板子,卡在flash几天了,可以分享下代码吗
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-1-12 03:46:25 | 显示全部楼层
因为我用的芯片型号不同,所以对文件做了微小的修改,下面附上开发板源文件:flash.c
/****************************************Copyright (c)**************************************************                        

**------------------------------------------------------------------------------------------------------
** Modified by:                       
** Modified date:       
** Version:
** Descriptions:               
********************************************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "SST25VF016B.h"

/* 移植本软件包时需要修改以下的函数或宏 */

/*******************************************************************************
* Function Name  : SPI_FLASH_Init
* Description    : 初始化控制SSI的管脚
* Input          : None
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void SPI_FLASH_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  //RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_SPI_FLASH_CS, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
                                                                  
  GPIO_InitStructure.GPIO_Pin = SPI_FALSH_CS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(SPI_FALSH_CS_PORT, &GPIO_InitStructure);

  SPI_FLASH_CS_HIGH();
  /* SPI2 Config -------------------------------------------------------------*/                                                                   
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);
  /* Enable SPI2 */
  SPI_Cmd(SPI1, ENABLE);
}


/*******************************************************************************
* Function Name  : Flash_ReadWriteByte
* Description    : 通过硬件SPI发送一个字节到SST25VF016B
* Input          : - data: 发送的数据
* Output         : None
* Return         : SST25VF016B 返回的数据
* Attention                 : None
*******************************************************************************/
uint8_t Flash_ReadWriteByte(uint8_t data)               
{
  /* Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

  /* Send byte through the SPI2 peripheral */
  SPI_I2S_SendData(SPI1, data);
   
  /* Wait to receive a byte */
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI1);                                             
}


/* 以下函数在移植时无需修改 */
/*******************************************************************************
* Function Name  : SSTF016B_RD
* Description    : SST25VF016B的读函数,可选择读ID和读数据操作
* Input          : - Dst: 目标地址,范围 0x0 - MAX_ADDR(MAX_ADDR = 0x1FFFFF)
*                  - RcvBufPt: 接收缓存的指针
*                  - NByte: 要读取的数据字节数       
* Output         : 操作成功则返回OK,失败则返回ERROR
* Return         : SST25VF016B 返回的数据
* Attention                 : 若某功能下,某一入口参数无效,可在该入口参数处填Invalid,该参数将被忽略
*******************************************************************************/
uint8_t SSTF016B_RD(uint32_t Dst, uint8_t* RcvBufPt ,uint32_t NByte)
{
        uint32_t i = 0;
        if ((Dst+NByte > MAX_ADDR)||(NByte == 0))        return (ERROR);         /*        检查入口参数 */
       
    SPI_FLASH_CS_LOW();
        Flash_ReadWriteByte(0x0B);                                                 /* 发送读命令 */
        Flash_ReadWriteByte(((Dst & 0xFFFFFF) >> 16));        /* 发送地址信息:该地址由3个字节组成        */
        Flash_ReadWriteByte(((Dst & 0xFFFF) >> 8));
        Flash_ReadWriteByte(Dst & 0xFF);
        Flash_ReadWriteByte(0xFF);                                                /* 发送一个哑字节以读取数据        */
        for (i = 0; i < NByte; i++)               
        {
       RcvBufPt[i] = Flash_ReadWriteByte(0xFF);               
        }
    SPI_FLASH_CS_HIGH();
        return (ENABLE);
}

/*******************************************************************************
* Function Name  : SSTF016B_RdID
* Description    : SST25VF016B的读ID函数,可选择读ID和读数据操作
* Input          : - IDType: ID类型。用户可在Jedec_ID,Dev_ID,Manu_ID三者里选择
* Output         : - RcvbufPt: 存储ID变量的指针
* Return         : 操作成功则返回OK,失败则返回ERROR
* Attention                 : 若填入的参数不符合要求,则返回ERROR
*******************************************************************************/
uint8_t SSTF016B_RdID(idtype IDType,uint32_t* RcvbufPt)
{
        uint32_t temp = 0;
              
        if (IDType == Jedec_ID)
        {
                SPI_FLASH_CS_LOW();       
                               
                Flash_ReadWriteByte(0x9F);                                          /* 发送读JEDEC ID命令(9Fh)        */
                    
        temp = (temp | Flash_ReadWriteByte(0x00)) << 8;  /* 接收数据 */
                temp = (temp | Flash_ReadWriteByte(0x00)) << 8;       
        temp = (temp | Flash_ReadWriteByte(0x00));              /* 在本例中,temp的值应为0xBF2541 */

        SPI_FLASH_CS_HIGH();

                *RcvbufPt = temp;
                return (ENABLE);
        }
       
        if ((IDType == Manu_ID) || (IDType == Dev_ID) )
        {
            SPI_FLASH_CS_LOW();       
               
                Flash_ReadWriteByte(0x90);                                /* 发送读ID命令 (90h or ABh) */
            Flash_ReadWriteByte(0x00);                                /* 发送地址        */
                Flash_ReadWriteByte(0x00);                                /* 发送地址        */
                Flash_ReadWriteByte(IDType);                    /* 发送地址 - 不是00H就是01H */
                temp = Flash_ReadWriteByte(0x00);            /* 接收获取的数据字节 */

        SPI_FLASH_CS_HIGH();

                *RcvbufPt = temp;
                return (ENABLE);
        }
        else
        {
                return (ERROR);       
        }
}


/*******************************************************************************
* Function Name  : SSTF016B_WR
* Description    : SST25VF016B的写函数,可写1个和多个数据到指定地址
* Input          : - Dst: 目标地址,范围 0x0 - MAX_ADDR(MAX_ADDR = 0x1FFFFF)
*                  - SndbufPt: 发送缓存区指针
*                  - NByte: 要写的数据字节数
* Output         : None
* Return         : 操作成功则返回OK,失败则返回ERROR
* Attention                 : 若某功能下,某一入口参数无效,可在该入口参数处填Invalid,该参数将被忽略
*******************************************************************************/
uint8_t SSTF016B_WR(uint32_t Dst, uint8_t* SndbufPt,uint32_t NByte)
{
        uint8_t temp = 0,StatRgVal = 0;
        uint32_t i = 0;
        if (( (Dst+NByte-1 > MAX_ADDR)||(NByte == 0) ))
        {
                return (ERROR);         /*        检查入口参数 */
        }

       
        SPI_FLASH_CS_LOW();                                 
        Flash_ReadWriteByte(0x05);                                                            /* 发送读状态寄存器命令        */
        temp = Flash_ReadWriteByte(0xFF);                                            /* 保存读得的状态寄存器值 */
        SPI_FLASH_CS_HIGH();                                                               

        SPI_FLASH_CS_LOW();                               
        Flash_ReadWriteByte(0x50);                                                            /* 使状态寄存器可写        */
        SPI_FLASH_CS_HIGH();       
               
        SPI_FLASH_CS_LOW();                               
        Flash_ReadWriteByte(0x01);                                                            /* 发送写状态寄存器指令 */
        Flash_ReadWriteByte(0);                                                                    /* 清0BPx位,使Flash芯片全区可写 */
        SPI_FLASH_CS_HIGH();                       
       
        for(i = 0; i < NByte; i++)
        {
                SPI_FLASH_CS_LOW();                               
                Flash_ReadWriteByte(0x06);                                                    /* 发送写使能命令 */
                SPI_FLASH_CS_HIGH();                       

                SPI_FLASH_CS_LOW();                                       
                Flash_ReadWriteByte(0x02);                                                     /* 发送字节数据烧写命令        */
                Flash_ReadWriteByte((((Dst+i) & 0xFFFFFF) >> 16));  /* 发送3个字节的地址信息 */
                Flash_ReadWriteByte((((Dst+i) & 0xFFFF) >> 8));
                Flash_ReadWriteByte((Dst+i) & 0xFF);
                Flash_ReadWriteByte(SndbufPt[i]);                                        /* 发送被烧写的数据        */
                SPI_FLASH_CS_HIGH();                       

                do
                {
                          SPI_FLASH_CS_LOW();                                         
                        Flash_ReadWriteByte(0x05);                                            /* 发送读状态寄存器命令 */
                        StatRgVal = Flash_ReadWriteByte(0xFF);                        /* 保存读得的状态寄存器值 */
                        SPI_FLASH_CS_HIGH();                                                       
                  }
                while (StatRgVal == 0x03 );                                                  /* 一直等待,直到芯片空闲        */

        }

        SPI_FLASH_CS_LOW();                                       
        Flash_ReadWriteByte(0x06);                                                            /* 发送写使能命令 */
        SPI_FLASH_CS_HIGH();                       

        SPI_FLASH_CS_LOW();                                       
        Flash_ReadWriteByte(0x50);                                                            /* 使状态寄存器可写        */
        SPI_FLASH_CS_HIGH();
                       
        SPI_FLASH_CS_LOW();                               
        Flash_ReadWriteByte(0x01);                                                            /* 发送写状态寄存器指令 */
        Flash_ReadWriteByte(temp);                                                             /* 恢复状态寄存器设置信息 */
        SPI_FLASH_CS_HIGH();

        return (ENABLE);               
}


/*******************************************************************************
* Function Name  : SSTF016B_Erase
* Description    : 根据指定的扇区号选取最高效的算法擦除
* Input          : - sec1: 起始扇区号,范围(0~511)
*                  - sec2: 终止扇区号,范围(0~511)
* Output         : None
* Return         : 操作成功则返回OK,失败则返回ERROR
* Attention                 : None
*******************************************************************************/
uint8_t SSTF016B_Erase(uint32_t sec1, uint32_t sec2)
{
        uint8_t  temp1 = 0,temp2 = 0,StatRgVal = 0;
    uint32_t SecnHdAddr = 0;                                 
        uint32_t no_SecsToEr = 0;                                                               /* 要擦除的扇区数目 */
        uint32_t CurSecToEr = 0;                                                              /* 当前要擦除的扇区号 */
       
        /*  检查入口参数 */
        if ((sec1 > SEC_MAX)||(sec2 > SEC_MAX))       
        {
                return (ERROR);       
        }
          
           SPI_FLASH_CS_LOW();                         
        Flash_ReadWriteByte(0x05);                                                                /* 发送读状态寄存器命令        */
        temp1 = Flash_ReadWriteByte(0x00);                                                /* 保存读得的状态寄存器值 */
        SPI_FLASH_CS_HIGH();                                                               

        SPI_FLASH_CS_LOW();                       
        Flash_ReadWriteByte(0x50);                                                                /* 使状态寄存器可写        */
        SPI_FLASH_CS_HIGH();                       

        SPI_FLASH_CS_LOW();                                                                         
        Flash_ReadWriteByte(0x01);                                                                /* 发送写状态寄存器指令        */
        Flash_ReadWriteByte(0);                                                                        /* 清0BPx位,使Flash芯片全区可写 */
        SPI_FLASH_CS_HIGH();
       
        SPI_FLASH_CS_LOW();                       
        Flash_ReadWriteByte(0x06);                                                                /* 发送写使能命令 */
        SPI_FLASH_CS_HIGH();                       

        /* 如果用户输入的起始扇区号大于终止扇区号,则在内部作出调整 */
        if (sec1 > sec2)
        {
           temp2 = sec1;
           sec1  = sec2;
           sec2  = temp2;
        }
        /* 若起止扇区号相等则擦除单个扇区 */
        if (sec1 == sec2)       
        {
                SPI_FLASH_CS_LOW();                               
                Flash_ReadWriteByte(0x06);                                                    /* 发送写使能命令 */
                SPI_FLASH_CS_HIGH();                       

            SecnHdAddr = SEC_SIZE * sec1;                                          /* 计算扇区的起始地址        */
            SPI_FLASH_CS_LOW();       
            Flash_ReadWriteByte(0x20);                                                          /* 发送扇区擦除指令 */
            Flash_ReadWriteByte(((SecnHdAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
                   Flash_ReadWriteByte(((SecnHdAddr & 0xFFFF) >> 8));
                   Flash_ReadWriteByte(SecnHdAddr & 0xFF);
                  SPI_FLASH_CS_HIGH();                       
                do
                {
                          SPI_FLASH_CS_LOW();                         
                        Flash_ReadWriteByte(0x05);                                                  /* 发送读状态寄存器命令 */
                        StatRgVal = Flash_ReadWriteByte(0x00);                          /* 保存读得的状态寄存器值        */
                        SPI_FLASH_CS_HIGH();                                                               
                  }
                while (StatRgVal == 0x03);                                              /* 一直等待,直到芯片空闲        */
                return (ENABLE);                       
        }
       
    /* 根据起始扇区和终止扇区间距调用最快速的擦除功能 */       
       
        if (sec2 - sec1 == SEC_MAX)       
        {
                SPI_FLASH_CS_LOW();                       
                Flash_ReadWriteByte(0x60);                                                          /* 发送芯片擦除指令(60h or C7h) */
                SPI_FLASH_CS_HIGH();                       
                do
                {
                          SPI_FLASH_CS_LOW();                         
                        Flash_ReadWriteByte(0x05);                                                  /* 发送读状态寄存器命令 */
                        StatRgVal = Flash_ReadWriteByte(0x00);                          /* 保存读得的状态寄存器值        */
                        SPI_FLASH_CS_HIGH();                                                               
                  }
                while (StatRgVal == 0x03);                                                  /* 一直等待,直到芯片空闲        */
                   return (ENABLE);
        }
       
        no_SecsToEr = sec2 - sec1 +1;                                                  /* 获取要擦除的扇区数目 */
        CurSecToEr  = sec1;                                                                          /* 从起始扇区开始擦除        */
       
        /* 若两个扇区之间的间隔够大,则采取8扇区擦除算法 */
        while (no_SecsToEr >= 8)
        {
                SPI_FLASH_CS_LOW();                               
                Flash_ReadWriteByte(0x06);                                                    /* 发送写使能命令 */
                SPI_FLASH_CS_HIGH();                       

            SecnHdAddr = SEC_SIZE * CurSecToEr;                                  /* 计算扇区的起始地址 */
            SPI_FLASH_CS_LOW();       
            Flash_ReadWriteByte(0x52);                                                          /* 发送32KB擦除指令 */
            Flash_ReadWriteByte(((SecnHdAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
                   Flash_ReadWriteByte(((SecnHdAddr & 0xFFFF) >> 8));
                   Flash_ReadWriteByte(SecnHdAddr & 0xFF);
                  SPI_FLASH_CS_HIGH();                       
                do
                {
                          SPI_FLASH_CS_LOW();                         
                        Flash_ReadWriteByte(0x05);                                                  /* 发送读状态寄存器命令 */
                        StatRgVal = Flash_ReadWriteByte(0x00);                          /* 保存读得的状态寄存器值        */
                        SPI_FLASH_CS_HIGH();                                                               
                  }
                while (StatRgVal == 0x03);                                                  /* 一直等待,直到芯片空闲        */
                CurSecToEr  += 8;
                no_SecsToEr -=  8;
        }
        /* 采用扇区擦除算法擦除剩余的扇区 */
        while (no_SecsToEr >= 1)
        {
                SPI_FLASH_CS_LOW();                               
                Flash_ReadWriteByte(0x06);                                                    /* 发送写使能命令 */
                SPI_FLASH_CS_HIGH();                       

            SecnHdAddr = SEC_SIZE * CurSecToEr;                                  /* 计算扇区的起始地址 */
            SPI_FLASH_CS_LOW();       
            Flash_ReadWriteByte(0x20);                                                          /* 发送扇区擦除指令 */
            Flash_ReadWriteByte(((SecnHdAddr & 0xFFFFFF) >> 16)); /* 发送3个字节的地址信息 */
                   Flash_ReadWriteByte(((SecnHdAddr & 0xFFFF) >> 8));
                   Flash_ReadWriteByte(SecnHdAddr & 0xFF);
                  SPI_FLASH_CS_HIGH();                       
                do
                {
                          SPI_FLASH_CS_LOW();                         
                        Flash_ReadWriteByte(0x05);                                                  /* 发送读状态寄存器命令 */
                        StatRgVal = Flash_ReadWriteByte(0x00);                          /* 保存读得的状态寄存器值        */
                        SPI_FLASH_CS_HIGH();                                                               
                  }
                while (StatRgVal == 0x03);                                                  /* 一直等待,直到芯片空闲 */
                CurSecToEr  += 1;
                no_SecsToEr -=  1;
        }
    /* 擦除结束,恢复状态寄存器信息 */
        SPI_FLASH_CS_LOW();                       
        Flash_ReadWriteByte(0x06);                                                                  /* 发送写使能命令 */
        SPI_FLASH_CS_HIGH();                       

        SPI_FLASH_CS_LOW();                       
        Flash_ReadWriteByte(0x50);                                                                  /* 使状态寄存器可写 */
        SPI_FLASH_CS_HIGH();                       
        SPI_FLASH_CS_LOW();                       
        Flash_ReadWriteByte(0x01);                                                                  /* 发送写状态寄存器指令 */
        Flash_ReadWriteByte(temp1);                                                                  /* 恢复状态寄存器设置信息 */
        SPI_FLASH_CS_HIGH();   
        return (ENABLE);
}


/*******************************************************************************
* Function Name  : SPI_FLASH_Test
* Description    : 读取SST25VF016B ID
* Input          : None
* Output         : None
* Return         : None
* Attention                 : None
0x00BF258E 查看ChipID的值是否0xBF258E
*******************************************************************************/
void SPI_FLASH_Test(void)
{
    uint32_t  ChipID = 0;
          SSTF016B_RdID(Jedec_ID, &ChipID);                                   /*  单步运行到此处时, 在Watch里*/

        ChipID &= ~0xff000000;                                                                        /*  仅保留低24位数据            */
        if (ChipID != 0x00BF2541)
         {                                                                                        /*  ID不正确进入死循环          */
           while(1);
    }
}

/*********************************************************************************************************
      END FILE
*********************************************************************************************************/
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-1-12 03:46:53 | 显示全部楼层
flash.h
/****************************************Copyright (c)**************************************************
**
**                                 http://www.powermcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name:                         SST25VF016B.h
** Last modified Date:         2010-10-29
** Last Version:                 1.0
** Descriptions:                 SPI flash 操作函数
**
**------------------------------------------------------------------------------------------------------
** Created          By:                 AVRman
** Created date:                 2010-10-29
** Version: 1.0
** Descriptions:                 First version
**
**------------------------------------------------------------------------------------------------------
** Modified by:        
** Modified date:        
** Version:
** Descriptions:         
**
********************************************************************************************************/

#ifndef __SST25VF016B_H
#define __SST25VF016B_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Private typedef -----------------------------------------------------------*/
/* 定义操作SST25VF016B所需的数据 */
typedef enum ERTYPE{Sec1,Sec8,Sec16,Chip} ErType;  
typedef enum IDTYPE{Manu_ID,Dev_ID,Jedec_ID} idtype;

/* Private define ------------------------------------------------------------*/
#define MAX_ADDR                0x1FFFFF        /* 定义芯片内部最大地址 */
#define        SEC_MAX             511         /* 定义最大扇区号 */
#define SEC_SIZE                0x1000      /* 扇区大小        */

/* 宏,用于定义SST25VF016B的片选引脚 */
#define RCC_APB2Periph_GPIO_SPI_FLASH_CS      RCC_APB2Periph_GPIOB
#define SPI_FALSH_CS_PORT                     GPIOB
#define SPI_FALSH_CS_PIN                      GPIO_Pin_0

#define SPI_FLASH_CS_LOW()       GPIO_ResetBits(GPIOB, GPIO_Pin_0)
#define SPI_FLASH_CS_HIGH()      GPIO_SetBits(GPIOB, GPIO_Pin_0)

/* Private function prototypes -----------------------------------------------*/
void  SPI_FLASH_Init(void);
uint8_t SSTF016B_RD(uint32_t Dst, uint8_t* RcvBufPt ,uint32_t NByte);
uint8_t SSTF016B_RdID(idtype IDType,uint32_t* RcvbufPt);
uint8_t SSTF016B_WR(uint32_t Dst, uint8_t* SndbufPt,uint32_t NByte);

uint8_t SSTF016B_Erase(uint32_t sec1, uint32_t sec2);
void SPI_FLASH_Test(void);
void df_write_open(uint32_t addr);
void df_write(uint8_t *buf,uint16_t size);
void df_read(uint8_t *buf,uint16_t size);
void df_read_open(uint32_t addr);
void df_write_close(void);

#endif
/*********************************************************************************************************
      END FILE
*********************************************************************************************************/

君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-1-12 03:47:30 | 显示全部楼层
Flashdrive.c
/****************************************Copyright (c)**************************************************                        
---------------------------------------------------------------------------------------------------
** Created by:                        AVRman
** Created date:                2010-10-29
** Version:                                1.0
** Descriptions:                The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:                       
** Modified date:       
** Version:
** Descriptions:               
********************************************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "SST25VF016B.h"
#include "FlashDriver.h"

/* Private variables ---------------------------------------------------------*/
static uint32_t CurReadAddr;        /* 当前读的地址 */
static uint32_t CurWriteAddr;        /* 当前写页地址        */

/*******************************************************************************
* Function Name  : df_read_open
* Description    : 读初始化功能函数
* Input          : - addr: 打开后读到的初始地址
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_read_open(uint32_t addr)
{
  CurReadAddr=addr;        /* 当前读的地址        */
}


/*******************************************************************************
* Function Name  : df_write_open
* Description    : 写初始化功能函数
* Input          : - addr: 要写的初始地址
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_write_open(uint32_t addr)
{
CurWriteAddr=addr;        /* 当前写地址 */
}

/*******************************************************************************
* Function Name  : df_read
* Description    : 读FLASH函数
* Input          : - buf: 接受数据的指针
*                  - size: 读取数据的大小
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_read(uint8_t *buf,uint16_t size)
{
  if( CurReadAddr + size <= MAX_ADDR )
  {
    SSTF016B_RD(CurReadAddr,buf,size);
    CurReadAddr+=size;
  }
}

/*******************************************************************************
* Function Name  : df_write
* Description    : 写FLASH函数
* Input          : - buf: 写数据的指针
*                  - size: 要写数据的大小
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_write(uint8_t *buf,uint16_t size)
{
  if( CurWriteAddr + size <= MAX_ADDR )
  {
    SSTF016B_WR(CurWriteAddr,buf,size);
    CurWriteAddr+=size;
  }
}

/*******************************************************************************
* Function Name  : df_read_seek
* Description    : 调整读取FLASH的地址       
* Input          : - addr: 新的地址
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_read_seek(uint32_t addr)
{
df_read_close();
df_read_open(addr);
}

/*******************************************************************************
* Function Name  : df_write_seek
* Description    : 调整写FLASH的地址
* Input          : - addr: 新的地址
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_write_seek(uint32_t addr)
{
df_write_close();
df_write_open(addr);
}

/*******************************************************************************
* Function Name  : df_read_close
* Description    : None
* Input          : None
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_read_close(void)
{
/* 此处不做任何处理 */
}

/*******************************************************************************
* Function Name  : df_write_close
* Description    : None
* Input          : None
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
void df_write_close(void)
{
}

/*********************************************************************************************************
      END FILE
*********************************************************************************************************/
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-1-12 03:47:56 | 显示全部楼层
Flashdrive.h
/****************************************Copyright (c)**************************************************
**
**                                 http://www.powermcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name:                         FlashDriver.h
** Last modified Date:         2010-10-29
** Last Version:                 1.0
** Descriptions:                 SPI flash 功能函数
**
**------------------------------------------------------------------------------------------------------
** Created          By:                 AVRman
** Created date:                 2010-10-29
** Version: 1.0
** Descriptions:                 First version
**
**------------------------------------------------------------------------------------------------------
** Modified by:        
** Modified date:        
** Version:
** Descriptions:         
**
********************************************************************************************************/
#ifndef __FLASHDRIVER_H
#define __FLASHDRIVER_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Private function prototypes -----------------------------------------------*/
void df_read_open(uint32_t addr);
void df_write_open(uint32_t addr);
void df_read(uint8_t *buf,uint16_t size);
void df_write(uint8_t *buf,uint16_t size);
void df_read_seek(uint32_t addr);
void df_write_seek(uint32_t addr);
void df_read_close(void);
void df_write_close(void);

#endif
/*********************************************************************************************************
      END FILE
*********************************************************************************************************/

君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-1-12 03:48:42 | 显示全部楼层
1005934646 发表于 2017-1-5 13:58
我正在调试stm32l151的板子,卡在flash几天了,可以分享下代码吗

代码贴在下面4个楼层了
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2016-12-5
在线时间
51 小时
发表于 2017-1-12 11:02:24 | 显示全部楼层
XUZJWWSZ 发表于 2017-1-12 03:48
代码贴在下面4个楼层了

多谢你的分享,大赞
回复

使用道具 举报

6

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
182
金钱
182
注册时间
2015-6-13
在线时间
19 小时
发表于 2017-2-16 13:26:51 | 显示全部楼层
本帖最后由 隨颩洏過 于 2017-2-16 13:28 编辑

楼主您好!
      我现在要做的项目也遇到你说的这样的问题:上位机软件不定期向我获取flash里的信息。它的指令里会给我两个时间参数,我要把这段时间内的历史数据发给上位机。想问一下你是怎么解决这个问题的呢?我也是用的外部Flash,要按时间点作为索引读取历史数据,跟你的要求一样!能指点一下吗?非常感谢!
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-2-17 13:54:44 | 显示全部楼层
隨颩洏過 发表于 2017-2-16 13:26
楼主您好!
      我现在要做的项目也遇到你说的这样的问题:上位机软件不定期向我获取flash里的信息。它的 ...

存入flash的每条信息都带着时间。先假设没有掉电的情况,每条信息在FLASH的存储地址和时间是一一对应的。
也就是说假如你最近一次存储数据的时间是t,那么在t之前的任何时间段T1到T2之间,都会有对应的地址段ADDR1到ADDR2。
如果有掉电呢?ADDR1和ADDR2会向你最近一次存储数据的地址偏移一定量。
所以我的思路是根据时间段算出地址区间,取得区间边界的时间与命令中的时间段作比较,如果吻合直接从地址段中取数据回应。如果不吻合就把地址段整体偏移,然后在取地址边界的时间作比较,这个过程用了二分法。
本着回应的数据只多不少的原则,我这样做暂时达到了目的。
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 09:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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