OpenEdv-开源电子网

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

STM32内部存储数据问题

[复制链接]

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
发表于 2016-10-24 21:32:53 | 显示全部楼层 |阅读模式
2金钱
最近在做一个项目,用到STM32的Flash操作,具体内容是每次上电或者复位的时候读取Flash存储数据的区域,这片数据要求是根据用户的输入来填入数据,所以要求第一次上电的时候,也就是第一次程序下载运行的那次这片数据全部填0,以后上电或者复位的时候直接读取上次保存的数据就可以,达到保存数据的目的,现在的问题是第一次上电读数据的时候,需要的那片数据全为1,所以读出来也是1,所以在读数据之前要对数据进行清零,但是这样做之后每一次都会执行数据清零操作,没法读取上次的用户输入的数据,谁有好的办法?

最佳答案

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

数据区增加一个标志字节,非0xAA时即视为存储区未初始化过,以后每次写存储区时确保标志字节为0xAA
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-10-13
在线时间
9 小时
发表于 2016-10-24 21:32:54 | 显示全部楼层
数据区增加一个标志字节,非0xAA时即视为存储区未初始化过,以后每次写存储区时确保标志字节为0xAA
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-10-24 23:08:22 | 显示全部楼层
这、、、直接参考原子哥AT24CXX程序
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 08:58:00 | 显示全部楼层
龙之谷 发表于 2016-10-24 23:08
这、、、直接参考原子哥AT24CXX程序

STM32内部flash存储数据,并不是在外部的存储芯片存储数据
回复

使用道具 举报

7

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
325
金钱
325
注册时间
2016-10-21
在线时间
43 小时
发表于 2016-10-25 09:07:03 | 显示全部楼层
第一次程序下载运行时,没有使用到的FLASH为全1,因为FLASH擦除后的数据为1,不是0。上电后程序读取数据,如果全为1则要写入新数据,如果不为1,则为用户写入的数据。
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 09:15:23 | 显示全部楼层
dalarang 发表于 2016-10-25 08:23
数据区增加一个标志字节,非0xAA时即视为存储区未初始化过,以后每次写存储区时确保标志字节为0xAA

write_falsh(0x55);//第一次烧写的时候执行,之后永远不执行,这个如何实现???
read_flash();
if(flag==0x55)//无论那次运行都会进行
{
     write_zero();//清零操作
    write_flash(0xAA);
}
while(1){task()};
回复

使用道具 举报

10

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1479
金钱
1479
注册时间
2016-1-25
在线时间
260 小时
发表于 2016-10-25 09:39:37 | 显示全部楼层
write_falsh(0x55);//第一次烧写的时候执行,之后永远不执行,这个如何实现???  你可以在这个程序里面设置一个static 静态变量直接初始化为0 【static u8  first=0;】  这样执行一次后就将变量置1  之后的程序去判断如果为1 就会跳过这个write_falsh(0x55)函数。 因为static 静态变量的话  不会因为你复位后改变变量的值  只会存储你最后一次保存的变量值
回复

使用道具 举报

5

主题

121

帖子

0

精华

高级会员

Rank: 4

积分
621
金钱
621
注册时间
2016-1-26
在线时间
150 小时
发表于 2016-10-25 09:40:23 | 显示全部楼层
首先是存储有效数据的时候加个包头包尾标志,如0x0D0A,每次读取Flash时就根据是否读到0D0A来判断返回一个是否读取成功,第二步就是,在第一次download操作时先全部擦除再下载,程序初始化时读取Flash,如果不成功,则将Flash重新存入全0,这样就实现了!
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 10:17:23 | 显示全部楼层
无休 发表于 2016-10-25 09:40
首先是存储有效数据的时候加个包头包尾标志,如0x0D0A,每次读取Flash时就根据是否读到0D0A来判断返回一个是 ...

读取Flash已经成功了,就是上电的时候需要程序区清flash,否则数据全为1
flash.png
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-10-25 10:37:55 | 显示全部楼层
这是FF ,怎么能叫 1。
读的时候判断,一个不够就判断2个,不行就判断10个
我有故事,你有酒吗
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 11:18:27 | 显示全部楼层
来俩不甜的 发表于 2016-10-25 10:37
这是FF ,怎么能叫 1。
读的时候判断,一个不够就判断2个,不行就判断10个

