STM32的PB12与PA15引脚作为IO使用时可能踩的坑

首先是PB12,通常来说PB12作为普通IO不会有什么问题,跟其他IO一样,配置好时钟与模式就能愉快地操作。
但是当SPI2被开启使用时,问题就来了,通常来说,用SPI的主模式操作外部FLASH等器件是很常见的需求,但是当你把SPI2配置为主模式时,你会发现PB12同时失灵了,原因在于,PB12的默认功能为SPI2的NSS引脚,SPI2配置为主模式时,这个Pin默认被用来作为该主设备的主从选择输入。
PB12的默认功能包括了SPI2的NSS片选信号
STM32的PB12与PA15引脚作为IO使用时可能踩的坑_第1张图片
因此,如果你打算把PB12拿来当普通IO,你将无法控制这个引脚。

那么,在这个情况下把SPI2_NSS配置为输出则成为了必要的操作
STM32的PB12与PA15引脚作为IO使用时可能踩的坑_第2张图片
规格书上所见,需要配置SSOE才能使得SPI2_NSS转换为输出模式,于是在初始化时,加入下面一句。

SPI2->CR2 = SPI_CR2_SSOE;
//使能NSS输出,使PB12可控

你熟悉的IO操作就又回来了。

再来是PA15,这个是今天发生的事,浪费了我30分钟,所以我觉得我需要在这里记录一下。

PA15默认是JTDI
PA15在上电后是不可用的,你需要配置AFIO_MAPR寄存器的SWJ_CFG位来关闭JTAG,只保留SWD调试口来调试你的代码,这是我一直以来的常规操作,在我的GPIOInit函数内,第一句就会包含这个操作

AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
	//关闭JTAG 释放出PB3,PB4,PA15

但是很奇怪的是,今天不行,我怎么也控制不了PA15,它一直处于高电平的状态,因为无法拉低,我以为我的目标板存在器件损坏,或者短路到电源什么的,换了PA15驱动的IC,甚至是把外围都拆了,它还是保持高电平巍然不动,当我打算把STM32吹下来换一片新的时候,我找到另一块目标板,用同样的代码跑下来发现,PA15还是不受控。

那么,和硬件没什么关系了,是我的代码出了问题。

MDK开发环境有一个很方便的调试功能,可以直接在一个寄存器配置窗口,在线点点鼠标配置寄存器,即时生效,例如USART可以像下图这样玩
STM32的PB12与PA15引脚作为IO使用时可能踩的坑_第3张图片
你不需要重新编译代码运行,就可以在这里调戏你要的寄存器,并观察结果,这是一个很好的特性。

然后我打开了AFIO的窗口,它比较简陋,没有USART那样的配置,但是一样可以发现问题。
STM32的PB12与PA15引脚作为IO使用时可能踩的坑_第4张图片
我发现无论我更改AFIO内的任何一个内容,都不会得到执行,勾选后马上会被清除,然后我搜寻了互联网,打开了我以前的代码,最终找到答案
STM32的PB12与PA15引脚作为IO使用时可能踩的坑_第5张图片

就是这样,AFIO的配置需要额外打开AFIO时钟,我原来的代码里存在着一个选项,移植过来之后配置时应该是不小心删掉了

不能用的时钟配置是这样的

RCC->APB2ENR = RCC_APB2ENR_USART1EN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_SPI1EN \
				| RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN |  \
				| RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN;
//	

加上去后是这样的

RCC->APB2ENR = RCC_APB2ENR_USART1EN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_SPI1EN \
				| RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN | RCC_APB2ENR_AFIOEN \
				| RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN;
//	

然后,PA15就可控了。

你可能感兴趣的:(MCU,STM32)