打印
[应用相关]

stm32f10x_flash.c中文版

[复制链接]
1031|37
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
functions|  楼主 | 2020-2-7 17:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/********************************************************************************
  * @文件    stm32f10x_flash.c
  * @作者    MCD 应用程序组
  * @版本    V3.1.0
  * @日期    06/19/2009
  * @简述    这个文件 提供所有 FLASH 固件函数.
  * @翻译    ANSON/sweet1985 Email:airanson110@126.com
  * @日期    23/07/2009
  ******************************************************************************
  * @复件
  *
  * 这个固件仅仅是提供给客户作为设计产品而编写程序的参考目的使客户节约时间。由于
  * 客户使用本固件在开发产品编程上产生的结果意法半导体公司不承担任何直接的和间接
  * 的责任,也不承担任何损害而引起的赔偿。
  *
  * <h2><center>&复制; 版权所有 2009 意法半导体公司</center></h2>
  * 翻译版本仅供学习,如与英文原版有出入应以英文原版为准。
  */

使用特权

评论回复
沙发
functions|  楼主 | 2020-2-7 17:36 | 只看该作者
/* 包含 ------------------------------------------------------------------*/
#include "stm32f10x_flash.h"

/* 自用类型 --------------------------------------------------------------*/
/* 自用定义 --------------------------------------------------------------*/

/* Flash Access Control Register bits */
#define ACR_LATENCY_Mask         ((uint32_t)0x00000038)
#define ACR_HLFCYA_Mask          ((uint32_t)0xFFFFFFF7)
#define ACR_PRFTBE_Mask          ((uint32_t)0xFFFFFFEF)

使用特权

评论回复
板凳
functions|  楼主 | 2020-2-7 17:36 | 只看该作者
/* Flash Access Control Register bits */
#define ACR_PRFTBS_Mask          ((uint32_t)0x00000020)

/* Flash Control Register bits */
#define CR_PG_Set                ((uint32_t)0x00000001)
#define CR_PG_Reset              ((uint32_t)0x00001FFE)
#define CR_PER_Set               ((uint32_t)0x00000002)
#define CR_PER_Reset             ((uint32_t)0x00001FFD)
#define CR_MER_Set               ((uint32_t)0x00000004)
#define CR_MER_Reset             ((uint32_t)0x00001FFB)
#define CR_OPTPG_Set             ((uint32_t)0x00000010)
#define CR_OPTPG_Reset           ((uint32_t)0x00001FEF)
#define CR_OPTER_Set             ((uint32_t)0x00000020)
#define CR_OPTER_Reset           ((uint32_t)0x00001FDF)
#define CR_STRT_Set              ((uint32_t)0x00000040)
#define CR_LOCK_Set              ((uint32_t)0x00000080)

使用特权

评论回复
地板
functions|  楼主 | 2020-2-7 17:36 | 只看该作者
/* FLASH Mask */
#define RDPRT_Mask               ((uint32_t)0x00000002)
#define WRP0_Mask                ((uint32_t)0x000000FF)
#define WRP1_Mask                ((uint32_t)0x0000FF00)
#define WRP2_Mask                ((uint32_t)0x00FF0000)
#define WRP3_Mask                ((uint32_t)0xFF000000)

使用特权

评论回复
5
functions|  楼主 | 2020-2-7 17:36 | 只看该作者
/* FLASH Keys */
#define RDP_Key                  ((uint16_t)0x00A5)
#define FLASH_KEY1               ((uint32_t)0x45670123)
#define FLASH_KEY2               ((uint32_t)0xCDEF89AB)

使用特权

评论回复
6
functions|  楼主 | 2020-2-7 17:37 | 只看该作者
/* Delay definition */   
#define EraseTimeout             ((uint32_t)0x00000FFF)
#define ProgramTimeout           ((uint32_t)0x0000000F)

使用特权

评论回复
7
functions|  楼主 | 2020-2-7 17:37 | 只看该作者
/* 自用宏 -------------------------------------------------------------*/
/* 自用变量 -----------------------------------------------------------*/
/* 自用函数原型 -------------------------------------------------------*/
/* 自用函数 -----------------------------------------------------------*/

