OpenEdv-开源电子网

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

求助!!stm32 flash写操作死机,手动复位NRST脚无效,必须重新上电!

[复制链接]

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
发表于 2016-10-20 20:31:14 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 平凡8236 于 2016-10-20 20:47 编辑

用正点原子标准flash例程,void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)        ,写u16数据,大部分时候没问题,但有时会死机!!!,手动复位NRST脚无效!必须重新上电!!!重新上电后工作正常。不知哪位大侠遇到过这种情况??求解!!

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

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-20 21:16:00 | 显示全部楼层
新人贴没人理哈求高手指点迷津!!!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-10-20 22:24:26 | 显示全部楼层
你看看什么时候死机,死机的时候,看看这几个输入参数的值是多少
回复

使用道具 举报

1

主题

84

帖子

0

精华

高级会员

Rank: 4

积分
529
金钱
529
注册时间
2015-7-21
在线时间
47 小时
发表于 2016-10-21 08:29:50 | 显示全部楼层
死机是程序死在哪里了?还有函数STMFLASH_Write()是怎么调用的,传入的参数是?你把相关代码贴一下
一名合格的工程师一定要做到,代码虐我千百遍依然待她如初恋!
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-21 12:07:57 | 显示全部楼层
本帖最后由 平凡8236 于 2016-10-21 12:11 编辑

#define FLASH_SAVE_ADDR  0x0801f000   //stm32f103cbt6
flash_buf[0] = X_addata;
flash_buf[1] = Y_addata;
flash_buf[2] = E_addata;
flash_buf[3] = Z_addata;
STMFLASH_Write(FLASH_SAVE_ADDR,flash_buf,4);
死机的时候程序已跑飞!手动复位失效。死机的几率只有十分之一!!郁闷!!请高手赐教
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-21 12:29:03 | 显示全部楼层
流水若冰 发表于 2016-10-21 08:29
死机是程序死在哪里了?还有函数STMFLASH_Write()是怎么调用的,传入的参数是?你把相关代码贴一下

#define FLASH_SAVE_ADDR  0x0801f000   //stm32f103cbt6
flash_buf[0] = X_addata;
flash_buf[1] = Y_addata;
flash_buf[2] = E_addata;
flash_buf[3] = Z_addata;
STMFLASH_Write(FLASH_SAVE_ADDR,flash_buf,4);
死机的时候程序已跑飞!手动复位失效。死机的几率只有十分之一!!郁闷!!请高手赐教
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-21 12:29:43 | 显示全部楼层
正点原子 发表于 2016-10-20 22:24
你看看什么时候死机,死机的时候,看看这几个输入参数的值是多少

#define FLASH_SAVE_ADDR  0x0801f000   //stm32f103cbt6
flash_buf[0] = X_addata;
flash_buf[1] = Y_addata;
flash_buf[2] = E_addata;
flash_buf[3] = Z_addata;
STMFLASH_Write(FLASH_SAVE_ADDR,flash_buf,4);
死机的时候程序已跑飞!手动复位失效。死机的几率只有十分之一!!郁闷!!请高手赐教
回复

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2016-10-21 13:07:58 | 显示全部楼层
随便给你找段我的程序,你看下:
for(i=0;i<36;i++)                                                                                //2&#187;3&#172;1y36K3ìDò
                {
                        for(j=0;j<512;j++)                                                                //u8±&#228;3éu16oóμ&#196;×&#214;&#189;úêy&#190;Y                                          
                        {
                                IAPBUF[j] = *(u16*)(APP3adress+k+i*1024);         //&#189;&#171;áùê±Flashà&#239;μ&#196;êy&#190;Y&#182;á3&#246;à′         &#195;&#191;′&#206;&#182;á1K×&#214;&#189;ú
                                k+=2;
                        }
                        k = 0;
                        FLASH_Unlock();
                        FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
                        FLASH_ErasePage(APP2adress+i*1024);                        //&#207;è2áoóD′£&#172;&#195;&#191;′&#206;2á3yò&#187;ò3μ&#216;&#214;·(1K);
                        for(j=0;j<512;j++)                                                                                        //u8±&#228;3éu16oóμ&#196;×&#214;&#189;úêy&#190;Y                                          
                        {
                                FLASH_ProgramHalfWord((APP2adress+j*2+i*1024),IAPBUF[j]);//flash  &#206;aò&#187;&#184;&#246;×&#214;&#189;ú′&#230;′¢£&#172;16&#206;&#187;êy&#190;Y±&#216;D&#235;μ&#216;&#214;·&#188;ó2
                        }
                        FLASH_Lock();
                        j = 0;
                        delay_ms(2);
                }
shop60994719.taobao.com
回复

使用道具 举报

1

主题

84

帖子

0

精华

高级会员

Rank: 4

积分
529
金钱
529
注册时间
2015-7-21
在线时间
47 小时
发表于 2016-10-21 15:23:04 | 显示全部楼层
平凡8236 发表于 2016-10-21 12:29
#define FLASH_SAVE_ADDR  0x0801f000   //stm32f103cbt6
flash_buf[0] = X_addata;
flash_buf[1] = Y_ ...

