历史上的今天
今天是:2024年12月25日(星期三)
2018年12月25日 | STM32F407.FLASH 读写经验
2018-12-25 来源:eefocus
现象:
如下代码:
//从指定地址开始写入指定长度的数据
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
{
u8 status=0;
u32 addrx=0;
u32 endaddr=0;
if(WriteAddr
addrx=WriteAddr; //写入的起始地址
endaddr=WriteAddr+NumToWrite*4; //写入的结束地址
if(addrx<0X1FFF0000) //只有主存储区,才需要执行擦除操作!!
{
while(addrx
if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
{
printf("S");
status=STMFLASH_EraseSector(STMFLASH_GetFlashSector(addrx));
if(status)break; //发生错误了
}else addrx+=4;
}
}
if(status==0)
{
while(WriteAddr
if(STMFLASH_WriteWord(WriteAddr,*pBuffer))//写入数据
{
break; //写入异常
}
WriteAddr+=4;
pBuffer++;
}
}
STMFLASH_Lock();//上锁
}
红色的printf,加上,程序运行正常.
红色的printf去掉,程序随即进入死循环,死在等待FLASH空闲里面,一旦JTAG仿真,并设置断点在这里,则可以不要printf,也可以正常运行.
非常诡异.
试过的方法:
1,找官方代码替换掉我的代码,结果,失败.
2,把printf,换成延时,失败.
3,把代码结构改了,失败.
4,把printf,换成直接写DR的方式发送,失败.
5,清FLASH->SR标记位,失败.
6,将系统的delay_us,换成i--之类的延时,失败.
7,加多等待FLASH操作结束,失败.
...
总之,2个晚上,就在不停的尝试各种可能的解决方案.不停的刷代码,估计这板子上的F4,都快要被我刷爆了...
最后,眼看着今晚又要3点了,万念俱灰之际,找来stm32f4的编程手册(其实一直在看,寄存器看了N遍了...),发现

这感情十分吻合啊,bus stall...
shit,才想起来,在系统时钟初始化的时候,默认是设置了DATA FETCHES的,仿真看下FLASH->ACR的DCEN位,果然是1.
立即修改代码如下:
//从指定地址开始写入指定长度的数据
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
{
u8 status=0;
u32 addrx=0;
u32 endaddr=0;
if(WriteAddr
FLASH->ACR&=~(1<<10); //FLASH擦除期间,必须禁止数据fetch!!!搞了我两晚上才发现这个问题!
addrx=WriteAddr; //写入的起始地址
endaddr=WriteAddr+NumToWrite*4; //写入的结束地址
if(addrx<0X1FFF0000) //只有主存储区,才需要执行擦除操作!!
{
while(addrx
if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
{
status=STMFLASH_EraseSector(STMFLASH_GetFlashSector(addrx));
if(status)break; //发生错误了
}else addrx+=4;
}
}
if(status==0)
{
while(WriteAddr
if(STMFLASH_WriteWord(WriteAddr,*pBuffer))//写入数据
{
break; //写入异常
}
WriteAddr+=4;
pBuffer++;
}
}
FLASH->ACR|=1<<10; //FLASH擦除结束,开启数据fetch
STMFLASH_Lock();//上锁
}
下载,测试....
奇迹出现了...运行正常了.
史海拾趣
|
我在project.reg 里添加了如下内容 [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\FontPath] \"FontPath\"=\"\\\\Hard Disk\\\\Font\" ; 字库文件所在目录 [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\FontLink\\SystemL ...… 查看全部问答> |
|
本以为解决了,结果还不行! 目前的情况: 计算机发信号给LED显示屏,中间用433无线模块传输。发送端通过232转485接无线模块,接收端模块通过485接显示屏。正常。但因为433模块不好用,所以客户想用我们的超级无线传输模块。但是,他要求,用我们 ...… 查看全部问答> |
|
使用AD采样一个电压信号,开机后显示数值710稳定,过了大约5分钟数值变为692 这是怎么回事?使用的是内部1.5V基准 有同鞋遇到过同样的问题没?… 查看全部问答> |
|
【设计工具】利用 Xilinx FPGA 打造出高端比特精度和周期精度浮点 DSP 算法实现方案 系统要求和可用 FPGA 的当前趋势使浮点实现方法变得更加重用。本白皮书和视频说明了(与其它设计流程的不同之处)DSP 系统生成器 13.3 如何为用户提供针对比特精度、周期精度、单精度、双精度和定制精度浮点 ...… 查看全部问答> |