/**
  * @简述  设置代码延时值.
  * @参数  FLASH_Latency: 指定的 FLASH 延时值.
  *          这个参数可以是下面的值之一:
  *          FLASH_Latency_0: FLASH 0个延时周期
  *          FLASH_Latency_1: FLASH 1个延时周期
  *          FLASH_Latency_2: FLASH 2个延时周期
  * @返回  没有
  */
void FLASH_SetLatency(uint32_t FLASH_Latency)
{
  uint32_t tmpreg = 0;
  /* 检查参数 */
  assert_param(IS_FLASH_LATENCY(FLASH_Latency));
  /* 读 ACR 寄存器 */
  tmpreg = FLASH->ACR;  
  /* 设置延时值 */
  tmpreg &= ACR_LATENCY_Mask;
  tmpreg |= FLASH_Latency;
  /* 写 ACR 寄存器 */
  FLASH->ACR = tmpreg;
}

使用特权

评论回复
8
functions|  楼主 | 2020-2-7 17:37 | 只看该作者
/**
  * @简述  使能或者失能 FLASH 半周期访问.
  * @参数  FLASH_HalfCycleAccess: 指定的 FLASH 半周期访问模式.
  *          这个参数可以是下面的值之一:
  *          FLASH_HalfCycleAccess_Enable:  半周期访问使能
  *          FLASH_HalfCycleAccess_Disable: 半周期访问失能
  * @返回  没有
  */
void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)
{
  /* 检查参数 */
  assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess));
  /* 使能或者失能半周期访问 */
  FLASH->ACR &= ACR_HLFCYA_Mask;
  FLASH->ACR |= FLASH_HalfCycleAccess;
}

使用特权

评论回复
9
functions|  楼主 | 2020-2-7 17:37 | 只看该作者
/**
  * @简述  使能或者失能预取缓存.
  * @参数  FLASH_PrefetchBuffer: 指定的预取缓存状态.
  *          这个参数可以是下面的值之一:
  *          FLASH_PrefetchBuffer_Enable:  使能预取指缓存
  *          FLASH_PrefetchBuffer_Disable: 失能预取指缓存
  * @返回  没有
  */
void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)
{
  /* 检查参数 */
  assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer));
  /* 使能或者失能预取缓存 */
  FLASH->ACR &= ACR_PRFTBE_Mask;
  FLASH->ACR |= FLASH_PrefetchBuffer;
}

使用特权

评论回复
10
functions|  楼主 | 2020-2-7 17:38 | 只看该作者
/**
  * @简述  解锁 FLASH 编写擦除控制器.
  * @参数  没有
  * @返回  没有
  */
void FLASH_Unlock(void)
{
  /* 授权 FPEC 存取 */
  FLASH->KEYR = FLASH_KEY1;
  FLASH->KEYR = FLASH_KEY2;
}

使用特权

评论回复
11
functions|  楼主 | 2020-2-7 17:38 | 只看该作者
/**
  * @简述  锁定 FLASH 编写擦除控制器.
  * @参数  没有
  * @返回  没有
  */
void FLASH_Lock(void)
{
  /* 设置锁定位来锁定 FPEC 和 FCR */
  FLASH->CR |= CR_LOCK_Set;
}

使用特权

评论回复
12
functions|  楼主 | 2020-2-7 17:38 | 只看该作者
/**
  * @简述  擦除一个 FLASH 页面.
  * @参数  Page_Address: 需要擦除的页.
  * @返回  FLASH 状态: 返回值可以是: FLASH_BUSY, FLASH_ERROR_PG,
  *                    FLASH_ERROR_WRP, FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
{
  FLASH_Status status = FLASH_COMPLETE;
  /* 检查参数 */
  assert_param(IS_FLASH_ADDRESS(Page_Address));
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(EraseTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 如果前一个操作已经完成 */
    FLASH->CR|= CR_PER_Set;
    FLASH->AR = Page_Address;
    FLASH->CR|= CR_STRT_Set;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(EraseTimeout);
    if(status != FLASH_TIMEOUT)
    {
      /* 如果擦除操作完成,失能 PER 位 */
      FLASH->CR &= CR_PER_Reset;
    }
  }
  /* 返回擦除状态 */
  return status;
}

