普冉PY32系列(七) SOP8, SOP10和SOP16封装的PY32F003/PY32F002A管脚复用

科技资讯 投稿 7200 0 评论

普冉PY32系列(七) SOP8, SOP10和SOP16封装的PY32F003/PY32F002A管脚复用

目录

    普冉PY32系列(一 PY32F0系列32位Cortex M0+ MCU简介
  • 普冉PY32系列(二 Ubuntu GCC Toolchain和VSCode开发环境
  • 普冉PY32系列(三 PY32F002A资源实测 - 这个型号不简单
  • 普冉PY32系列(四 PY32F002A/003/030的时钟设置
  • 普冉PY32系列(五 使用JLink RTT代替串口输出日志
  • 普冉PY32系列(六 通过I2C接口驱动PCF8574扩展的1602LCD
  • 普冉PY32系列(七 SOP8,SOP10,SOP16封装的PY32F002A/PY32F003管脚复用

PY32F0系列的封装

    20PIN, 24PIN 和 32PIN, 带有独立的 NRST 和 BOOT0, PIN脚互相独立不复用;
  • 8PIN, 10PIN 和 16PIN, 没有 BOOT0, 存在多个PIN脚共用同一个物理管脚的情况

这篇主要介绍没有BOOT0的情况如何修改Option Bytes, 以及如何在物理管脚上使用不同的PIN

PY32F002A 的封装

PY32F002AL15S, PY32F002AA15M, PY32F002AW15S

PY32F002AW15U, PY32F002AF15P

PY32F003 的封装

PY32F003L1xS, PY32F003L2XD, PY32F003L2xS

PY32F003A18N, PY32F003W1XS

PY32F002A/PY32F003 管脚复用

在 OB(Option Bytes中禁用和启用 PF2/RESET

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

对于正常带 PF4/BOOT0 的型号, 在上电时拉高 BOOT0, 就可以从 system memory 启动 boot loader, 通过 ISP 工具连接后在工具里修改 OB, 但是 SOP8 和 SOP16 这些封装没有 BOOT0, 所以没法使用 ISP 工具修改. 只能通过代码或第三方工具(例如JLink修改. 以下以LL库为例, 说明在代码中修改OB的方法

static void APP_FlashSetOptionBytes(void
{
  FLASH_OBProgramInitTypeDef OBInitCfg;

  LL_FLASH_Unlock(;
  LL_FLASH_OB_Unlock(;

  OBInitCfg.OptionType = OPTIONBYTE_USER;
  OBInitCfg.USERType = OB_USER_BOR_EN | OB_USER_BOR_LEV | OB_USER_IWDG_SW | OB_USER_WWDG_SW | OB_USER_NRST_MODE | OB_USER_nBOOT1;
  /*
   * 默认的值: OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_WWDG_SW | OB_RESET_MODE_RESET | OB_BOOT1_SYSTEM;
  */
  OBInitCfg.USERConfig = OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_WWDG_SW | OB_RESET_MODE_GPIO | OB_BOOT1_SYSTEM;
  LL_FLASH_OBProgram(&OBInitCfg;

  LL_FLASH_Lock(;
  LL_FLASH_OB_Lock(;
  /* 重新载入OB, 这会触发软复位, MCU重启 */
  LL_FLASH_OB_Launch(;
}

注意, 上面这个方法执行后会重启MCU, 所以在调用前要做个判断, 否则它会一直循环重启下去

/* 检查 PF2 是否已经关闭了复位 */
if(READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE == OB_RESET_MODE_RESET
{
  /* 如果没关闭则调用 */
  APP_FlashSetOptionBytes(;
}
// 否则继续正常执行

这样执行完之后, RESET按钮就失效了, 如果要恢复, 要再将OB改回默认的值

OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_WWDG_SW | OB_RESET_MODE_RESET | OB_BOOT1_SYSTEM;

同一物理管脚的其它PIN, 设为模拟(ANALOG模式

以下以SOP16封装的为例, 启用 PF1, PF0, 禁用对应同一管脚的 PA14 和 PF2

static void APP_GPIO_Config(void
{
  //...

  // PF1 SCL
  GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
  LL_GPIO_Init(GPIOF, &GPIO_InitStruct;

  // PF0 SDA
  GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
  LL_GPIO_Init(GPIOF, &GPIO_InitStruct;

  /**
   * 根据数据手册第20页, 同管脚的其它PIN应当设为 ANALOG.
  */
  // PA14
  LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_14, LL_GPIO_MODE_ANALOG;
  // PF2
  LL_GPIO_SetPinMode(GPIOF, LL_GPIO_PIN_2, LL_GPIO_MODE_ANALOG;

  //...
}

电路连线避免干扰

管脚复用之后, 一些功能脚带的开关按钮和电阻电容就会对其它PIN造成影响。

启动增加延时, 确保上电烧录

因为小封装没有 BOOT0, 所以在 SWD 口烧录失败的情况下, 没法用 ISP 工具救场, 如果你的程序加电后没有预留足够长时间的 delay, 又把 SWD 口的 PA13 PA14 给关掉了, 那下一次烧录就会干瞪眼。

int main(void
{
  uint8_t i;

  BSP_RCC_HSI_24MConfig(;
  /** 
   * 在SWD口关闭前停留2秒, 保证上电后有足够长的烧录等待时间
  */
  LL_mDelay(2000;

  //...

代码示例

以 SOP16 封装的 PY32F003W18S 为例, 依然使用 1602LCD 作为参考。

源代码已经提交到 GitHub 仓库, 地址: https://github.com/IOsetting/py32f0-template/tree/main/Examples/LL/I2C/PCF8574_1602LCD_PY32F003W_PF0_PF1

编程笔记 » 普冉PY32系列(七) SOP8, SOP10和SOP16封装的PY32F003/PY32F002A管脚复用

赞同 (32) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