OpenEdv-开源电子网

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

Flash擦除失败,求指教

[复制链接]

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7573
金钱
7573
注册时间
2016-11-30
在线时间
643 小时
发表于 2018-8-21 09:08:02 | 显示全部楼层 |阅读模式
10金钱
void TIM1_Init(void)
{
        TIM_ClockConfigTypeDef sClockSourceConfig;


        //HAL_TIM_Base_DeInit(&TIM1_Handler);//加这句代码导致Flash擦除失败
        TIM1_Handler.Instance = TIM1; //通用定时器 2
        TIM1_Handler.Init.Prescaler = 0; //分频系数,不分频72MHz
        TIM1_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数器
        TIM1_Handler.Init.Period=0xFFFF; //自动装载值
        TIM1_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; //时钟分频银子
        HAL_TIM_Base_Init(&TIM1_Handler);

        //设置位外部时钟2模式
        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
        sClockSourceConfig.ClockPolarity = TIM_ETRPOLARITY_NONINVERTED;
        sClockSourceConfig.ClockPrescaler = TIM_ETRPRESCALER_DIV1;
        sClockSourceConfig.ClockFilter = 0x0;
        HAL_TIM_ConfigClockSource(&TIM1_Handler, &sClockSourceConfig);
        __HAL_TIM_SET_COUNTER(&TIM1_Handler,0);
        HAL_TIM_Base_Start(&TIM1_Handler);
        /**/
}



/********************************
*函数功能:Flash按页写入
*传入参数age_Addr页首地址,*pBuffer写入的数据
*传出参数:无
*返回值:0:写Flash正确1:地址超出范围,2:地址不是页首地址,3:擦除页失败
*********************************/
u8 STMFLASH_Page_Write_Double_Word(u32 Page_Addr,u64 *pBuffer)       
{
        u32 Page_error;
        FLASH_EraseInitTypeDef FlashEraseInit;
        u8 sta;
        //TIM2_Disable();
       
        if(Page_Addr<STM32_FLASH_BASE||(Page_Addr>=(STM32_FLASH_BASE+STM_SECTOR_SIZE*STM32_SECTOR_NUM)))
        {
                printf("age_Addr = %X\r\n",Page_Addr);
                printf("地址超出范围\r\n");
                return 1;//非法地址
        }
        else if(((Page_Addr-STM32_FLASH_BASE)%STM_SECTOR_SIZE) != 0)
                {
                        printf("非页首地址\r\n");
                        return 2;//非法地址
                }

        HAL_FLASH_Unlock();             //解锁       

        FlashEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;       //擦除类型,扇区擦除
        FlashEraseInit.Banks = FLASH_BANK_1;   //位于哪个块
        FlashEraseInit.Page = STMFLASH_Get_Page_Num(Page_Addr);  //擦除哪个扇区
        FlashEraseInit.NbPages = 1;       //一次只擦除一个扇区
        sta = HAL_FLASHEx_Erase(&FlashEraseInit,&age_error);
        printf("sta = %d\r\n",sta);
        if(sta != HAL_OK)
        {
                printf("擦除页失败\r\n");
                return 3;
        }
       
        FLASH_WaitForLastOperation(FLASH_WAITETIME);            //等待上次操作完成


        STMFLASH_Write_Double_Word(Page_Addr,pBuffer,STM_PAGE_SIZE);//写入整个扇区  

        HAL_FLASH_Lock();//上锁
        //TIM2_Enable();
        return 0;
}

现象是这样的:
HAL_TIM_Base_DeInit(&TIM1_Handler);加上这句代码之后,Flash擦除失败sta = 1;
注释掉HAL_TIM_Base_DeInit(&TIM1_Handler);这句代码之后,Flash擦除成功sta = 0;

虽然是解决我的问题了,但是不知其所以然,想搞明白导致擦除失败的根本原因。这两者之间
到底有什么关联点呢?研究了下DeInit函数,没发现特别的地方。请大神指教!!!@正点原子


最佳答案

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

擦写失败有时一次失败,第二次就成功了。操作Flash之前最好是关总中断,完事儿再开总中断。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7573
金钱
7573
注册时间
2016-11-30
在线时间
643 小时
 楼主| 发表于 2018-8-21 09:08:03 | 显示全部楼层
擦写失败有时一次失败,第二次就成功了。操作Flash之前最好是关总中断,完事儿再开总中断。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-8-22 02:07:36 | 显示全部楼层
帮顶
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
发表于 2018-8-22 16:30:59 | 显示全部楼层
你定时器中断里面是不是影响了擦写
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7573
金钱
7573
注册时间
2016-11-30
在线时间
643 小时
 楼主| 发表于 2018-8-23 09:19:19 | 显示全部楼层
午夜狼嚎 发表于 2018-8-22 16:30
你定时器中断里面是不是影响了擦写

定时器中断没有影响Flash的操作,我只有加上DeInit函数后才会擦除失败,没有DeInit函数是不会擦除失败的,中断函数没有更改过
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-24 01:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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