使用特权

评论回复
13
functions|  楼主 | 2020-2-7 17:38 | 只看该作者
/**
  * @简述  擦除全部 FLASH 页面.
  * @参数  没有
  * @返回  FLASH 状态: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                    FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_EraseAllPages(void)
{
  FLASH_Status status = FLASH_COMPLETE;
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(EraseTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 如果前一个操作已经完成,擦除所有的页 */
     FLASH->CR |= CR_MER_Set;
     FLASH->CR |= CR_STRT_Set;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(EraseTimeout);
    if(status != FLASH_TIMEOUT)
    {
      /* 如果擦除操作完成,失能 MER 位 */
      FLASH->CR &= CR_MER_Reset;
    }
  }      
  /* 返回擦除状态 */
  return status;
}

使用特权

评论回复
14
functions|  楼主 | 2020-2-7 17:39 | 只看该作者
/**
  * @简述  擦除 FLASH 选择字节.
  * @参数  没有
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_EraseOptionBytes(void)
{
  FLASH_Status status = FLASH_COMPLETE;
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(EraseTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 授权小信息块编程 */
    FLASH->OPTKEYR = FLASH_KEY1;
    FLASH->OPTKEYR = FLASH_KEY2;
    /* 如果前一个操作完成,擦除选项字节 */
    FLASH->CR |= CR_OPTER_Set;
    FLASH->CR |= CR_STRT_Set;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(EraseTimeout);
    if(status == FLASH_COMPLETE)
    {
      /* 如果擦除操作完成,失能 OPTER 位 */
      FLASH->CR &= CR_OPTER_Reset;
      /* 使能字节编程操作选项 */
      FLASH->CR |= CR_OPTPG_Set;
      /* 使能读出访问 */
      OB->RDP= RDP_Key;
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(ProgramTimeout);
      if(status != FLASH_TIMEOUT)
      {
        /* 如果编程操作完成,失能 OPTPG 位 */
        FLASH->CR &= CR_OPTPG_Reset;
      }
    }
    else
    {
      if (status != FLASH_TIMEOUT)
      {
        /* 失能 OPTPG 位 */
        FLASH->CR &= CR_OPTPG_Reset;
      }
    }  
  }
  /* 返回擦除状态 */
  return status;
}

使用特权

评论回复
15
functions|  楼主 | 2020-2-7 17:39 | 只看该作者
/**
  * @简述  在指定地址编写一个字.
  * @参数  Address: 将要编程的地址.
  * @参数  Data: 指定被编程的数据.
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
{
  FLASH_Status status = FLASH_COMPLETE;
  __IO uint32_t tmp = 0;

  /* 检查参数 */
  assert_param(IS_FLASH_ADDRESS(Address));
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(ProgramTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 如果前一个操作完成,编程新的第一个半字 */
    FLASH->CR |= CR_PG_Set;
    *(__IO uint16_t*)Address = (uint16_t)Data;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(ProgramTimeout);
    if(status == FLASH_COMPLETE)
    {
      /* 如果前一个操作完成,编程新的第二个半字 */
      tmp = Address + 2;

      *(__IO uint16_t*) tmp = Data >> 16;
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(ProgramTimeout);
      if(status != FLASH_TIMEOUT)
      {
        /* 失能 PG 位 */
        FLASH->CR &= CR_PG_Reset;
      }
    }
    else
    {
      if (status != FLASH_TIMEOUT)
      {
        /* 失能 PG 位 */
        FLASH->CR &= CR_PG_Reset;
      }
     }
  }
  /* 返回编程状态 */
  return status;
}

使用特权

