PY32F003 管脚复用--在 OB(Option Bytes)中禁用和启用 PF2/RESET

1.简介

当 PF2/NRST作用为GPIO 口时,SWD口又复用为其他IO功能时,需要重新下载程序,会无法下载。

有三种方式解决:


 (1) 在SWD口复用为其他io功能 前停留2秒, 保证上电后有足够长的烧录等待时间

(2)把boot0引脚上拉3.3V,再插入SWD进行下载

(3)把PF2/NRST改回 复位功能

PF2/NRST这个PIN是比较麻烦的一个功能脚, 因为默认启用了RESET功能, 不受PIN模式的影响, 所以无论你把它设置成INPUT, OUTPUT 还是 ANALOG, RESET永远生效, 和这个PIN同处于同一个物理管脚的PIN就没法正常使用.

要禁用它的RESET功能, 要在芯片的 OB(Option Bytes)里修改. OB 位于地址 0x1FFF 0E80, 占用4个字节, 其中2字节是配置, 另外2字节是这两个字节的反码. 对应 RESET 功能的设置 NRST_MODE 存储于第14位, 0表示仅复位输入, 1表示禁用复位输入,启用 GPIO 功能.

闪存解锁
在复位后, flash 存储器会被保护,防止不想要的(比如电干扰引起的)写和擦除操作。写 FLASH_CR
存器是不被允许的(除了用作 reload option bytes OBL_LAUNCH 位)。每次对 flash 的写和擦除操作,都必
须通过写 FLASH_KEYR 寄存器,产生 Unlock 时序,启用 FLASH_CR 寄存器的访问。
具体步骤如下:
步骤 1 :向 FLASH_KEYR 寄存器写入 KEY1=0x4567 0123
步骤 2 :向 FLASH_KEYR 寄存器写入 KEY2=0xCDEF 89AB
任何错误的时序都会锁住 FLASH_CR 寄存器,直到下一次复位。在错误的 KEY 时序时,总线错误被发现,
并产生 Hard Fault 中断。这样的错误包括第一个写周期的 KEY1 不匹配,或者 KEY1 匹配,但第二个写周期的 KEY2 不匹配。
FLASH_CR 寄存器可以通过软件写 FLASH_CR 寄存器的 LOCK 位被再次锁住。
另外,当 FLASH_SR 寄存器的 BSY 位被置位时, FLASH_CR 寄存器不能被写。此时,任何尝试进行写该
寄存器( FLASH_CR )的操作会引起 AHB 总线的拖延,直到 BSY1 位被清零。
Flash 选项字节写
复位后, FLASH_CR 寄存器中与选项字节相关的位是被写保护的。当对选项字节进行相关操作前, FLASH_CR 寄存器中的 OPTLOCK 位必须被清零。
以下步骤用来解锁该寄存器:
1) 通过 Unlock 时序, unlock FLASH_CR 寄存器的写保护
2) FLASH_OPTKEYR 寄存器,写 OPTKEY1=0x0819 2A3B
3) FLASH_OPTKEYR 寄存器,写 OPTKEY2=0x4C5D 6E7F
任何错误的时序都会 lock FLASH_CR 寄存器,直到下一次复位。在错误的 KEY 时序时,总线错误被发 现,并产生 Hard Fault 中断。
User option information flash option bytes )可以通过软件写 FLASH_CR 寄存器的 OPTLOCK 位,被 保护住,以防止不想要的 erase/program 操作。
如果软件置位 Lock 位,则 OPTLOCK 位也被自动置位。
#define RSTPIN_MODE_GPIO  0

static void APP_FlashSetOptionBytes(void)
{
  FLASH_OBProgramInitTypeDef OBInitCfg;

  HAL_FLASH_Unlock();         /* 解锁FLASH */
  HAL_FLASH_OB_Unlock();      /* 解锁OPTION */

  /* 配置OPTION选项*/
  OBInitCfg.OptionType = OPTIONBYTE_USER;
  OBInitCfg.USERType = OB_USER_BOR_EN | OB_USER_BOR_LEV | OB_USER_IWDG_SW | OB_USER_IWDG_SW | OB_USER_NRST_MODE | OB_USER_nBOOT1;
	OBInitCfg.RDPLevel = OB_RDP_LEVEL_0;//RDP
#if(RSTPIN_MODE_GPIO==1)
  /* BOR不使能/BOR上升3.2,下降3.1/软件模式看门狗/GPIO功能/System memory作为启动区 */
  OBInitCfg.USERConfig = OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_WWDG_SW | OB_RESET_MODE_GPIO | OB_BOOT1_SYSTEM;
#else 
  /* BOR不使能/BOR上升3.2,下降3.1/软件模式看门狗/RST功能/System memory作为启动区 */
	OBInitCfg.USERConfig = OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_WWDG_SW | OB_RESET_MODE_RESET | OB_BOOT1_SYSTEM;
#endif

  /* 启动option byte编程 */
  HAL_FLASH_OBProgram(&OBInitCfg);

  HAL_FLASH_Lock();          /* 锁定FLASH */
  HAL_FLASH_OB_Lock();       /* 锁定OPTION */

  /* 产生一个复位,option byte装载 */
  HAL_FLASH_OB_Launch();
}




//使用下初始化,可以保证只初始化一次,避免出现重复修改失败,导致flash 锁死
	if(RSTPIN_MODE_GPIO ==0 && READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_GPIO)//如果是gpio模式,需要修改为RST模式
		{
			/* 如果没关闭则调用 */
			APP_FlashSetOptionBytes();
		}else if(RSTPIN_MODE_GPIO==1 && READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_RESET)//如果是RST模式,需要修改为gpio模式
		{
			APP_FlashSetOptionBytes();
		}

需要把PF2q启用 GPIO 功能时,

修改  #define RSTPIN_MODE_GPIO  1

配置输出

MCU_GPIO_Conf(GPIOF, GPIO_PIN_2, GPIO_MODE_OUTPUT_PP, GPIO_PULLUP);

设置高电平

MCU_GPIO_Set(GPIOF, GPIO_PIN_2,GPIO_PIN_RESET);

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chilian12321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值