跑飞的时候是进了硬件错误中断吗?你确定是操作FLASH导致的程序跑飞?这个flash_buf的类型是u16的吗?
一名合格的工程师一定要做到,代码虐我千百遍依然待她如初恋!
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-21 17:46:18 | 显示全部楼层
流水若冰 发表于 2016-10-21 15:23
跑飞的时候是进了硬件错误中断吗?你确定是操作FLASH导致的程序跑飞?这个flash_buf的类型是u16的吗?

感谢帮助!!肯定是操作flash引起的,flash_buf的类型也对,关键是这个故障几率很小,但一旦出现,什么硬件看门狗统统不好用,只有重新上电!郁闷
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-21 17:49:17 | 显示全部楼层
密耳 发表于 2016-10-21 13:07
随便给你找段我的程序,你看下:
for(i=0;i

我用的是正点原子的标准flash模拟EEPROM例程中的flash读写函数,应该没问题吧??
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-10-22 20:03:47 | 显示全部楼层
平凡8236 发表于 2016-10-21 12:29
#define FLASH_SAVE_ADDR  0x0801f000   //stm32f103cbt6
flash_buf[0] = X_addata;
flash_buf[1] = Y_ ...

操作FLASH的时候,禁止中断试试。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-10-20
在线时间
5 小时
 楼主| 发表于 2016-10-23 00:34:12 | 显示全部楼层
正点原子 发表于 2016-10-22 20:03
操作FLASH的时候,禁止中断试试。

感谢原子哥的帮助!!可我在flash的函数里已经关了中断,还是会出现flash写死机的情况,感觉像stm32受到了干扰。我觉得这个问题有点怪,希望您能指点迷津!下面是我在flash例程里加的代码,请指正谢谢!
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)       
{
        u32 secpos;           //扇区地址
        u16 secoff;           //扇区内偏移地址(16位字计算)
        u16 secremain; //扇区内剩余地址(16位字计算)          
        u16 i;   
        u32 offaddr;   //去掉0X08000000后的地址
        __set_FAULTMASK(1);                                 //关闭所有中断
        if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
        FLASH_Unlock();                                                //解锁
        offaddr=WriteAddr-STM32_FLASH_BASE;                //实际偏移地址.
        secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT6
        secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.)
        secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小   
        if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
        while(1)
        {       
                STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
                for(i=0;i<secremain;i++)//校验数据
                {
                        if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除            
                }
                if(i<secremain)//需要擦除
                {
                        FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
                        for(i=0;i<secremain;i++)//复制
                        {
                                STMFLASH_BUF[i+secoff]=pBuffer;          
                        }
                        STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区  
                }else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                   
                if(NumToWrite==secremain)break;//写入结束了
                else//写入未结束
                {
                        secpos++;                                //扇区地址增1
                        secoff=0;                                //偏移位置为0          
                           pBuffer+=secremain;          //指针偏移
                        WriteAddr+=secremain;        //写地址偏移          
                           NumToWrite-=secremain;        //字节(16位)数递减
                        if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
                        else secremain=NumToWrite;//下一个扇区可以写完了
                }         
        };       
        FLASH_Lock();//上锁
        __set_FAULTMASK(0);                //打开所有中断
}
#endif
回复

使用道具 举报

7

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
325
金钱
325
注册时间
2016-10-21
在线时间
43 小时
发表于 2016-10-24 15:20:51 | 显示全部楼层
建议给FLASH申请一个空间,:
const  u8  SHSHCode[2048] __attribute__((at(SHSHFLASHADDR)))  = {
    0xF1,0xF2,0x66,0x15,0xC7,0x78,0xD8,0x85,0x55,0xCA,0x9A,0x9D};

#define FLASH_SAVE_ADDR  0x0801f000   //stm32f103cbt6  这样写你能确定编译器会不使用这段空间的FLASH吗?

const  u8  SHSHCode[2048] __attribute__((at(SHSHFLASHADDR)))
这样编译器会在SHSHFLASHADDR这个地址留出2K的空间,不会在这个空间写入数据,为什么是2K,因为扇区大小是2K,擦除工作是需要一个扇区一个扇区来,申请的2K空间,在擦除时就不会擦除程度代码了。

SHSHFLASHADDR定义值,建议编译完后,看MAP文件,看看编译生成代码的最后地址,定义紧接最后一个地址的下一个扇区。
回复

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2013-1-5
在线时间
11 小时
发表于 2016-11-9 09:09:20 | 显示全部楼层
我也遇到这个问题,请问楼主解决了没有。
回复

使用道具 举报

28

主题

218

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
498
金钱
498
注册时间
2013-11-19
在线时间
92 小时
发表于 2016-11-16 16:43:59 | 显示全部楼层
估计是程序跑飞了,如果有时候写Flash正常有时候异常,那么你传入的地址估计不合法
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 05:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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