单片机学习!
目录
前言
STM32单片机中片上外设的端口可以借指定GPIO口来输出,也就是引脚复用。但是当指定端口输出冲突了,没法同时使用时怎么办呢?本文介绍问题的解决办法:引脚重映射。
一、引脚重映射的作用
引脚定义表:
虽然引脚与外设都是规定好的,但是还可以根据情况做一次改动。在引脚定义表重定义(重映射)这一列,还可以对应更改。
对于 USART2_CTS 和 TIM2_CH1 同时使用,但是查看引脚定义表默认复用功能这一列它俩都在PA0端口输出,引脚复用冲突了,没法同时使用。这时可以在重定义功能这一列里找一下,有 TIM2_CH1 ,那么 TIM2_CH1 就可以从PA0端口输出换为从PA15端口输出。这样就避免了两个外设引脚的冲突。但是如果重定义功能这一列里找不到,那外设复用的GPIO就不能挪位置。
配置重映射需要用AFIO来完成。
二、重映射使用的库函数
2.1 RCC_APB2PeriphClockCmd 函数
代码示例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
2.2 GPIO_PinRemapConfig函数
代码示例:
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
三、重映射步骤
- 第一步、开启AFIO时钟,引脚重映射需要使用AFIO,就要开启AFIO的时钟。
- 第二步、引脚重映射配置。
- 第三步、解除调试端口复用(重映射的引脚与调试端口冲突时)。
以上步骤可根据需求调整。第一步为引脚重映射必要步骤,第二、第三步可更具具体情况选择使用。
四、重映射代码示例
从引脚定义表里可以看到,TIM2的CH1可以从PA0挪到PA15引脚上。这里就以TIM2的CH1的引脚重映射举例。
4.1 开启AFIO时钟
首先,要使用AFIO,所以第一步需要开启AFIO的时钟。AFIO是APB2的设备,开启时钟时需注意使用RCC的APB2库函数。
代码示例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//引脚重映射开启AFIO时钟
4.2 引脚重映射配置
第二步、引脚重映射配置,需要用到 GPIO_PinRemapConfig 库函数。函数定义中可以看到函数的第一个参数的选项非常多,这些都是重映射的方式,每个方式对应的关系可以查看参考手册AFIO这一节,里面有引脚重映射的内容和表格,表格里是重映射方式和引脚更改的关系。本文以TIM2的重映射方式和引脚更改的关系举例,下表为TIM2复用功能重映射(重映像就是重映射):
表中有四种重映射的方式:
- 第一种:没有重映射,引脚就是PA0、PA1、PA2、PA3.
- 第二种:部分重映射方式1,引脚就是PA15、PB3、PA2、PA3,只有前两个引脚变了。
- 第三种:部分重映射方式2,引脚就是PA0、PA1、PB10、PB11,只有后两个引脚变了。
- 第四种:完全重映射,引脚就是PA15、PB3、PB10、PB11,就是四个引脚都更改位置。
以上就是TIM2复用功能重映像表中,重映射方式和引脚对应关系,同理可查看参考手册中其他重映射的表。
TIM2的CH1的引脚重映射对应表可知,需要把PA0改到PA15,就可以选择部分重映射方式1和完全重映射这两种。
GPIO_PinRemapConfig 库函数定义中TIM2的重映射方式:
* @arg GPIO_PartialRemap1_TIM2 : TIM2 Partial1 Alternate Function mapping
* @arg GPIO_PartialRemap2_TIM2 : TIM2 Partial2 Alternate Function mapping
* @arg GPIO_FullRemap_TIM2 : TIM2 Full Alternate Function mapping
- GPIO_PartialRemap1_TIM2 :TIM2部分重映射方式1
- GPIO_PartialRemap2_TIM2 :TIM2部分重映射方式2
- GPIO_FullRemap_TIM2 :TIM2完全重映射
如果定义中以上三种都不选择,就是TIM2没有重映射。对应表格中的四种方式。这里选择部分重映射方式1的参数。
代码示例:
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//引脚重映射选择
以上代码就可以把PA0改到PA15了。
4.3 解除调试端口复用
第三步、解除调试端口复用。查看文章的最前面的表,引脚定义表可知,PA15引脚上电后默认复用为了调试端口JTDI,要让PA15引脚作为普通的GPIO口或者复用定时器的通道,还需要先关闭调试端口JTDI的复用,还需要用到 GPIO_PinRemapConfig 库函数。
以下库函数定义中的三个参数就是用来接触调试端口的复用的:
* @arg GPIO_Remap_SWJ_NoJTRST : Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST
* @arg GPIO_Remap_SWJ_JTAGDisable : JTAG-DP Disabled and SW-DP Enabled
* @arg GPIO_Remap_SWJ_Disable : Full SWJ Disabled (JTAG-DP + SW-DP)
SWJ就是SWD和JTAG这两种调试方式。
- 第一个,GPIO_Remap_SWJ_NoJTRST,就是解除 JTRST 引脚的复用。在引脚定义表中就是 NJTRST 也就是PB4。使用 GPIO_Remap_SWJ_NoJTRST 参数,PB4 就变为正常的GPIO口了。其他四个端口PA13、PA14、PA15、PB3仍然是调试端口,不能当做GPIO口来使用。
- 第二个,GPIO_Remap_SWJ_JTAGDisable,就是解除 JTAG 调试端口的复用,在引脚定义表中就是PA15、PB3、PB4这三个端口全都变回GPIO口,PA13和PA14任为SWD的调试端口。
- 第三个,GPIO_Remap_SWJ_Disable,就是把SWD和JTAG的调试端口全部解除,在引脚定义表中就是PA13、PA14、PA15、PB3、PB4这5个引脚全部变成普通的GPIO,没有调试功能了。这个参数不可随意调用,一旦调用这个参数并且下载程序后,调试端口就没有了,这之后的STLINK就下载不进去程序了,这时只能使用串口下载,下载一个没有解除调试端口的新的程序。这样调试端口才能重新使用。
以上描述对应参考手册中的以下两个表:
这个表对应IO口能用还是不能用:
因为把PA0改到PA15,需要使用PA15,通常就是解除 JTAG 的复用,保留 SWD 的复用,所以这里选择GPIO_Remap_SWJ_JTAGDisable参数。
代码示例:
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除调试端口复用
这样就可以使用PA15这个引脚了。
总结:
- 若需要PA15、PB3、PB4这3个引脚当作GPIO来使用,首先需要打开AFIO时钟,再用AFIO将JTAG复用解除掉。
- 若需要重映射定时器或者其他外设的复用引脚,首先需要打开AFIO时钟,再用AFIO重映射外设复用的引脚。
- 若需要重映射的引脚又正好是调试端口,首先需要打开AFIO时钟,再用AFIO重映射外设复用的引脚,最后用AFIO将JTAG复用解除掉。