打印
[其他ST产品]

flash 模拟eeprom

[复制链接]
440|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ead5ah|  楼主 | 2023-1-29 17:02 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
STM32 的页擦除顺序为:

 检查 FLASH_CR 的 LOCK 是否解锁,如果没有则先解锁

 检查 FLASH_SR 寄存器的 BSY 位,以确认没有其他正在进行的闪存操作

 设置 FLASH_CR 寄存器的 PER 位为’1’

 用 FLASH_AR 寄存器选择要擦除的页

 设置 FLASH_CR 寄存器的 STRT 位为’1’

 等待 BSY 位变为’0’

 读出被擦除的页并做验证

void        Up_E2Data(u32 e2address)                 //更新flash参数数据
{
        u8  i=0;
        if(Flag_UpdataE2)                //接收到新的参数
        {
                Flag_UpdataE2=0;
                 if(FLASH->CR&(1<<7))                        //解锁
                {
                        FLASH->KEYR=0x45670123;
                        FLASH->KEYR=0xCDEF89AB;
                }
                FLASH->CR|=1<<1;                           //擦除指定页数据,为新的数据作准备
                FLASH->AR=e2address;
                FLASH->CR|=1<<6;
                while(FLASH->SR&(1<<0));
            FLASH->CR&=~(1<<1);
                FLASH->CR|=1<<0;
                while(FLASH->SR&(1<<0));
                                                  //写如新的数据
                while(i<2)                                  //写如新的数据
                {
                        while(FLASH->SR&(1<<0));
                        *(volatile u16 *)e2address=Parameter[i];
                        e2address+=2;
                        i++;       
                }
                FLASH->CR&=~(1<<0);
                FLASH->CR|=1<<7;                        //加锁,防止误操作
        }
}



————————————————
版权声明:本文为CSDN博主「位文杰TOP」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36958104/article/details/102497422

使用特权

评论回复
沙发
ead5ah|  楼主 | 2023-1-29 17:03 | 只看该作者
下面我们重点介

绍一下 STMFLASH_Write 函数,该函数用于在 STM32 的指定地址写入指定长度的数据,该函

数的实现基本类似第 29 章的 W25QXX_Write 函数,不过该函数对写入地址是有要求的,必须

保证以下两点:

1, 该地址必须是用户代码区以外的地址。

2, 该地址必须是 2 的倍数。

条件 1 比较好理解,如果把用户代码给卡擦了,可想而知你运行的程序可能就被废了,从

而很可能出现死机的情况。条件 2 则是 STM32 FLASH 的要求,每次必须写入 16 位,如果你写

的地址不是 2 的倍数,那么写入的数据,可能就不是写在你要写的地址了。

另外,该函数的 STMFLASH_BUF 数组,也是根据所用 STM32 的 FLASH 容量来确定的,

战舰 STM32 开发板的 FLASH 是 512K 字节,所以 STM_SECTOR_SIZE 的值为 512,




//要写入到STM32 FLASH的字符串数组
const u8 TEXT_Buffer[]={"STM32F103 FLASH TEST"};
#define SIZE sizeof(TEXT_Buffer)        //数组长度
#define FLASH_SAVE_ADDR  0X08070000        //设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)

使用特权

评论回复
板凳
ead5ah|  楼主 | 2023-1-29 17:07 | 只看该作者
FLASH的大小计算

在Keil MDK编译器编译后,信息栏都会显示编译情况,这其中就包含了FLASH跟SRAM的信息。如下图所示,

一方面它也说明程序在编译后会把相同性质的数据(比如变量,其中包括局部变量和全局变量。当然其中也包括代码)归放到同一域里面。

使用特权

评论回复
地板
ead5ah|  楼主 | 2023-1-29 17:24 | 只看该作者
/*********************************************************************************************/

查看FLASH跟SRAM的占用空间问题主要看下面的语句。

Program Size: Code=29864 RO-data=123592 RW-data=60 ZI-data=3900

/*********************************************************************************************/

其中 要着重注意的是Code、RO-data、RW-data、ZI-data所代表的意思

Code:即代码域,它指的是编译器生成的机器码,它被存储在ROM区。也表示程序所占用 FLASH 的大小( FLASH)。

使用特权

评论回复
5
ead5ah|  楼主 | 2023-1-29 17:27 | 只看该作者
RO-data:即 Read Only-data,只读数据区, 它被存储在ROM区。表示程序定义的常量,如 const 类型( FLASH)。


RW-data:即 Read Write-data,可读可写数据区,它被存储在ROM区, 表示已被初始化的全局变量(这里的初始值是指非0值)( SRAM)



ZI-data:即 Zero Initialie data, 0初始化数据,它被存储在RAM区,表示未被初始化的全局变量(SRAM)

使用特权

评论回复
6
ead5ah|  楼主 | 2023-1-29 17:30 | 只看该作者
注:在查阅野火的<<零死角玩转STM32>>电子书的 “程序的组成、存储于运行” 这个章节时,发现还有一个区会被忽略,也许在查看了上面几个存储区域后,会发现在 RW-data 和 ZI-data 这两个区域都存储在RAM中,存储的都是全局变量,那么局部变量存储在哪里呢?答案是:存储在ZI-data 的栈空间(Stack)及堆空间(Heap)。

使用特权

评论回复
7
ead5ah|  楼主 | 2023-1-30 23:45 | 只看该作者
ZI-data 的栈空间(Stack)及堆空间(Heap):在 C 语言中,函数内部定义的局部变量属于栈空间,进入函数的时候从向栈空间申请内存给局部变量,退出时释放局部变量,归还内存空间。而使用 malloc 动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于 ZI-data 区域的,这些空间都会被初始值化为 0值。编译器给出的 ZI-data占用的空间值中包含了堆栈的大小(经实际测
试,若程序中完全没有使用 malloc 动态申请堆空间,编译器会优化,不把堆空间计算在内)

使用特权

评论回复
8
ead5ah|  楼主 | 2023-1-30 23:49 | 只看该作者
/*********************************************************************************************/

那么FLASH和SRAM占用情况的计算方式如下所示:

flash = Code + RO-data + RW-data = 29864 + 123592 + 60 = 153516 bytes

sram = RW-data + ZI-data = 60+ 3900= 3960bytes

还有一个要特别注意的是程序的大小不是.hex文件的大小,而是编译结果的Code+RO-data。

在程序初始化的时候,RW-data会从FLASH中拷贝到RAM中。

使用特权

评论回复
9
ead5ah|  楼主 | 2023-1-30 23:55 | 只看该作者
程序编译完成

对STM32容量选型或者 计算FLASH 充当EEPROM起始地址时会用到此参数。

按照下面截图  程序空间 = (16700+732+4580)/1024 = 21.5K

使用特权

评论回复
10
ead5ah|  楼主 | 2023-1-30 23:55 | 只看该作者
但需要注意的是  程序的起始地址 为0x08000000,所以 flash的 起始地址 必须是 0x08000000 + 0x55FC(22012的16进制)  = 0x080055FC之后


使用特权

评论回复
11
ead5ah|  楼主 | 2023-1-30 23:59 | 只看该作者
其余的空间都可以作为 其他功能使用。
程序的调试的小方法,

如果判断程序出问题了,在某一块,可以添加



程序块

while(1); //将程序停留在此处  检测运行到此处是否出了问题,可一步一步的排除

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

86

帖子

1

粉丝