OpenEdv-开源电子网

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

片上FLASH写入时,怎么会有莫名其妙的数据?谢谢。

[复制链接]

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
428
金钱
428
注册时间
2014-1-28
在线时间
8 小时
发表于 2015-7-22 16:55:16 | 显示全部楼层 |阅读模式
5金钱
根据教程来的,想在0x0807 0000写“12”,但是不知道为什么,后面跟着好几个莫名其妙的数字?
请问,是怎么回事?
谢谢。

////////////
const u8 TEXT_Buffer[]={"12"};
#define SIZE sizeof(TEXT_Buffer)       
#define FLASH_SAVE_ADDR  0X08070000 


STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)TEXT_Buffer,SIZE); 
delay_ms(1000);

 STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)datatemp,SIZE);  
delay_ms(1000);

/////////////







最佳答案

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

回复【2楼】jermy_z: --------------------------------- 我搜索了一下,好像找到原因了。 因为FLASH是一次写16位,下面的这个u8的SIZE,应该要除以2。才是写入的长度。 #define SIZE sizeof(TEXT_Buffer)   应该变成 #define SIZE (sizeof(TEXT_Buffer))/2
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
428
金钱
428
注册时间
2014-1-28
在线时间
8 小时
 楼主| 发表于 2015-7-22 16:55:17 | 显示全部楼层
回复【2楼】jermy_z:
---------------------------------
我搜索了一下,好像找到原因了。
因为FLASH是一次写16位,下面的这个u8的SIZE,应该要除以2。才是写入的长度。

#define SIZE sizeof(TEXT_Buffer)  

应该变成 #define SIZE (sizeof(TEXT_Buffer))/2
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13129
金钱
13129
注册时间
2012-11-26
在线时间
3814 小时
发表于 2015-7-22 17:01:06 | 显示全部楼层
你写的是字符串  字符串后面是有0的 24 1A 哪来的  没看出来
学无止境
回复

使用道具 举报

2

主题

12

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-7-21
在线时间
0 小时
发表于 2015-7-22 18:52:18 | 显示全部楼层
回复【3楼】LuoKen:
---------------------------------
你确定吗?原子老师的可没有除于2。。。我也在做这个,也读出来乱码了,可以交流一下
回复

使用道具 举报

70

主题

6763

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13129
金钱
13129
注册时间
2012-11-26
在线时间
3814 小时
发表于 2015-7-23 11:30:18 | 显示全部楼层
回复【4楼】龙阿龙:
---------------------------------
实验代码里  buffer是  Uint16 所以不用除以2
学无止境
回复

使用道具 举报

5

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2014-10-21
在线时间
31 小时
发表于 2015-7-27 21:46:44 | 显示全部楼层
回复【5楼】jermy_z:
---------------------------------
实验代码里是const u8 TEXT_Buffer[]={"STM32 FLASH TEST"};
并不是u16啊??
求教,谢谢,借这个问一下= =[]~( ̄▽ ̄)~*\(^o^)/~\(^o^)/~
回复

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
428
金钱
428
注册时间
2014-1-28
在线时间
8 小时
 楼主| 发表于 2015-7-28 09:35:54 | 显示全部楼层
回复【6楼】你干嘛:
---------------------------------
你去下载最新版本的教程。
需要注意的是:
1、写FLASH地址,必须是偶数地址。否则会不写,或者进入硬件错误(我遇到过一次,没有分析原因)。
2、别纠结u8的这个字符串。u8必须转化为u16,你直接写一个u16的数组,测试就行。
3、WriteAddr+=secremain*2; //写地址偏移
回复

使用道具 举报

5

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2014-10-21
在线时间
31 小时
发表于 2015-7-28 14:58:24 | 显示全部楼层
回复【7楼】LuoKen:
---------------------------------
哦哦,谢谢
#define SIZE (sizeof(TEXT_Buffer))/2
那请问你上次说的这个SIZE是不是不应该除以2了,应该直接是u8的个数,因为反正u8会转换成u16的嘛,所以SIZE 还是为sizeof(TEXT_Buffer)
我的理解有误吗??
总结起来就是说,写入flash的个数为u16数组的个数,或者u8数组的个数,u8和u16最终都转换成u16了
回复

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
428
金钱
428
注册时间
2014-1-28
在线时间
8 小时
 楼主| 发表于 2015-7-29 09:33:06 | 显示全部楼层
