OpenEdv-开源电子网

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

atm32怎么方便的将一个结构体存入flash并且原样读写出来

[复制链接]

35

主题

181

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1115
金钱
1115
注册时间
2016-8-1
在线时间
235 小时
发表于 2017-9-2 10:54:59 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 rindy 于 2017-9-2 11:53 编辑

假如有这样一个结构体数组,怎么存入flash呢,并且原样读写出来,之前只写过一些简单变量的存储与读写操作,不知道结构体怎么操作
struct User   
{
        char  user_physical[20];
        char  user_custom[20];
        char user_pa[20];
        char user_flag;
};
struct   User      user1[60];//添加60条数据,现在要把这60条结构体数据存放到flash需要怎么操作?

最佳答案

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

存进去的话,可以使用指针来操作 比如:struct User *user1 ; u8 *p; p=(U8*)user1; 在使用单字节写入时候 write_data(*p++); 这种写法是 把新的指针指向结构体的初始位置 然后按照u8类型进行存储。p++每次偏移一个字节。不过需要注意的是,你不能越界了,也就是循环写入的次数最多时sizeof(struct User); 读出来就好办了。先放到一个buff里面 然后再赋值到各个变量。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-9-2 10:55:00 | 显示全部楼层
存进去的话,可以使用指针来操作

比如:struct User  *user1  ;

u8 *p;
p=(U8*)user1;      
在使用单字节写入时候     write_data(*p++);   这种写法是 把新的指针指向结构体的初始位置

然后按照u8类型进行存储。p++每次偏移一个字节。不过需要注意的是,你不能越界了,也就是循环写入的次数最多时sizeof(struct User);

读出来就好办了。先放到一个buff里面   然后再赋值到各个变量。
自己选择的路,成家前走完。
回复

使用道具 举报

35

主题

181

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1115
金钱
1115
注册时间
2016-8-1
在线时间
235 小时
 楼主| 发表于 2017-9-2 12:06:41 | 显示全部楼层
aiyeba 发表于 2017-9-2 11:52
存进去的话,可以使用指针来操作

比如:struct User  *user1  ;

嗯嗯,就是再想问一下用你这种方式读出来的时候都存放到一个buf中,那怎么一次给结构体赋值呢,因为结构体各个成员变量都不一样有可能,包括长度什么的
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2017-9-2 12:20:11 | 显示全部楼层
[mw_shl_code=c,true]//flash 操作函数
void write_flash(int write_addr,char *write_buff,int write_size);
void read_flash(int read_addr,char *read_buff,int read_size);

struct  User  user1[60]
//写全部
write_flash(0,(char*)user1),sizeof(user1);
//读全部
read_flash(0,(char*)user1),sizeof(user1);[/mw_shl_code]
回复

使用道具 举报

35

主题

181

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1115
金钱
1115
注册时间
2016-8-1
在线时间
235 小时
 楼主| 发表于 2017-9-2 12:33:20 | 显示全部楼层