评论回复
16
functions|  楼主 | 2020-2-7 17:39 | 只看该作者
/**
  * @简述  在特定地址编程一个半字.
  * @参数  Address: 被编程的地址.
  * @参数  Data: 指定被编程的半字数据.
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{
  FLASH_Status status = FLASH_COMPLETE;
  /* 检查参数 */
  assert_param(IS_FLASH_ADDRESS(Address));
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(ProgramTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 如果前一个操作完成,编程新的数据 */
    FLASH->CR |= CR_PG_Set;
    *(__IO uint16_t*)Address = Data;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(ProgramTimeout);
    if(status != FLASH_TIMEOUT)
    {
      /* 如果编程操作完成,失能 PG 位 */
      FLASH->CR &= CR_PG_Reset;
    }
  }
  /* 返回编程状态 */
  return status;
}

使用特权

评论回复
17
functions|  楼主 | 2020-2-7 17:40 | 只看该作者
/**
  * @简述  在指定的选项字节数据地址上编写一个半字.
  * @参数  Address: 被编程的地址.
  *                 这个参数可以是 0x1FFFF804 或 0x1FFFF806.
  * @参数  Data: 被编写的数据.
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)
{
  FLASH_Status status = FLASH_COMPLETE;
  /* 检查参数 */
  assert_param(IS_OB_DATA_ADDRESS(Address));
  status = FLASH_WaitForLastOperation(ProgramTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 授权小信息块编程 */
    FLASH->OPTKEYR = FLASH_KEY1;
    FLASH->OPTKEYR = FLASH_KEY2;
    /* 使能字节编程操作选项 */
    FLASH->CR |= CR_OPTPG_Set;
    *(__IO uint16_t*)Address = Data;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(ProgramTimeout);
    if(status != FLASH_TIMEOUT)
    {
      /* 如果编程操作完成,失能 OPTPG 位 */
      FLASH->CR &= CR_OPTPG_Reset;
    }
  }   
  /* 返回选项字节数据的编程状态 */
  return status;
}

使用特权

评论回复
18
functions|  楼主 | 2020-2-7 17:40 | 只看该作者
/**
  * @简述  对期望的页面写保护
  * @参数  FLASH_Pages: 待写保护页面的地址.
  *                 这个参数可以是:
  *                 STM32_低密度处理器: value between FLASH_WRProt_Pages0to3 和 FLASH_WRProt_Pages28to31  
  *                 STM32_中密度处理器: value between FLASH_WRProt_Pages0to3 和 FLASH_WRProt_Pages124to127
  *                 STM32_高密度处理器: value between FLASH_WRProt_Pages0to1 和 FLASH_WRProt_Pages60to61 或 FLASH_WRProt_Pages62to255
  *                 STM32_连通性处理器: value between FLASH_WRProt_Pages0to1 和 FLASH_WRProt_Pages60to61 或 FLASH_WRProt_Pages62to127   
  *                 FLASH_WRProt_AllPages
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE 或 FLASH_TIMEOUT.
  */
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
{
  uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
  FLASH_Status status = FLASH_COMPLETE;
  /* 检查参数 */
  assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));
  FLASH_Pages = (uint32_t)(~FLASH_Pages);
  WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
  WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
  WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
  WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(ProgramTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 授权小信息块编程 */
    FLASH->OPTKEYR = FLASH_KEY1;
    FLASH->OPTKEYR = FLASH_KEY2;
    FLASH->CR |= CR_OPTPG_Set;
    if(WRP0_Data != 0xFF)
    {
      OB->WRP0 = WRP0_Data;
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(ProgramTimeout);
    }
    if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))
    {
      OB->WRP1 = WRP1_Data;
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(ProgramTimeout);
    }
    if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))
    {
      OB->WRP2 = WRP2_Data;
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(ProgramTimeout);
    }
    if((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF))
    {
      OB->WRP3 = WRP3_Data;
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(ProgramTimeout);
    }
    if(status != FLASH_TIMEOUT)
    {
      /* 如果编程操作完成,失能 OPTPG 位 */
      FLASH->CR &= CR_OPTPG_Reset;
    }
  }
  /* 返回写保护操作状态 */
  return status;      
}

使用特权