回复【8楼】你干嘛:
---------------------------------
1.你理解的不对。void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)。你看这个函数的第2个参数,是u16 *pBuffer(因为FLASH的硬件结构,决定了每次写入16位)。是1个16位的指针,那么指针+1,相当于移动了16bit的位置。不要被第3个参数,NumToWrite的u16所误导,这个u16仅仅是范围大,可以写入更多的数据。

2. 如果是u8的数组,举个例子 
          u8 test[4]={0x01, 0x02, 0x03, 0x04};,
          那么 sizeof(test)=4,因为数组长度是4。
          用STMFLASH_Write函数去写4个数据的时候,就会出现:*pBuffer=0x0201, *(pBuffer+1)=0x0403, *(pBuffer+2)=未知内存值(2字节),*(pBuffer+3)=未知内存值(2字节)。
         未知的内存值,就是出现乱码的原因。
          所以,此处如果要想正确,不论你是什么样的数组,u8,u16,u32,都一定要把写入的SIZE 转换为 U16的长度。
          u8的size ,就得除以2。
          u16的size,保持不变化。
          u32的size,就得乘以2。

3. 这下应该明白了吧。
回复

使用道具 举报

5

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2014-10-21
在线时间
31 小时
发表于 2015-7-30 20:16:04 | 显示全部楼层
回复【9楼】LuoKen:
---------------------------------
我实验了一下,我想你说的size指的是u16的个数吧,而不是sizeof(test)的值对么?
也就是说你说的:
   u8的size ,就得除以2。 
   u16的size,保持不变化。 
   u32的size,就得乘以2。
这里的size,指的是数组的个数,而不是sizeof(test),因为sizeof()得到的是八位数的个数
1.定义u8数组
   u8 Flash_save_test[4]={0x01,0x02,0x03,0x04};
   u8 Flash_read_test[4];
   然后写入
   sizeof(Flash_save_test)=4;
   STMFLASH_Write(FLASH_SAVE_ADDR,(uint16*)Flash_save_test,4);
   STMFLASH_Read(FLASH_SAVE_ADDR,(uint16*)Flash_read_test,4);
   如下
   0X08020000: 01 02 03 04 00 00 00 00
   这里后面的四个数出错,个数应该写2,表示两个16位的数
   即
   STMFLASH_Write(FLASH_SAVE_ADDR,(uint16*)Flash_save_test,2);
   个数为2后,结果为
   0X08020000: 01 02 03 04,正确
2.定义u16数组
   u16 Flash_save_test[4]={0x01,0x02,0x03,0x04};
   u16 Flash_read_test[4];
   然后写入
   sizeof(Flash_save_test)=8;
   STMFLASH_Write(FLASH_SAVE_ADDR,(uint16*)Flash_save_test,8);
   0X08020000: 01 00 02 00 03 00 04 00 00 00 00 00 00 00 00 00
   这里也出错,应该是4,也就是说是4个16位数
   改为
   STMFLASH_Write(FLASH_SAVE_ADDR,(uint16*)Flash_save_test,4);
   得到的为
   0X08020000: 01 00 02 00 03 00 04 00,正确
3.最后个问题,如果就存一个八位的数,那不是会浪费掉一个字节么,比如存0x01,那么就会
   0X08020000:01 00
4.看来我原来的理解错误了,现在的理解对吗?
   就是若是8位数组,那么是两个八位数,组成一个十六位写入一个
   若是16位数组,那么一个十六位数写入一个
   若是32位数组,那么一个三十二位数拆成两个十六位数写入两个
   那么不就是只要sizeof(test)/2带入就行了? 
   感谢乔巴大神的耐心赐教
回复

使用道具 举报

60

主题

153

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
428
金钱
428
注册时间
2014-1-28
在线时间
8 小时
 楼主| 发表于 2015-7-31 09:32:57 | 显示全部楼层
回复【10楼】你干嘛:
---------------------------------
1.2. 完美,测试的很详细。
3. 确实会浪费一个字节。
4. 
{
   就是若是8位数组,那么是两个八位数,组成一个十六位写入一个 
   若是16位数组,那么一个十六位数写入一个 
   若是32位数组,那么一个三十二位数拆成两个十六位数写入两个 
}  //都对。

{
   那么不就是只要sizeof(test)/2带入就行了?  
} //因为sizeof的结果,根据数组的个数,可能是偶数,也可能是奇数。例如:4/2=2,5/2=2。如果是4个数,就正确。但是5个数的话,就会少写一个。
回复

使用道具 举报

5

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2014-10-21
在线时间
31 小时
发表于 2015-7-31 19:11:20 | 显示全部楼层
回复【11楼】LuoKen:
---------------------------------
哦,对,忘记了数组有可能是奇数,哈哈,感谢。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 05:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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