Acuity 发表于 2017-9-2 12:20
[mw_shl_code=c,true]//flash 操作函数
void write_flash(int write_addr,char *write_buff,int write_siz ...

感觉这个意思是不是就是把整个结构体数组看成一个大数组,写也是从开始地址一个字节一个字节的写到flash,读也是一个字节一个字节的读出来然后从开始地址一个个把读出来的放进去
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2017-9-2 13:33:05 | 显示全部楼层
1、可以这么通俗地理解,flash不支持单字节操作吧,一般是整页或者块操作;
2、专业解析是计算机内存存储原则,不管是什么变量、结构体(自定义的、C标准的。。。)等,使用时,本质是获取系统的一段内存(1字节、2字节、n字节等),然后操作内存内存放的内容,指针就表示这段内存的地址,理解这个了,指针也理解了。
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2017-9-2 13:45:33 | 显示全部楼层
rindy 发表于 2017-9-2 12:06
嗯嗯,就是再想问一下用你这种方式读出来的时候都存放到一个buf中,那怎么一次给结构体赋值呢,因为结构 ...

这样的操作方式必须强制结构体单字节内存对齐,否则用一个char(uchar)类型的buff操作会导致数据不正确。
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-9-2 14:31:38 | 显示全部楼层
rindy 发表于 2017-9-2 12:06
嗯嗯,就是再想问一下用你这种方式读出来的时候都存放到一个buf中,那怎么一次给结构体赋值呢,因为结构 ...

感觉你对指针的理解不是很够哦。你怎么说也是一个太阳了。

如另外一个老铁和你说的。flash操作都是页操作或者块操作。不过底层也是一个个字节写入的,(可以参考以下原子哥的EEPROM来理解一下)。这种函数的接口往往给的是buff,但是如果是结构体呢?其实用强制转换就可以了。

可以这么理解,结构体里面有u8、u16、u32的和数组的各种类型的。但是最基本的还是u8
如果你flash里面存的数据刚好每一个字节都是和我的结构体对齐,那么数据就不会乱的。
也就是你按什么类型存的,到时候按什么类型来取就可以了。(地址对齐)
举例说明。flash地址0到6   你存的是  0x11   0x22  0x33   0x44 0x55 0x66 0x77
(特别记住:这7个字节可以是任意类型拆分存进来的)

不同的取法,会得到不同的值。
如果你按照u8来去  那么打印的就是7个字节

如果你按照  u16来取  那么打印的就是0x1122  0x3344  0x5566  0x77??(注意大小端)

u32你自己想咯

这个又怎么理解呢?   u8 buff[7]={0x11,0x22,0x33,0x44,0x55,0x66,0x77};

u16 *p;   p=(u16 *)buff;  printf("0x%04x\r\n",*p++);  这个循环3次就越界了。








自己选择的路,成家前走完。
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-9-2 14:43:12 | 显示全部楼层
本帖最后由 aiyeba 于 2017-9-2 14:45 编辑

u8 *p;      struct User  *user1;

p=(u8*)user1;           假如你有取出来的数组buff[60];

for(i=0;i<(sizeof(struct User));i++)
{
    *p++=buff;
}
自己选择的路,成家前走完。
回复

使用道具 举报

0

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
206
金钱
206
注册时间
2017-8-29
在线时间
32 小时
发表于 2017-9-2 15:46:27 | 显示全部楼层
本帖最后由 hstar 于 2017-9-2 15:50 编辑

用共用体来解决存储的问题。很简单
[mw_shl_code=c,true]typedef union User {
    struct{
                char  user_physical[20];
        char  user_custom[20];
        char user_pa[20];
        char user_flag;
    }Source;
    char all[20+20+20+1];
}USAER;

USAER user[10];

user.all[0][0] =1;
printf("%d\r\n",user.Source.user_physical[0]);[/mw_shl_code]

输出结果是1所以只需要写入共用体的user.all,这样就能把结构体写入了。

共用体的内存空间是共享的,反正就当一个数组读取存储就可以了。
回复

使用道具 举报

35

主题

181

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1115
金钱
1115
注册时间
2016-8-1
在线时间
235 小时
 楼主| 发表于 2017-9-2 16:06:17 | 显示全部楼层
本帖最后由 rindy 于 2017-9-2 16:54 编辑
aiyeba 发表于 2017-9-2 14:31
感觉你对指针的理解不是很够哦。你怎么说也是一个太阳了。

如另外一个老铁和你说的。flash操作都是页 ...

大虾,这块内容确实自己不怎么扎实(主要之前用得少),这次遇到实际问题了(这次一定要把这块内容啃精了),自己现在也在看这方面的内容,我自己现在是这样一个思路,您看行不行,现在不是struct   User      user1[60];     我定义一个指向结构体数组的指针p,开始地址就是user1[60]的首地址,然后通过这个函数来存入flash,您觉得可以吗

void flashWriteSysData(User *p)//传进来的p已经指向了user1[60]的首地址
{
  u8 i = 0;
  u8 temp = 0;
  for(i=0;i<60;i++)//总共循环60次,因为有60个元素
  {
    for(j=0;j<61;j++)//一个结构体数组元素占61(20+20+20+1)个字节
    {
        //这里就是将每个元素的61个字节依次写入到flash中                

         memcpy(&temp,   *((uint8_t *)p+j),  1);                            //从当前指针指向的结构体元素所在内存中拷贝一个byte        

        FLASH_ProgramByte(SYS_DATA_ADDR,temp);            //写入这个byte

        
SYS_DATA_ADDR=SYS_DATA_ADDR+2;                     //stm32的flash地址必须是2的倍数
         
    }
    p++;
  }
}




回复

使用道具 举报

35

主题

181

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1115
金钱
1115
注册时间
2016-8-1
在线时间
235 小时
 楼主| 发表于 2017-9-2 16:19:07 | 显示全部楼层
hstar 发表于 2017-9-2 15:46
用共用体来解决存储的问题。很简单
[mw_shl_code=c,true]typedef union User {
    struct{

貌似不错的样子
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-9-2 17:00:12 | 显示全部楼层
rindy 发表于 2017-9-2 16:06
大虾,这块内容确实自己不怎么扎实(主要之前用得少),这次遇到实际问题了(这次一定要把这块内容啃精了 ...

我在确认一下给你答复,不然,误人子弟了。
自己选择的路,成家前走完。
回复

使用道具 举报

10

主题

266

帖子

0

精华

高级会员

Rank: 4

积分
693
金钱
693
注册时间
2017-7-27
在线时间
98 小时
发表于 2017-9-2 20:02:57 | 显示全部楼层
还是好好的看看书吧,把基础知识学扎实,给你推荐[C程序设计(第四版)].谭浩强的,结构体那章节,里面讲解很清楚
回复

使用道具 举报

35

主题

181

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1115
金钱
1115
注册时间
2016-8-1
在线时间
235 小时
 楼主| 发表于 2017-9-4 07:58:20 | 显示全部楼层
huanghan 发表于 2017-9-2 20:02
还是好好的看看书吧,把基础知识学扎实,给你推荐[C程序设计(第四版)].谭浩强的,结构体那章节,里面讲解很 ...

正在边看边做,书是一直放在桌边的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 14:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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