打印
[STM32F1]

[已解决]我又来啦,这次是STM32 Flash的问题

[复制链接]
3048|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 深夜星空 于 2013-12-16 22:37 编辑

STM32F103,想用内部Flash存几个数据。但总有问题,读出后放入数组,每个奇数的数组都是0。上图

程序加在线仿真结果,存的数是1 2 3 4 5 6 7 8 9 10 11 ,我知道这里大神多,现行谢谢啦。



















已解决,读的时候for循环内部不要i++,太低级了 - - ,耽误大家时间了,轻喷。都怪拿来的代码只看了flash编程的思路,没好好自己写。下面更新新图,成功代码。



沙发
rtgchym| | 2013-12-16 10:01 | 只看该作者
首先根据你的存储器容量来确定每页的字节数和待写入地址的正确性,因为是按半字写入的,地址都是按2个字节偏移,应该是每次累加2,读的时候也应该按半字读,别用uint32_t

使用特权

评论回复
板凳
caijize| | 2013-12-16 10:53 | 只看该作者
读的时候应该用4个字节的:
u32 flag = *(vu32*)(FLASHCMD);
写的时候也应该用4个字节的:
u32 cmd = FCMD_UPD;
FLASH_ProgramWord(FLASHCMD, cmd);
我给的代码只是个例子,你应该明白我在说什么。
不要用半字写入,应该用全字写入,这样才对应该。

使用特权

评论回复
地板
深夜星空|  楼主 | 2013-12-16 11:04 | 只看该作者
rtgchym 发表于 2013-12-16 10:01
首先根据你的存储器容量来确定每页的字节数和待写入地址的正确性,因为是按半字写入的,地址都是按2个字节 ...

STM32F103CBT6 128K中等容量 每页1K,0~127页。第127页地址0x0801 FC00~0x0801 FFFF 。
我把数据写在127页。大神,地址偏移什么的,我也觉得这里有问题,想看看数组在Flash里是怎么储存的。
我读写都改成2字节偏移,读的时候用uint16_t 还是不行啊

使用特权

评论回复
5
深夜星空|  楼主 | 2013-12-16 11:09 | 只看该作者
rtgchym 发表于 2013-12-16 10:01
首先根据你的存储器容量来确定每页的字节数和待写入地址的正确性,因为是按半字写入的,地址都是按2个字节 ...

还有个问题,每个地址,比如0x0801 FC00 对应的就是32位;0x0801 FC01 对应的也是32位,那地址偏移为什么每次要加2,加4呢?难道这个地址是映射过来的?每个对应半个字?

使用特权

评论回复
6
深夜星空|  楼主 | 2013-12-16 11:13 | 只看该作者
caijize 发表于 2013-12-16 10:53
读的时候应该用4个字节的:
u32 flag = *(vu32*)(FLASHCMD);
写的时候也应该用4个字节的:

明白,但我觉得写入的数据是16位还是32位不是我的问题,我觉得我的问题还是出现在地址的对应上

使用特权

评论回复
7
caijize| | 2013-12-16 11:23 | 只看该作者
深夜星空 发表于 2013-12-16 11:13
明白,但我觉得写入的数据是16位还是32位不是我的问题,我觉得我的问题还是出现在地址的对应上 ...

写入可以是两个字节,但读出应该是4个字节,如果你不处理成了一下,那每次读出时你要手动处理一下,也就是说写入两次(2个字节的)读出一次(4个字节)就够了。

使用特权

评论回复
8
深夜星空|  楼主 | 2013-12-16 11:29 | 只看该作者
caijize 发表于 2013-12-16 11:23
写入可以是两个字节,但读出应该是4个字节,如果你不处理成了一下,那每次读出时你要手动处理一下,也就 ...

是,那看我最后一张图,写入两次,读出一次,可为什么每次读出后面都会读出一次0000呢?

使用特权

评论回复
9
rtgchym| | 2013-12-16 13:31 | 只看该作者
深夜星空 发表于 2013-12-16 11:09
还有个问题,每个地址,比如0x0801 FC00 对应的就是32位;0x0801 FC01 对应的也是32位,那地址偏移为什么 ...

STM32是32位的单片机,它的地址线当然是32位,但是闪存编程时是在相应的地址写入半字,你看调用的库函数都是FLASH_ProgramHalfWord,因为是按半字写入,所以扇区内的偏移是按2个字节为基本单位,读也是, return *(_IO uint16_t*)addr是没问题的

使用特权

评论回复
10
rtgchym| | 2013-12-16 13:31 | 只看该作者
本帖最后由 rtgchym 于 2013-12-16 13:39 编辑
深夜星空 发表于 2013-12-16 11:09
还有个问题,每个地址,比如0x0801 FC00 对应的就是32位;0x0801 FC01 对应的也是32位,那地址偏移为什么 ...
void Flash_Write( uint32_t  WriteAddr, uint16_t *Flash_WriteBuff )
{
        uint8_t i;

        FLASH_Unlock();
        FLASH_ClearFlag( FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP );
        FLASH_ErasePage( 0x0801FC00 );       

        for( i = 0; i < 11; i++ )
        {
                WriteAddr += 2;
                FLASH_ProgramHalfWord( WriteAddr, Flash_WriteBuff );
        }
        FLASH_Lock();
}

uint16_t FLASH_ReadHalfWord( uint32_t Flash_Addr )
{
        return *(vu16*)Flash_Addr;
}


void FLASH_Read( uint32_t  ReadAddr )
{
        uint8_t i;

        for( i = 0; i < 11; i++)
        {
                ReadAddr += 2;
                Flash_ReadBuff = FLASH_ReadHalfWord(ReadAddr);       
        }
}
根据我以前的代码大致改了改,希望对你有用




使用特权

评论回复
11
pattywu| | 2013-12-16 13:41 | 只看该作者
LZ,你直接查看一下写入后,FLASH中的数据是如何存放的,不就行了?

使用特权

评论回复
12
深夜星空|  楼主 | 2013-12-16 20:11 | 只看该作者
pattywu 发表于 2013-12-16 13:41
LZ,你直接查看一下写入后,FLASH中的数据是如何存放的,不就行了?

这正是我发此贴的终极目的啊

使用特权

评论回复
13
深夜星空|  楼主 | 2013-12-16 21:12 | 只看该作者
rtgchym 发表于 2013-12-16 13:31
void Flash_Write( uint32_t  WriteAddr, uint16_t *Flash_WriteBuff )
{
        uint8_t i;

试了,还是没解决数据中间有0000的问题 = =

使用特权

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

本版积分规则

31

主题

345

帖子

3

粉丝