参考江科大32单片机学习相关知识
GPIO基本构造
APB2(Advanced Peripheral Bus 2)是STM32微控制器架构中的一个外设总线,用于连接一些高性能外设,如定时器、USART、ADC和GPIO等。这些外设通常对性能要求较高,需要更快的数据传输速率。相较于APB1,总线频率更高,适合用于需要快速响应的外设。
寄存器高16位用不到,只用低16位
1. 输入模式和输出模式
-
浮动输入:不连接任何电阻,GPIO口在未施加电压时处于不确定状态。适合不需要上拉或下拉的场景。
-
上拉输入:通过内部电阻将GPIO引脚拉高。当外部信号接地时,GPIO读取为低电平;未接地时读取为高电平。
-
下拉输入:通过内部电阻将GPIO引脚拉低。当外部信号接到高电压时,GPIO读取为高电平;未接高电压时读取为低电平。
FT(five tolerance)输入容忍5V -
模拟输入:GPIO无效,引脚直接接内部ADC
-
推挽输出:能在高低电平之间切换,并提供较大的电流驱动能力。适合驱动LED和其他负载。又被称为强推输出模式
-
开漏输出:只能在低电平时驱动外部设备,而高电平需要外部拉高。适合多路复用或总线系统中的信号线。如I2C
-
复用开漏输出:在开漏输出模式下,GPIO引脚能够通过内部开关连接到地(GND),但不能主动驱动高电平。高电平状态需要外部上拉电阻来实现。当GPIO引脚被设置为低电平时,开关闭合,信号被拉低。当引脚被设置为高电平时,开关断开,信号线处于高阻抗状态,此时需要外部上拉电阻将信号拉高,注意,此时没有驱动能力。
-
复用推挽输出:在推挽输出模式下,GPIO引脚能够同时驱动高电平和低电平。它通过两个开关(一个连接到电源,一个连接到地)实现输出。工作原理:当GPIO引脚被设置为高电平时,连接到电源的开关闭合,信号被拉高。当引脚被设置为低电平时,连接到地的开关闭合,信号被拉低。
3. 配置方法
在STM32中,配置输入输出模式通常通过设置MODER
寄存器实现。每两个比特位表示一个引脚的模式。
在STM32微控制器中,GPIO口的寄存器用于配置和控制引脚的行为。每个GPIO端口都有一组特定的寄存器,主要包括以下几类:
1. MODER(模式寄存器)
- 功能:配置每个GPIO引脚的工作模式。
- 位域:每两个比特位对应一个引脚的模式设置。
00
: 输入模式01
: 输出模式10
: 复用模式11
: 模拟模式
2. OTYPER(输出类型寄存器)
- 功能:设置引脚的输出类型。
- 位域:
0
: 推挽输出1
: 开漏输出
3. OSPEEDR(输出速度寄存器)
- 功能:配置引脚的输出速度。
- 位域:每两个比特位对应一个引脚的速度设置。
00
: 低速01
: 中速10
: 高速11
: 极高速
4. PUPDR(上拉下拉寄存器)
- 功能:配置引脚的上拉或下拉电阻。
- 位域:
00
: 无上拉/下拉01
: 上拉10
: 下拉11
: 保持不变
5. IDR(输入数据寄存器)
- 功能:读取引脚的输入状态。
- 位域:每个位对应一个引脚的输入状态,
1
表示高电平,0
表示低电平。
6. ODR(输出数据寄存器)
- 功能:控制输出引脚的电平。
- 位域:每个位对应一个引脚的输出状态,设置为
1
则输出高电平,0
则输出低电平。
7. BSRR(位设定/重置寄存器)
- 功能:快速设置或重置引脚的输出状态。
- 位域:高16位用于设置引脚为高电平,低16位用于设置引脚为低电平。
8. LCKR(锁定寄存器)
- 功能:锁定GPIO引脚的配置,防止在运行时被意外修改。
- 操作:通过写入特定序列来锁定或解锁引脚配置。
9. AFR(替代功能寄存器)
- 功能:配置引脚的替代功能(复用功能)。
- 位域:每个引脚的复用功能由4位表示,可以选择多种外设功能(如UART、SPI等)。
10. 注意事项
- 时钟使能:在配置GPIO寄存器之前,需确保对应GPIO端口的时钟已使能。
- 寄存器操作:直接操作寄存器时,应注意位域的清除与设置,以避免影响其他引脚配置。
- 复用设置:在复用模式下,需要仔细设置替代功能寄存器,确保外设能够正常工作。
LED
以下是GPIO输入模式的简单示例,假设连接一个按钮:
#include "stm32f10x.h" // Device header
#include "Delay.h"int main(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟,使用各个外设前必须开启时钟,否则对外设的操作无效。APB2PeriphClockCmd:这个函数用于使能或禁用 APB2 外设的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO模式,赋值为推挽输出模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO引脚,赋值为第0号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度,赋值为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOA的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){/*设置PA0引脚的高低电平,实现LED闪烁,下面展示3种方法*//*方法1:GPIO_ResetBits设置低电平,GPIO_SetBits设置高电平*/GPIO_ResetBits(GPIOA, GPIO_Pin_0); //将PA0引脚设置为低电平Delay_ms(500); //延时500msGPIO_SetBits(GPIOA, GPIO_Pin_0); //将PA0引脚设置为高电平Delay_ms(500); //延时500ms/*方法2:GPIO_WriteBit设置低/高电平,由Bit_RESET/Bit_SET指定*/GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); //将PA0引脚设置为低电平Delay_ms(500); //延时500msGPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); //将PA0引脚设置为高电平Delay_ms(500); //延时500ms/*方法3:GPIO_WriteBit设置低/高电平,由数据0/1指定,数据需要强转为BitAction类型*/GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0); //将PA0引脚设置为低电平Delay_ms(500); //延时500msGPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1); //将PA0引脚设置为高电平Delay_ms(500); //延时500ms}
}
1.RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
是一行用于开启 STM32 微控制器中 GPIOA 时钟的代码。RCC:时钟控制器(Reset and Clock Control),负责管理系统中的时钟和复位。
APB2PeriphClockCmd:这个函数用于使能或禁用 APB2 外设的时钟。APB2 是高级外设总线,用于连接某些外设(如 GPIO、USART 等)
2. GPIO_InitTypeDef
GPIO_InitTypeDef GPIO_InitStructure;
是一行用于定义一个结构体变量的代码,这个结构体用于配置 GPIO 引脚的参数。这个结构体包含多个字段,用于设置 GPIO 的工作模式、引脚、速度等参数。
如
- GPIO_Pin:用于指定要配置的 GPIO 引脚。例如,
GPIO_Pin_0
表示第 0 号引脚(PA0)。 - GPIO_Mode:用于设置 GPIO 的工作模式,比如输入、输出、复用或模拟模式。
- GPIO_Speed:用于配置引脚的速度,比如 2 MHz、50 MHz 或 100 MHz。
- GPIO_OType:设置引脚的输出类型,可以选择推挽输出或开漏输出。
- GPIO_PuPd:配置引脚的上拉/下拉电阻,选择上拉、下拉或无上拉/下拉。
3.GPIO_Init(GPIOA, &GPIO_InitStructure);
函数:GPIO_Init 是 STM32 标准外设库中提供的函数,用于根据指定的参数配置 GPIO 引脚。这个函数会根据传入的结构体变量设置相应的寄存器。
4.GPIO设置
- void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//功能:将指定的 GPIOx 引脚GPIO_Pin设置为高电平
- void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//功能:将指定的 GPIOx 引脚GPIO_Pin设置为低电平
- void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//根据给定的值BitVal(要写入的值,使用 Bit_SET 或 Bit_RESET)设置指定的 GPIO 引脚GPIO_Pin。。
- void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//将一个 16 位的值写入指定的 GPIOx端口的所有引脚。值的每一位对应 GPIO 端口的每一个引脚,1 表示高电平,0 表示低电平。
LED闪烁
闪烁还是挺简单的,江科大连延时函数也不讲,直接调用,还是非常容易的思路。