STM32 GPIO的学习

1.GPIO的作用
目前我使用的是STM32F0xx系列, 参考数据手册Memory Map处可以看到ST所有的外设寄存器均处于Peripherals处,地址范围为0x40000 0000~ 0x48001800。其中包含了APB1~APB2,AHB1~AHB2.参考详细的数据手册可以发现,GPIOA~F 均处于Peripherals的外设AHB2中,详细的可以看下图。
Memory Map
AHB1~2
APB2
APB1
根据上面寄存器在APB,AHB中的分布,即可知GPIO 处于AHB2中,要知道,不管配置任何寄存器,首先第一点是要配置时钟(而配置时钟会在另外一个博客中讲解,如下时钟树红色标识处可知),再者在AHB2寄存器中使能GPIO口。接下来再配置GPIO相应的寄存器达到相应的功能。
Clock tree

2.GPIO口的配置
每个通用I/O口都有4个32位配置寄存器(GPIOx_ MODER, GPIOx_ OTYPER,GPIOx_ OSPEED和GPIOx_ PUPDR),2个32位数据寄存器(GPIOx _ IDR和GPIOx _ ODR)和1个32位置位/复位寄存器(GPIOx_ BSRR)。GPIOA和GPIOB还含有1个32位锁存寄存器(GPIOx_LCKR)和2个32位复用功能寄存器(GPIOx _ AFRH和GPIOx _AFRL).通过这些寄存器可以实现很多功能。下面一个一个来进行说明:
GPIO Configure
2.1 GPIOx_ MODER:端口模式寄存器,这个寄存器主要是配置GPIO口的模式,其中00表示输入;01表示输出;10表示复用功能;11表示模拟功能。其中复用功能与模拟功能的区别一定要弄清楚。
复用功能:指的是除了普通的输出输入,还有其他的功能,如TIM,IIC等。如下图表示红色部分所示。
Alternate
模拟功能:开始以为模拟功能与复用功能是一样的,那是错误的。模拟功能一般是指电压这些模拟信号。如果是配置ADC则需要配置模拟功能。
2.2 GPIOx _ OTYPER :端口输出类型寄存器, 0表示推挽输出(复位状态),1表示开漏输出。从其他博主那里了解到了两者的不同,推挽输出从示波器上看主要是方形波,但是设置成开漏输出的话,示波器上看输出是锯齿波。还有一点如果要设置成开漏的话,需要使PUPDR设置成上拉电阻的状态。因而在选择时要小心。
2.3GPIOx_ OSPEED: GPIO口输出速度寄存器,其中两位为一个配置,x0代表低速,01代表中速,11代表高速。但是这里我不是很清楚低速,中速,高速的速度到底是怎么样的?后来在概括的参考手册中找到了答案。如下图所示。
低速指的是2MHZ; 中速指的是10~25MHZ; 高速指的是20~50MHZ. 其中它们具体的大小与对应连接的电压和电容有关。
GPIO->OSPEED
2.4 GPIOx_ PUPDR: GPIO口上拉/下拉寄存器。其中00表示无上拉和下拉;01表示上拉;10表示下拉;11表示保留。是否要配置上拉或者下拉的看具体的功能。其中在GPIOx_ MODER寄存器选择输入/输出/复用时,均可上拉或者下拉。但是在模拟配置时,则弱上拉和下拉电阻被禁止。
2.5 GPIOx _ IDR: GPIO端口数据输入寄存器,是只读寄存器。主要是接收从外部读取相应位的数据。
2.6 GPIOx _ ODR: GPIO端口数据输出寄存器。这个我们一般不直接配置,因为硬件设计时有些小bug。 所以我们一般是根据下面的GPIOx_ BSRR复位/置位寄存器进行配置。
2.7 GPIOx_ BSRR:GPIO端口复位/置位寄存器。为32位的寄存器,其中低16位主要用来BSy置位相应的 ODRx位,高16位主要是用来BRy复位相应的 ODRx 位。
2.8 GPIOx_LCKR:GPIO端口配置锁存寄存器
2.9 GPIOx _ AFRH和GPIOx _AFRL: 32位替代功能寄存器,其中这两个的用法一般是把AFR[2]表示一个数组。其中的元素AFR[0]地址0x20 表示GPIOx _AFRL寄存器。AFR[1]地址0x24表示GPIOx _AFRH寄存器。对其选择相应的复用功能,主要有:
0000: AF0
0001: AF1
0010: AF2
0011: AF3
0100: AF4 ( 仅限端口 A)
0101: AF5 ( 仅限端口 A)
0110: AF6 ( 仅限端口 A)
0111: AF7 ( 仅限端口 A)
1000: 保留
1001: 保留
1010: 保留
1011: 保留
1100: 保留
1101: 保留
1110: 保留
1111: 保留
要知道AFR功能主要是指的是GPIO的复用功能,但是到底是AF0~AF7的哪个,请见下面图的例子:
AFR
例:把PB3设为硬件复用SPI SCK模式。把PB8设为硬件IIC1 SCL模式。
分析:因为是把相应的GPIO口设为复用功能模式,首先要把GPIOB->MODER模式设为复用模式10. 然后把相应的AF为配置为相应的AF复用功能。比如PB3 是在上面图片中是在GPIOB_AFRL,即数组的AFR[0]元素,且是AF0.参照上面的AF配置是 0000: AF0 。 则设置如下:

// Set PB3 to alternate SPI SCK mode
GPIOB->MODER=(GPIOB->MODER&~(3<<(3*2))) | (2<<(3*2));
GPIOB->AFR[0]=(GPIOB->AFR[0]&~(0xF<<(3*4))) | (0<<(3*4));

PB8设置为IIC1 SCL复用功能,它处于GPIOB_AFRH, 即数组的AFR[1]元素,即是AF1,如上图红色部分所示。参照上面的AF配置是 0001: AF1

// Set PB8 to alternate IIC1 SCL mode
GPIOB->MODER=(GPIOB->MODER&~(3<<(8*2))) | (2<<(8*2));
GPIOB->AFR[1]=(GPIOB->AFR[1]&~(0xF<<(0*4))) | (1<<(0*4));

注:可能会好奇为何后面](0xF<<(0*4))) | (1<<(0*4));均为0而不是为8,这是因为如果以AFR[1]位起始地址的话,第一个地址就是AFRF8[3:0],所以不用进行移位处理。

3.实例演示
例: 如下图 LED连接了PB12, 并且连接了3.3v电压。如果要使LED灯亮的话,图如下,应该怎么做?
GPIOB-LED
目标是使PB12口成为输出口,并且输出低电平,步骤如下:
3.1 首先配置时钟,会在另外一篇博客中配置。
3.2 使能相应的GPIO口,从上得知,因为是PB12,GPIOB寄存器处于AHB2外设里面,则应该使能GPIOB。
RCC->AHBENR|=RCC_AHBENR_GPIOBEN;
3.3 配置GPIOB->MODER的功能模式为输出模式
GPIOB->MODER=(GPIOB->MODER&~(3<<(12 * 2))) | (1 <<(12 * 2));
3.4 因为要输出数据,所以直接复位GPIOB->BSRR的高16位中的12位为1,则输出为0. 则LED灯亮。
GPIOB->BSRR=1<<(16+12);

猜你喜欢

转载自blog.csdn.net/Flylily9997/article/details/70673146