OpenEdv-开源电子网

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

FLASH编程实验—每次写入数组数据再读取,前面4个字节都会丢失

[复制链接]

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2018-8-8
在线时间
50 小时
发表于 2019-12-31 09:33:00 | 显示全部楼层 |阅读模式
30金钱
我创建了一个数组u8 data[]={"abcdefghijklmn"}; 先把该数组的数据写入flash的0x08010000,然后读取。
第一次读取得到的数据为abcdefghijklmn,正确。但是再次写入,读取后,前面的四个字节就会丢失,变成了efghijklmn;
然后重复写入、读取,就会变成ijklmn。。。mn。。。
最后一直是mn。求各位大佬帮忙看看。。。
下面上代码:

————————————————————————————————————————————————————————————————————
main函数:

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "key.h"
  6. #include "lcd.h"
  7. #include "sdram.h"
  8. #include "stmflash.h"

  9. int main(void)
  10. {
  11.                 u8 key;                 
  12.                 u8 i=0;             
  13.           u8 data[]={"abcdefghijklmn"};
  14.           #define SIZE sizeof(data)/4+((sizeof(data)%4)?1:0)
  15.                 u8 buff[SIZE];

  16.     HAL_Init();   
  17.     Stm32_Clock_Init(360,25,2,8);
  18.     delay_init(180);
  19.     uart_init(115200);
  20.     LED_Init();
  21.     KEY_Init();
  22.     SDRAM_Init();
  23.                 LCD_Init();
  24.                
  25.                 LCD_Clear(WHITE);
  26.                 POINT_COLOR=RED;
  27.                 BACK_COLOR=0xffff;
  28.                 LCD_ShowString(10,30,260,32,32,"Apollo STM32F429");
  29.                 LCD_ShowString(10,70,192,32,32,"FLASH TEST");
  30.                 POINT_COLOR=BLUE;
  31.                 printf("%d,%d\r\n",sizeof(data),sizeof(buff));
  32.         while(1)
  33.         {
  34.                 printf("1-%s\r\n",buff);
  35.                 key=KEY_Scan(0);´       
  36.                 if(key==KEY0_PRES)
  37.                 {
  38.                         FlashRead(0x08010000,(u32*)buff,SIZE);
  39.                         LCD_ShowString(10,130,192,16,16,buff);
  40.                         printf("2-%s\r\n",buff);
  41.                 }
  42.                 if(key==KEY1_PRES)
  43.                 {
  44.                         FlashWrite(0x08010000,(u32*)data,SIZE);
  45.                 }
  46.                 delay_ms(10);   
  47.                 i++;
  48.                 if(i==20)
  49.                 {
  50.                         i=0;
  51.                         LED0=!LED0;
  52.                 }
  53.         }
  54. }

复制代码
flash读写函数:
  1. #include "stmflash.h"

  2. u32 GetFlashSector(u32 addr)
  3. {
  4.         if(addr<ADDR_FLASH_SECTOR_1)                        return FLASH_SECTOR_0;
  5.         else if(addr<ADDR_FLASH_SECTOR_2)        return FLASH_SECTOR_1;
  6.         else if(addr<ADDR_FLASH_SECTOR_3)        return FLASH_SECTOR_2;
  7.         else if(addr<ADDR_FLASH_SECTOR_4)        return FLASH_SECTOR_3;
  8.         else if(addr<ADDR_FLASH_SECTOR_5)        return FLASH_SECTOR_4;
  9.         else if(addr<ADDR_FLASH_SECTOR_6)        return FLASH_SECTOR_5;
  10.         else if(addr<ADDR_FLASH_SECTOR_7)        return FLASH_SECTOR_6;
  11.         else if(addr<ADDR_FLASH_SECTOR_8)        return FLASH_SECTOR_7;
  12.         else if(addr<ADDR_FLASH_SECTOR_9)        return FLASH_SECTOR_8;
  13.         else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_SECTOR_9;
  14.         else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_SECTOR_10;
  15.         else if(addr<ADDR_FLASH_SECTOR_12)return FLASH_SECTOR_11;
  16.         else if(addr<ADDR_FLASH_SECTOR_13)return FLASH_SECTOR_12;
  17.         else if(addr<ADDR_FLASH_SECTOR_14)return FLASH_SECTOR_13;
  18.         else if(addr<ADDR_FLASH_SECTOR_15)return FLASH_SECTOR_14;
  19.         else if(addr<ADDR_FLASH_SECTOR_16)return FLASH_SECTOR_15;
  20.         else if(addr<ADDR_FLASH_SECTOR_17)return FLASH_SECTOR_16;
  21.         else if(addr<ADDR_FLASH_SECTOR_18)return FLASH_SECTOR_17;
  22.         else if(addr<ADDR_FLASH_SECTOR_19)return FLASH_SECTOR_18;
  23.         else if(addr<ADDR_FLASH_SECTOR_20)return FLASH_SECTOR_19;
  24.         else if(addr<ADDR_FLASH_SECTOR_21)return FLASH_SECTOR_20;
  25.         else if(addr<ADDR_FLASH_SECTOR_22)return FLASH_SECTOR_21;
  26.         else if(addr<ADDR_FLASH_SECTOR_23)return FLASH_SECTOR_22;  
  27.         return FLASH_SECTOR_23;       
  28. }

  29. u32 Flash_ReadOneWord(u32 addr)
  30. {
  31.         return *(vu32*)addr;
  32. }

  33. void FlashRead(u32 addr,u32 *rbuff,u32 NumToRead)
  34. {
  35.         u32 i;
  36.         for(i=0;i<NumToRead;i++)
  37.         {
  38.         rbuff[i]=Flash_ReadOneWord(addr);
  39.         addr+=4;
  40.         }
  41. }

  42. void FlashWrite(u32 addr,u32 *wbuff,u32 NumToWrite)
  43. {
  44.         FLASH_EraseInitTypeDef FLASH_EraseInit;
  45.         u32 endaddr;
  46.         u32 sectorerror=0;
  47.         u32 eraseaddr;
  48.         eraseaddr=addr;
  49.         endaddr=addr+NumToWrite*4;
  50.         HAL_FLASH_Unlock();
  51.        
  52.         if(addr<0x08000000||addr>0x1FFF0000||addr%4)        return;
  53.        
  54.         while(eraseaddr<endaddr)
  55.         {
  56.                 if(Flash_ReadOneWord(eraseaddr)!=0xffffffff)
  57.                 {
  58.                         FLASH_EraseInit.Banks=FLASH_BANK_1;
  59.                         FLASH_EraseInit.NbSectors=1;
  60.                         FLASH_EraseInit.Sector=GetFlashSector(eraseaddr);
  61.                         FLASH_EraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;
  62.                         FLASH_EraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;
  63.                         if(HAL_FLASHEx_Erase(&FLASH_EraseInit,§orerror)!=HAL_OK)
  64.                         {
  65.                                 break;
  66.                         }
  67.                 }else eraseaddr+=4;
  68.                 FLASH_WaitForLastOperation(50000);
  69.         }
  70.         if(FLASH_WaitForLastOperation(50000)==HAL_OK)
  71.         {
  72.                 while(addr<endaddr)
  73.                 {
  74.                         if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,addr,*wbuff)!=HAL_OK)
  75.                         {
  76.                                 break;
  77.                         }
  78.                         addr+=4;
  79.                         wbuff++;
  80.                 }
  81.         }
  82.         HAL_FLASH_Lock();
  83.        
  84. }

