深入解析GD32的I/O重映射:从部分映射到完全映射的实战指南
1. 认识GD32的I/O重映射功能第一次接触GD32的I/O重映射时我也是一头雾水。简单来说这个功能允许我们把某个外设的引脚从默认位置搬家到其他引脚上。想象一下你家的电路插座原本电视机插在客厅的插座上现在通过延长线可以改接到卧室的插座——I/O重映射就是这个原理。为什么需要这个功能呢在实际项目中我遇到过好几次这样的情况默认引脚被其他功能占用了或者PCB布线时发现默认引脚走线特别不方便。这时候重映射就能救场让硬件设计更加灵活。GD32的I/O重映射分为两种部分映射只改变部分引脚的位置完全映射所有相关引脚都重新安排位置以TIMER1为例它的4个PWM通道默认在GPIOA的8-11脚。但通过重映射我们可以把它们整体搬到GPIOB的13-15脚和PA8脚部分映射或者全部移到GPIOB的13-15脚和PA15脚完全映射。这个功能在PCB布线遇到困难时特别实用我就靠它解决过好几次布线冲突的问题。2. 配置重映射的完整流程2.1 硬件准备与时钟使能在开始重映射之前有几步准备工作必不可少。首先得确保相关GPIO端口和AFIOAlternate Function I/O复用功能I/O的时钟已经打开。这里有个坑我踩过忘记开AFIO时钟会导致配置完全不生效。// 必须开启的时钟 rcu_periph_clock_enable(RCU_GPIOA); // GPIOA时钟 rcu_periph_clock_enable(RCU_GPIOB); // GPIOB时钟 rcu_periph_clock_enable(RCU_AF); // AFIO时钟 rcu_periph_clock_enable(RCU_TIMER1);// TIMER1时钟2.2 理解重映射寄存器GD32通过两个特殊寄存器控制重映射功能AFIO_PCF0端口配置寄存器0AFIO_PCF1端口配置寄存器1这两个寄存器就像交通指挥中心决定哪些外设引脚可以改道。以TIMER1为例它的重映射由PCF0的bit8和bit9控制#define GPIO_TIMER1_PARTIAL_REMAP0 ((uint32_t)0x00180100U) // bit90, bit81 #define GPIO_TIMER1_PARTIAL_REMAP1 ((uint32_t)0x00180200U) // bit91, bit80 #define GPIO_TIMER1_FULL_REMAP ((uint32_t)0x00180300U) // bit91, bit81实际使用时我发现直接操作寄存器比较麻烦GD32提供了更简便的库函数gpio_pin_remap_config(GPIO_TIMER1_FULL_REMAP, ENABLE);3. 实战TIMER1 PWM通道重映射3.1 部分映射配置假设我们需要将TIMER1的部分PWM通道重映射。以部分映射1为例TIMER1_CH1/CH2/CH3重映射到PB13/PB14/PB15CH0保留在PA8// 1. 使能时钟同上 // 2. 配置重映射 gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP1, ENABLE); // 3. 配置GPIO为复用推挽输出 gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); // CH0 gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); // CH1-3这里有个细节要注意GPIO的速率设置要根据实际需求来。我调试电机控制时发现PWM频率超过10kHz时最好用50MHz的GPIO速度否则波形会有畸变。3.2 完全映射配置如果需要把所有PWM通道都重映射配置也很类似gpio_pin_remap_config(GPIO_TIMER1_FULL_REMAP, ENABLE); // PA15需要特别注意它可能默认是JTAG功能 gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE); // 禁用JTAG保留SWD gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15); // CH0现在在PA15完全映射时有个大坑PA15默认是JTAG的TDI引脚。如果不先禁用JTAG功能重映射会失效。这个问题折磨了我整整一个下午最后才发现是JTAG在作怪。4. 备用功能选择与特殊案例4.1 引脚功能冲突处理GD32有些引脚是多面手比如PA0既可以做TIMER1_CH0也能做TIMER1_ETI外部触发输入。但这两个功能不能同时使用就像你不能同时用同一个插座给手机充电和插台灯。/* 配置PA0为TIMER1 CH0PWM输出*/ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0); /* 或者配置为TIMER1 ETI外部触发输入*/ gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);在电机控制项目中我遇到过需要动态切换这两种功能的场景。解决方案是在运行时重新配置GPIO模式但要记得先停止定时器。4.2 重映射的实际应用技巧经过多个项目的实践我总结了几个实用技巧PCB设计阶段提前规划好所有外设的重映射方案在原理图中标注备用引脚调试阶段先用简单代码测试重映射是否生效比如点亮LED量产固件固定使用一种映射方案避免不同版本硬件出现兼容性问题文档记录在代码中详细注释重映射配置方便后续维护有个真实案例我们的一款产品因为PCB改版不得不把UART1从PA9/PA10重映射到PB6/PB7。通过重映射功能硬件工程师不用重新打板我只需要更新固件配置就解决了问题。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2459625.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!