1. 为什么PB3和PB4引脚无法使用很多刚开始使用N32G45X的开发者在配置PB3和PB4引脚时都会遇到一个奇怪的问题明明按照常规GPIO配置流程操作但这两个引脚就是无法正常工作。这个问题困扰了不少人我也是在项目开发中踩过这个坑之后才明白其中的缘由。原来N32G45X芯片在复位后默认启用了JTAG调试接口而这个接口恰好占用了PB3(JTDO)和PB4(NJTRST)两个引脚。不仅如此JTAG接口还会占用PA13(JTMS)、PA14(JTCK)和PA15(JTDI)三个引脚。这意味着如果你不做任何特殊配置这五个引脚就默认被调试接口占用无法作为普通GPIO使用。我在一个实际项目中就遇到过这种情况当时需要用到PB3和PB4作为普通IO口控制外设但无论如何配置都无法正常工作。经过仔细查阅用户手册才发现问题出在调试接口的默认配置上。这个设计其实在很多ARM Cortex-M内核的MCU中都很常见目的是为了方便开发者上电后就能直接进行调试。2. JTAG与SWD调试接口的区别要解决PB3和PB4引脚被占用的问题我们首先需要了解JTAG和SWD这两种调试接口的区别。JTAG(Joint Test Action Group)是一种标准的调试接口协议它使用5个引脚(TCK、TMS、TDI、TDO和nTRST)进行通信。JTAG功能强大支持边界扫描等高级调试功能但占用的引脚资源较多。相比之下SWD(Serial Wire Debug)是ARM公司推出的一种两线调试协议只需要SWDIO和SWCLK两个引脚就能实现基本调试功能。SWD在引脚资源占用上具有明显优势特别适合引脚资源紧张的MCU应用场景。在实际项目中我发现大多数情况下SWD调试已经足够使用。除非你需要使用JTAG特有的功能否则切换到SWD模式可以释放出3个宝贵的GPIO引脚(PA15、PB3和PB4)。这对于资源受限的N32G45X项目来说无疑是一个极具吸引力的优化方案。3. 如何将调试接口切换到SWD模式要将N32G45X的调试接口从默认的JTAG模式切换到SWD模式我们需要操作AFIO(Alternate Function I/O)重映射寄存器。这里我分享两种实现方法都是我在实际项目中验证过的。第一种方法是使用官方库函数代码如下RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); // 使能AFIO时钟 GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_DISABLE, ENABLE); // 禁用JTAG启用SWD不过在实际使用中我发现这个库函数在某些情况下可能无法正常工作。经过调试发现直接操作寄存器更加可靠。下面是第二种方法直接配置AFIO寄存器RCC-APB2PCLKEN | 1 0; // 使能AFIO时钟 AFIO-RMP_CFG 0xF8FFFFFF; // 清除[26:24]位 AFIO-RMP_CFG | 0x02000000; // 设置[26:24]为010关闭JTAG启用SWD这段代码的工作原理是首先使能AFIO模块的时钟然后清除AFIO_RMP_CFG寄存器的[26:24]位最后将这些位设置为010这样就关闭了JTAG功能同时保留了SWD功能。4. 验证配置是否成功配置完成后我们需要验证是否真的释放了PB3和PB4引脚。这里我分享几个实用的验证方法首先可以尝试将PB3和PB4配置为普通GPIO输出然后通过示波器或LED观察引脚状态变化GPIO_InitType GPIO_InitStructure; // 配置PB3为推挽输出 GPIO_InitStructure.Pin GPIO_PIN_3; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 配置PB4为推挽输出 GPIO_InitStructure.Pin GPIO_PIN_4; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 翻转PB3和PB4引脚状态 GPIO_WriteBit(GPIOB, GPIO_PIN_3, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_PIN_3))); GPIO_WriteBit(GPIOB, GPIO_PIN_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_PIN_4)));如果配置成功你应该能看到PB3和PB4引脚的电平正常翻转。如果配置不成功引脚状态将不会变化。另一个验证方法是检查调试功能是否仍然可用。在切换到SWD模式后你应该仍然能够通过SWD接口(PA13和PA14)进行调试和程序下载。如果调试功能完全失效说明配置可能有问题。5. 可能遇到的问题及解决方案在实际项目中我遇到过几个与调试接口配置相关的典型问题这里分享给大家第一个问题是配置后无法下载程序。这种情况通常是因为错误地完全关闭了调试接口。如果你将AFIO_RMP_CFG[26:24]设置为100(完全关闭JTAG和SWD)那么芯片将无法通过调试接口进行编程。解决方法是通过BOOT0引脚进入系统存储器启动模式然后擦除芯片重新编程。第二个问题是配置时序不当导致的问题。AFIO配置必须在GPIO配置之前完成否则可能无法正确释放引脚。我建议的系统初始化顺序是系统时钟配置→AFIO配置→GPIO配置→外设初始化。第三个问题是不同开发环境对SWD的支持差异。有些老版本的IDE可能需要额外配置才能支持SWD调试。例如在Keil MDK中需要在Debug配置中选择SW作为调试协议而不是默认的JTAG。6. 释放引脚后的应用实例成功释放PB3和PB4引脚后这两个引脚可以像普通GPIO一样使用。这里我分享一个实际项目中的应用案例在一个工业控制器项目中我们使用PB3连接LED指示灯PB4连接蜂鸣器PA15(也被释放)连接紧急停止按钮。配置代码如下// 配置PB3为LED输出 GPIO_InitStructure.Pin GPIO_PIN_3; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 配置PB4为蜂鸣器输出 GPIO_InitStructure.Pin GPIO_PIN_4; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 配置PA15为输入(紧急停止按钮) GPIO_InitStructure.Pin GPIO_PIN_15; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; // 上拉输入 GPIO_InitPeripheral(GPIOA, GPIO_InitStructure);在这个案例中通过优化调试接口配置我们成功获得了三个额外的GPIO引脚解决了项目资源紧张的问题。这种优化在引脚资源受限的N32G45X应用中尤为重要。7. 其他复用功能配置除了切换为SWD模式外AFIO重映射寄存器还支持其他几种调试接口配置模式。这些模式可以根据项目需求灵活选择// 模式1完全启用JTAG和SWD(复位默认值) AFIO-RMP_CFG | 0x00000000; // [26:24]000 // 模式2启用JTAG和SWD但禁用NJTRST(释放PB4) AFIO-RMP_CFG | 0x01000000; // [26:24]001 // 模式3禁用JTAG启用SWD(释放PB3、PB4和PA15) AFIO-RMP_CFG | 0x02000000; // [26:24]010 // 模式4完全禁用JTAG和SWD(释放所有调试引脚) AFIO-RMP_CFG | 0x04000000; // [26:24]100在实际项目中我建议优先选择模式3(禁用JTAG启用SWD)这样既能保留基本的调试功能又能最大限度地释放GPIO资源。只有在确定不需要任何调试功能的情况下才考虑使用模式4完全关闭调试接口。8. 系统设计时的注意事项在系统设计阶段有几点关于调试接口复用的注意事项需要特别关注首先是上电初始状态问题。调试接口的配置应该在系统初始化早期完成最好在时钟配置之后立即进行。这样可以避免外设初始化时误用被占用的引脚。其次是PCB设计时的引脚分配。即使计划通过软件配置释放调试引脚在PCB设计时也应考虑将这些引脚连接到可用的测试点或保留连接器。这样在调试阶段可以灵活切换配置。第三是固件升级的兼容性。如果产品需要通过调试接口进行现场升级务必确保至少保留SWD功能。完全关闭调试接口会导致无法进行固件更新。最后是团队协作时的沟通。调试接口的配置会影响整个团队的开发流程特别是硬件和软件工程师需要就引脚使用达成一致避免硬件设计假设与软件配置不符的情况。
N32G45X调试接口复用实战:从JTAG到SWD的引脚解放之路
发布时间:2026/6/30 8:50:50
1. 为什么PB3和PB4引脚无法使用很多刚开始使用N32G45X的开发者在配置PB3和PB4引脚时都会遇到一个奇怪的问题明明按照常规GPIO配置流程操作但这两个引脚就是无法正常工作。这个问题困扰了不少人我也是在项目开发中踩过这个坑之后才明白其中的缘由。原来N32G45X芯片在复位后默认启用了JTAG调试接口而这个接口恰好占用了PB3(JTDO)和PB4(NJTRST)两个引脚。不仅如此JTAG接口还会占用PA13(JTMS)、PA14(JTCK)和PA15(JTDI)三个引脚。这意味着如果你不做任何特殊配置这五个引脚就默认被调试接口占用无法作为普通GPIO使用。我在一个实际项目中就遇到过这种情况当时需要用到PB3和PB4作为普通IO口控制外设但无论如何配置都无法正常工作。经过仔细查阅用户手册才发现问题出在调试接口的默认配置上。这个设计其实在很多ARM Cortex-M内核的MCU中都很常见目的是为了方便开发者上电后就能直接进行调试。2. JTAG与SWD调试接口的区别要解决PB3和PB4引脚被占用的问题我们首先需要了解JTAG和SWD这两种调试接口的区别。JTAG(Joint Test Action Group)是一种标准的调试接口协议它使用5个引脚(TCK、TMS、TDI、TDO和nTRST)进行通信。JTAG功能强大支持边界扫描等高级调试功能但占用的引脚资源较多。相比之下SWD(Serial Wire Debug)是ARM公司推出的一种两线调试协议只需要SWDIO和SWCLK两个引脚就能实现基本调试功能。SWD在引脚资源占用上具有明显优势特别适合引脚资源紧张的MCU应用场景。在实际项目中我发现大多数情况下SWD调试已经足够使用。除非你需要使用JTAG特有的功能否则切换到SWD模式可以释放出3个宝贵的GPIO引脚(PA15、PB3和PB4)。这对于资源受限的N32G45X项目来说无疑是一个极具吸引力的优化方案。3. 如何将调试接口切换到SWD模式要将N32G45X的调试接口从默认的JTAG模式切换到SWD模式我们需要操作AFIO(Alternate Function I/O)重映射寄存器。这里我分享两种实现方法都是我在实际项目中验证过的。第一种方法是使用官方库函数代码如下RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); // 使能AFIO时钟 GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_DISABLE, ENABLE); // 禁用JTAG启用SWD不过在实际使用中我发现这个库函数在某些情况下可能无法正常工作。经过调试发现直接操作寄存器更加可靠。下面是第二种方法直接配置AFIO寄存器RCC-APB2PCLKEN | 1 0; // 使能AFIO时钟 AFIO-RMP_CFG 0xF8FFFFFF; // 清除[26:24]位 AFIO-RMP_CFG | 0x02000000; // 设置[26:24]为010关闭JTAG启用SWD这段代码的工作原理是首先使能AFIO模块的时钟然后清除AFIO_RMP_CFG寄存器的[26:24]位最后将这些位设置为010这样就关闭了JTAG功能同时保留了SWD功能。4. 验证配置是否成功配置完成后我们需要验证是否真的释放了PB3和PB4引脚。这里我分享几个实用的验证方法首先可以尝试将PB3和PB4配置为普通GPIO输出然后通过示波器或LED观察引脚状态变化GPIO_InitType GPIO_InitStructure; // 配置PB3为推挽输出 GPIO_InitStructure.Pin GPIO_PIN_3; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 配置PB4为推挽输出 GPIO_InitStructure.Pin GPIO_PIN_4; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 翻转PB3和PB4引脚状态 GPIO_WriteBit(GPIOB, GPIO_PIN_3, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_PIN_3))); GPIO_WriteBit(GPIOB, GPIO_PIN_4, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_PIN_4)));如果配置成功你应该能看到PB3和PB4引脚的电平正常翻转。如果配置不成功引脚状态将不会变化。另一个验证方法是检查调试功能是否仍然可用。在切换到SWD模式后你应该仍然能够通过SWD接口(PA13和PA14)进行调试和程序下载。如果调试功能完全失效说明配置可能有问题。5. 可能遇到的问题及解决方案在实际项目中我遇到过几个与调试接口配置相关的典型问题这里分享给大家第一个问题是配置后无法下载程序。这种情况通常是因为错误地完全关闭了调试接口。如果你将AFIO_RMP_CFG[26:24]设置为100(完全关闭JTAG和SWD)那么芯片将无法通过调试接口进行编程。解决方法是通过BOOT0引脚进入系统存储器启动模式然后擦除芯片重新编程。第二个问题是配置时序不当导致的问题。AFIO配置必须在GPIO配置之前完成否则可能无法正确释放引脚。我建议的系统初始化顺序是系统时钟配置→AFIO配置→GPIO配置→外设初始化。第三个问题是不同开发环境对SWD的支持差异。有些老版本的IDE可能需要额外配置才能支持SWD调试。例如在Keil MDK中需要在Debug配置中选择SW作为调试协议而不是默认的JTAG。6. 释放引脚后的应用实例成功释放PB3和PB4引脚后这两个引脚可以像普通GPIO一样使用。这里我分享一个实际项目中的应用案例在一个工业控制器项目中我们使用PB3连接LED指示灯PB4连接蜂鸣器PA15(也被释放)连接紧急停止按钮。配置代码如下// 配置PB3为LED输出 GPIO_InitStructure.Pin GPIO_PIN_3; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 配置PB4为蜂鸣器输出 GPIO_InitStructure.Pin GPIO_PIN_4; GPIO_InitPeripheral(GPIOB, GPIO_InitStructure); // 配置PA15为输入(紧急停止按钮) GPIO_InitStructure.Pin GPIO_PIN_15; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; // 上拉输入 GPIO_InitPeripheral(GPIOA, GPIO_InitStructure);在这个案例中通过优化调试接口配置我们成功获得了三个额外的GPIO引脚解决了项目资源紧张的问题。这种优化在引脚资源受限的N32G45X应用中尤为重要。7. 其他复用功能配置除了切换为SWD模式外AFIO重映射寄存器还支持其他几种调试接口配置模式。这些模式可以根据项目需求灵活选择// 模式1完全启用JTAG和SWD(复位默认值) AFIO-RMP_CFG | 0x00000000; // [26:24]000 // 模式2启用JTAG和SWD但禁用NJTRST(释放PB4) AFIO-RMP_CFG | 0x01000000; // [26:24]001 // 模式3禁用JTAG启用SWD(释放PB3、PB4和PA15) AFIO-RMP_CFG | 0x02000000; // [26:24]010 // 模式4完全禁用JTAG和SWD(释放所有调试引脚) AFIO-RMP_CFG | 0x04000000; // [26:24]100在实际项目中我建议优先选择模式3(禁用JTAG启用SWD)这样既能保留基本的调试功能又能最大限度地释放GPIO资源。只有在确定不需要任何调试功能的情况下才考虑使用模式4完全关闭调试接口。8. 系统设计时的注意事项在系统设计阶段有几点关于调试接口复用的注意事项需要特别关注首先是上电初始状态问题。调试接口的配置应该在系统初始化早期完成最好在时钟配置之后立即进行。这样可以避免外设初始化时误用被占用的引脚。其次是PCB设计时的引脚分配。即使计划通过软件配置释放调试引脚在PCB设计时也应考虑将这些引脚连接到可用的测试点或保留连接器。这样在调试阶段可以灵活切换配置。第三是固件升级的兼容性。如果产品需要通过调试接口进行现场升级务必确保至少保留SWD功能。完全关闭调试接口会导致无法进行固件更新。最后是团队协作时的沟通。调试接口的配置会影响整个团队的开发流程特别是硬件和软件工程师需要就引脚使用达成一致避免硬件设计假设与软件配置不符的情况。