显示F是因为16进制的原因,我说的1是每一bit,读的时候判断不是因为不够,是希望上电或者复位的时候flash的某一段初始化为0.
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 11:21:47 | 显示全部楼层
sodermalm 发表于 2016-10-25 09:39
write_falsh(0x55);//第一次烧写的时候执行,之后永远不执行,这个如何实现???  你可以在这个程序里面设 ...

我测试了一下,声明了一个static的变量,但是每次上上电还是会被初始化,现在试试使用分散文件加载一个NO_INIT的数据。
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 11:25:05 | 显示全部楼层
“可以通过在汇编文件中定义一个数据段并初始化,在链接脚本中将这个段指定到固定地址的方式来实现"
这个是另一个人给的解决方案,有兴趣的可以试一下,我有结果了也会贴出来。
回复

使用道具 举报

10

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1479
金钱
1479
注册时间
2016-1-25
在线时间
260 小时
发表于 2016-10-25 13:49:11 | 显示全部楼层
王秀峰 发表于 2016-10-25 11:21
我测试了一下,声明了一个static的变量,但是每次上上电还是会被初始化,现在试试使用分散文件加载一个NO ...

static这个关键字,用这个关键字定义的变量,其值会保存,下次再执行这个函数的时候。不会被初始化。也就是说有点类似与全局变量,值是会保存上一次赋值过后的值。  你可以去看看原子哥里面的key程序就是这么做的  static u8 key=1;
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-25 14:17:06 | 显示全部楼层
sodermalm 发表于 2016-10-25 13:49
static这个关键字,用这个关键字定义的变量,其值会保存,下次再执行这个函数的时候。不会被初始化。也就 ...

单片机上电的时候,数据会从flash搬到RAM里面,并初始化,和是不是static没有关系,static在C语言里面有两种用法,第一种用法是用来修饰局部变量,形成静态局部变量,和非静态局部变量的本质区别是存储类不同;非静态局部变量分配在栈上,而静态局部变量分配在数据段或bss段。第二种用法修饰全局变量,形成静态全局变量,和非静态全局变量的区别在于链接属性的不同。
回复

使用道具 举报

10

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1479
金钱
1479
注册时间
2016-1-25
在线时间
260 小时
发表于 2016-10-25 15:13:53 | 显示全部楼层
王秀峰 发表于 2016-10-25 14:17
单片机上电的时候,数据会从flash搬到RAM里面,并初始化,和是不是static没有关系,static在C语言里面有 ...

那就不是很清楚了。我是同常用到flash的话  都是会先算下程序的大小  然后把需要存入的数据分配固定的地址和 在一个地址里面写入一个固定的标志位  开机就先读这个标志位 如果标志位处于被置位的话 就不执行那段只执行一次的函数  这样就可以实现你所说的功能了  而且这个在从新烧写程序的时候也不会把设置擦除掉   所以从新擦除程序后也不要在设置
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-10-25 16:23:29 | 显示全部楼层
王秀峰 发表于 2016-10-25 11:18
显示F是因为16进制的原因,我说的1是每一bit,读的时候判断不是因为不够,是希望上电或者复位的时候flash ...

这问题就来了。用flash就是希望上电时保存断电时的值。而你却希望上电时值为0,那为何不直接用数组。按你说的,你本来就没打算用上一次的值
我有故事,你有酒吗
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-10-25 16:25:38 | 显示全部楼层
而且按你的要求,感觉这个数组会多次的更改,这你就要小心了。flash是有读写寿命的,具体多少次不清楚
我有故事,你有酒吗
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-27 20:24:59 | 显示全部楼层
来俩不甜的 发表于 2016-10-25 16:23
这问题就来了。用flash就是希望上电时保存断电时的值。而你却希望上电时值为0,那为何不直接用数组。按你 ...

只需要第一次烧程序上电的时候为零,之后一直保留用户更新的数据
回复

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-3-31
在线时间
9 小时
 楼主| 发表于 2016-10-27 20:28:30 | 显示全部楼层
来俩不甜的 发表于 2016-10-25 16:25
而且按你的要求,感觉这个数组会多次的更改,这你就要小心了。flash是有读写寿命的,具体多少次不清楚

大概有10w
回复

使用道具 举报

8

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2020-3-6
在线时间
26 小时
发表于 2020-3-6 11:11:13 | 显示全部楼层
想问一下楼主 解决了吗
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-26 16:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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