搜索
bottom↓
回复: 2

stm32f4xx_flash.c的函数FLASH_GetStatus有BUG

[复制链接]

出0入0汤圆

发表于 2013-9-1 19:45:38 | 显示全部楼层 |阅读模式
经过验证,确实是个BUG。在FLASH测试函数中打开OPERR和EOP中断,,但是NVIC中不使能,,这样不会响应FLASH中断,
但是FLASH操作结束后,会响应的设置OPERR和EOP标志位。

库的版本是V1.1.0,11-January-2013
不敢100%肯定,只敢99%确定是BUG,所以欢迎各位STM32er验证。

FLASH_Status FLASH_GetStatus(void)
{
  FLASH_Status flashstatus = FLASH_COMPLETE;
  
  if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
  {
    flashstatus = FLASH_BUSY;
  }
  else
  {  
    if((FLASH->SR & FLASH_FLAG_WRPERR) != (uint32_t)0x00)
    {
      flashstatus = FLASH_ERROR_WRP;
    }
    else
    {
      /*
      这句是否应该是if((FLASH->SR & (uint32_t)0xE0) != (uint32_t)0x00)才对啊
      OPERR: Operation error和EOP: End of operation是在中断使能时(ERRIE = 1EOPIE =1)才置位的
      假设EOP位为1,将返回FLASH_ERROR_PROGRAM,EOP为1不代表编程出错吧
      */
      if((FLASH->SR & (uint32_t)0xEF) != (uint32_t)0x00)
      {
        flashstatus = FLASH_ERROR_PROGRAM;
      }
      else
      {
        if((FLASH->SR & FLASH_FLAG_OPERR) != (uint32_t)0x00)
        {
          flashstatus = FLASH_ERROR_OPERATION;
        }
        else
        {
          flashstatus = FLASH_COMPLETE;
        }
      }
    }
  }
  /* Return the FLASH Status */
  return flashstatus;
}


/*
Flash read and write test example
- 对扇区11进行擦除,然后写入1024字节的数据
*/
void Flash_Read_Write_Test(void)
{
        uint32_t data, i, address ;
        FLASH_Status status;
        FlagStatus FStatus;
        
        //查看扇区写保护状态
        data = FLASH_OB_GetWRP();
        while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
        USART_SendData(USART3, data);
        //查看扇区读保护级别状态
        FStatus = FLASH_OB_GetRDP();
        while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
        USART_SendData(USART3, FStatus);
        
        //清除扇区11的写保护
        FLASH_OB_Unlock();
        FLASH_OB_WRPConfig(OB_WRP_Sector_11, DISABLE);
        status = FLASH_OB_Launch();
        FLASH_OB_Lock();
        if(FLASH_COMPLETE != status)
                return;
        
        //准备写数据
        FLASH_Unlock();
        
        //打开OPERR和EOP中断,FLASH_Status FLASH_GetStatus(void)函数将出现BUG
        FLASH_ITConfig(FLASH_IT_ERR|FLASH_IT_EOP, ENABLE);
        
        //擦除扇区11  
          FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                  FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
          status = FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
        if(FLASH_COMPLETE != status)
                return;
        //读数据,验证扇区11是否被擦除
        address = 0x080E0000;//扇区11首地址
        for(i=0; i<256*4; i++){
                data = *((uint8_t*)address + i);
                //输出到串口
                  while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
                    USART_SendData(USART3, data);
        }
        
        //写数据
        address = 0x080E0000;//扇区11首地址
        for(i=0; i<256; i++){
                /* Clear pending flags (if any) */
                  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                  FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
                data = i<<24 | i<<16 | i<<8 | i;
                status = FLASH_ProgramWord(address + i*4, data);//写一个字
                //status = FLASH_ProgramHalfWord(Address + i*2, uint16_t Data);//写一个半字
                //status = FLASH_ProgramByte(Address + i, uint8_t Data);//写一个字节
                if(FLASH_COMPLETE != status)
                        break;
        }
        
        FLASH_Lock();
        
        //读数据,验证是否写正确
        address = 0x080E0000;//扇区11首地址
        for(i=0; i<256*4; i++){
                data = *((uint8_t*)address + i);
                //输出到串口
                  while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
                    USART_SendData(USART3, data);
        }
}







修正的FLASH_GetStatus函数
/**
  * @brief  Returns the FLASH Status.
  * @param  None
  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
  *                       FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
  */
FLASH_Status FLASH_GetStatus(void)
{
  FLASH_Status flashstatus = FLASH_COMPLETE;
  
  if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
  {
    flashstatus = FLASH_BUSY;
  }
  else
  {  
    if((FLASH->SR & FLASH_FLAG_WRPERR) != (uint32_t)0x00)
    {
      flashstatus = FLASH_ERROR_WRP;
    }
    else
    {
          /*
          此处是否有BUG?应该是if((FLASH->SR & (uint32_t)0xE0) != (uint32_t)0x00)
          当PGSERR、PGPERR、PGAERR有至少1个不为0时,则表示FLASH_ERROR_PROGRAM
          OPERR和EOP只有当ERRIE = 1,EOPIE =1时才会设置,并且OPERR表示操作错误,
          EOP表示编程或擦除操作成功完成
          在使能中断情况下,可能是个BUG,未使能中断时,没有问题
         
          经过验证,通过FLASH_ITConfig(FLASH_IT_ERR|FLASH_IT_EOP, ENABLE)打开中断,
          发现在EOP置1的情况下,此处返回FLASH_ERROR_PROGRAM
          */
      if((FLASH->SR & (uint32_t)0xE0) != (uint32_t)0x00)
      {
        flashstatus = FLASH_ERROR_PROGRAM;
      }
      else
      {
        if((FLASH->SR & FLASH_FLAG_OPERR) != (uint32_t)0x00)
        {
          flashstatus = FLASH_ERROR_OPERATION;
        }
        else
        {
          flashstatus = FLASH_COMPLETE;
        }
      }
    }
  }
  /* Return the FLASH Status */
  return flashstatus;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2013-9-2 21:41:05 | 显示全部楼层
UP UP UP UP

出0入0汤圆

发表于 2013-11-6 21:58:32 | 显示全部楼层
我今天在玩STM32F2 Flash编程时也遇到这个问题,明天用楼主修改BUG后的方法试试看。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 01:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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