评论回复
19
functions|  楼主 | 2020-2-7 17:41 | 只看该作者
/**
  * @简述  使能或者失能读出保护.
  * @注解   如果在调用这个函数之前使用者已经编程了其它的选项字节,在这个
  *         函数擦除所有的选项字节以后他必须重新编程那些选项字节.
  * @参数  Newstate: 读出保护的新状态.
  *                  这个参数可以是: ENABLE 或 DISABLE.
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE or FLASH_TIMEOUT.
  */
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
{
  FLASH_Status status = FLASH_COMPLETE;
  /* 检查参数 */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  status = FLASH_WaitForLastOperation(EraseTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* 授权小信息块编程 */
    FLASH->OPTKEYR = FLASH_KEY1;
    FLASH->OPTKEYR = FLASH_KEY2;
    FLASH->CR |= CR_OPTER_Set;
    FLASH->CR |= CR_STRT_Set;
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(EraseTimeout);
    if(status == FLASH_COMPLETE)
    {
      /* 如果擦除操作完成,失能 OPTER 位 */
      FLASH->CR &= CR_OPTER_Reset;
      /* 使能字节编程操作选项 */
      FLASH->CR |= CR_OPTPG_Set;
      if(NewState != DISABLE)
      {
        OB->RDP = 0x00;
      }
      else
      {
        OB->RDP = RDP_Key;  
      }
      /* 等待最后一个操作完成 */
      status = FLASH_WaitForLastOperation(EraseTimeout);
      if(status != FLASH_TIMEOUT)
      {
        /* 如果编程操作完成,失能 OPTPG 位 */
        FLASH->CR &= CR_OPTPG_Reset;
      }
    }
    else
    {
      if(status != FLASH_TIMEOUT)
      {
        /* 失能 OPTER 位 */
        FLASH->CR &= CR_OPTER_Reset;
      }
    }
  }
  /* 返回写保护操作状态 */
  return status;      
}

使用特权

评论回复
20
functions|  楼主 | 2020-2-7 17:41 | 只看该作者
/**
  * @简述  编写FLASH用户选择字节: IWDG_SW / RST_STOP / RST_STDBY.
  * @参数  OB_IWDG: 选择 IWDG 模式
  *          这个参数可以是下面的值之一:
  *          OB_IWDG_SW: 选择软件独立看门狗
  *          OB_IWDG_HW: 选择硬件独立看门狗
  * @参数  OB_STOP: 当进入 STOP 模式产生复位事件.
  *          这个参数可以是下面的值之一:
  *          OB_STOP_NoRST: 进入 STOP 模式不产生复位
  *          OB_STOP_RST:   进入 STOP 模式产生复位
  * @参数  OB_STDBY: 当进入 Standby 模式产生复位事件.
  *          这个参数可以是下面的值之一:
  *          OB_STDBY_NoRST: 进入 Standby 模式不产生复位
  *          OB_STDBY_RST:   进入 Standby 模式不产生复位
  * @返回  FLASH Status: 返回值可以是: FLASH_ERROR_PG, FLASH_ERROR_WRP,
  *                      FLASH_COMPLETE or FLASH_TIMEOUT.
  */
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY)
{
  FLASH_Status status = FLASH_COMPLETE;

  /* 检查参数 */
  assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
  assert_param(IS_OB_STOP_SOURCE(OB_STOP));
  assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));

  /* 授权小信息块编程 */
  FLASH->OPTKEYR = FLASH_KEY1;
  FLASH->OPTKEYR = FLASH_KEY2;
  /* 等待最后一个操作完成 */
  status = FLASH_WaitForLastOperation(ProgramTimeout);
  if(status == FLASH_COMPLETE)
  {  
    /* 使能字节编程操作选项 */
    FLASH->CR |= CR_OPTPG_Set;
    OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8)));
    /* 等待最后一个操作完成 */
    status = FLASH_WaitForLastOperation(ProgramTimeout);
    if(status != FLASH_TIMEOUT)
    {
      /* 如果编程操作完成,失能 OPTPG 位 */
      FLASH->CR &= CR_OPTPG_Reset;
    }
  }   
  /* 返回选项字节编程状态 */
  return status;
}

使用特权

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

本版积分规则

39

主题

446

帖子

1

粉丝