复制代码




主FLASH编程.zip

14.17 MB, 下载次数: 12

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2019-12-31 13:13:02 | 显示全部楼层
帮顶                              
成功没有捷径
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2018-8-8
在线时间
50 小时
 楼主| 发表于 2019-12-31 14:37:00 | 显示全部楼层

每次都是你啊?整体帮顶??
回复

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4480
金钱
4480
注册时间
2013-4-22
在线时间
337 小时
发表于 2019-12-31 14:49:35 | 显示全部楼层
好像需要对齐处理吧
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2020-1-1 01:25:58 | 显示全部楼层
用我们例程测试下
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2020-1-1 20:23:25 | 显示全部楼层
走投无路的卡卡 发表于 2019-12-31 14:37
每次都是你啊?整体帮顶??

嘻嘻嘻                                         
成功没有捷径
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2018-8-8
在线时间
50 小时
 楼主| 发表于 2020-1-2 11:20:41 | 显示全部楼层
正点原子 发表于 2020-1-1 01:25
用我们例程测试下

data数组如果定义在main函数外部则不会出现这种问题,定义在内部就不行
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2018-8-8
在线时间
50 小时
 楼主| 发表于 2020-1-2 11:21:56 | 显示全部楼层
三叶草 发表于 2019-12-31 14:49
好像需要对齐处理吧

data数组如果定义在main函数外部则不会出现这种问题,定义在内部就不行
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2019-12-19
在线时间
2 小时
发表于 2020-1-2 11:22:20 | 显示全部楼层
关键在你写入时,对内存的擦除,这个操作是错误的,内存是以块进行擦除的,而不像EEPROM以字节可擦。所以,在进行数据的新地址写入时,先是对整位块进行擦除,再写数据,而不是去判断内容。你的写入函数的处理方式是错误的。
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2018-8-8
在线时间
50 小时
 楼主| 发表于 2020-1-2 11:25:35 | 显示全部楼层
chenyang601 发表于 2020-1-2 11:22
关键在你写入时,对内存的擦除,这个操作是错误的,内存是以块进行擦除的,而不像EEPROM以字节可擦。所以, ...
  1. if(Flash_ReadOneWord(eraseaddr)!=0xffffffff)
  2.                 {
  3.                         FLASH_EraseInit.Banks=FLASH_BANK_1;
  4.                         FLASH_EraseInit.NbSectors=1;
  5.                         FLASH_EraseInit.Sector=GetFlashSector(eraseaddr);
  6.                         FLASH_EraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;
  7.                         FLASH_EraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;
  8.                         if(HAL_FLASHEx_Erase(&FLASH_EraseInit,§orerror)!=HAL_OK)
  9.                         {
  10.                                 break;
  11.                         }
复制代码


我这段就是判断数据是否为ffff,如果不是就整块擦除呀
回复

使用道具 举报

6

主题

1127

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1656
金钱
1656
注册时间
2019-8-15
在线时间
102 小时
发表于 2020-1-2 14:30:23 | 显示全部楼层
我再顶                                             
成功没有捷径
回复

使用道具 举报

8

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
292
金钱
292
注册时间
2018-8-14
在线时间
37 小时
发表于 2020-1-2 15:50:23 | 显示全部楼层
数组定义成全局变量就不会出现这种情况,这个现象好像你中间地址上出错了,一下少四个字节,就是一次读操作的函数,这个现象好像就是bug建议还是仿真一下,尤其做IAP程序,有仿真会方便的多,在每个断点查看数组,写的初始地址,读的起始地址,地址内的真实数据。
捕获.PNG
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 00:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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