前言
最近在STM32的IO复用上面吃了一个亏,所以把问题记录下来并且将IO复用的原理再深刻理解一下。
起因就是自己做的项目需要用一个SPI读取数据的功能,我是用的STM32F429的HAL库,所以就将SPI的例子复制过来,之前SPI读的是开发板上面的spiflash,用的是SPI5,我自己的项目用的是SPI3,所以这里偷了个懒,直接把SPI5全部替换成了SPI3,但是运行的时候就出问题了,用示波器量SPI的SCK引脚没有时钟,读出来数据都是0x00,排查了半天线路和代码,感觉哪哪都没问题,最后偶然发现了这行代码:
GPIO_Initure.Alternate=GPIO_AF5_SPI3;
是不是这里有哪不对劲,F12进去以后,发现除了GPIO_AF5_SPI3以外,还存在一个GPIO_AF6_SPI3,我本来以为AF复用只能有一种呢,是我太年轻了。。。然后赶紧查了STM32F426的芯片数据手册。
原来我用的PA15/PB3/PB4/PB5引脚对应的SPI3,是AF6的复用,赶忙修改了,然后时钟和通讯都正常了,看来还是自己对复用理解不深刻,所以导致了这个问题的发生,下面详细分析一下IO的复用功能。
一、什么是IO复用
STM32的IO复用是指STM32微控制器中的通用输入输出(GPIO)引脚可以配置为执行除了基本的输入输出功能之外的其他特定功能。这些特定功能通常与STM32的内置外设(如ADC、TIM、USART等)相关联。当GPIO引脚被配置为执行这些特定功能时,就称为引脚复用。
具体来说,STM32的每个GPIO引脚都通过一个复用器连接到多个内置外设或模块。这个复用器允许一次只选择一个复用功能(AF)连接到对应的IO口,从而确保共用同一个IO引脚的外设之间不会发生冲突。
二、IO复用控制寄存器
上图是STM32F429的0到7引脚对应的GPIOx_AFRL寄存器,控制前7脚的复用,对于引脚 8-15,控制寄存器为 GPIOx_AFRH。我们配置相应的寄存器 GPIOx_AFRL 或者 GPIOx_AFRH,让对应引脚通过复用器连接到对应的复用功能外设。32 位寄存器 GPIOx_AFRL 每四个位控制一个 IO 口,所以每个寄存器控制32/4=8 个 IO 口。寄存器对应四位的值配置决定这个 IO 映射到哪个复用功能 AF。
三、代码实现
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟
__HAL_RCC_SPI3_CLK_ENABLE(); //使能SPI3时钟
//PB345
GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速
GPIO_Initure.Alternate=GPIO_AF6_SPI3; //复用为SPI3
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
}
贴出了自己SPI引脚的使能,复用的配置分别为
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
以及
GPIO_Initure.Alternate=GPIO_AF6_SPI3; //复用为SPI3
注意,GPIO_Initure.Alternate如何选择要看芯片对应的手册,除了ADC和DAC设置GPIO_Initure.Mode为模拟通道意外,其它外设都像这样配置成复用模式。
标签:SPI3,Initure,引脚,复用,STM32,IO,GPIO From: https://blog.csdn.net/qq_38072731/article/details/140736482