STM32入门:GPIO

1,337 阅读6分钟

STM32命名规则

示例:STM32 F 103 C 8 T 6

  1. 产品系列 STM32=基于ARM的32位微控制器
  2. 产品子系列
  • 101=基本型
  • 102=USB基本型,USB2.0全速设备
  • 103=增强型
  • 105或107=互联型
  1. 引脚数目
  • T=36引脚
  • C=48引脚
  • R=64引脚
  • V=100引脚
  1. 闪存存储器(flash)容量
  • 4=16K字节
  • 6=32K字节
  • 8=64K字节
  • C=256K字节
  • D=384K字节
  • E=512K字节
  1. 封装
  • H=BGA
  • T=LQFP
  • U=VFQFPN
  • Y=WLCSP64
  1. 温度范围
  • 6=工业级温度范围:-40℃~85℃
  • 7=工业级温度范围:-40℃~105℃

GPIO

GPIO工作方式

  1. 四种输入模式
  • 输入浮空(GPIO_Mode_IN_FLOATING):I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。 输入浮空

  • 输入上拉(GPIO_Mode_IPU):I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平。 输入上拉

  • 输入下拉(GPIO_Mode_IPD):I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平。 输入下拉

  • 模拟输入(GPIO_Mode_AIN):I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。 模拟输入

  1. 四种输出模式
  • 开漏输出(GPIO_Mode_Out_OD):通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。 开漏输出
  • 开漏复用(GPIO_Mode_AF_OD):与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。 开漏复用
  • 推挽输出(GPIO_Mode_Out_PP):通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。这里要注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。 推挽输出
  • 推挽复用(GPIO_Mode_AF_PP):与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。 推挽复用
  • 开漏输出与推挽输出区别:开漏输出只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极。适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内);推挽输出可以输出强高、低电平,连接数字器件。
  1. 三种最大翻转速度:2MHZ、10MHZ、50MHZ

GPIO相关配置寄存器

每组GPIO端口的寄存器包括(按组进行配置GPIO):

  • 两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)
  • 两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR)
  • 一个32位位设置/清除寄存器(GPIOx_BSRR)
  • 一个16位复位寄存器(GPIOx_BRR)
  • 一个32位锁定寄存器(GPIOx_LCKR)
  1. GPIOx_CRL,GPIOx_CRH
    每个GPIO需要4bit进行配置,即总共需要4×16=64位,而一个STM32寄存器是32位,故需要两个寄存器配置一组GPIO。其中GPIOx_CRL配置0至7,GPIOx_CRH配置8到15。而对于每个GPIO,4位中低2位配置是输入还是输出,高2位配置具体输入/输出模式。 如低两位中,
  • 00:输入模式(复位后的状态)
  • 01:输出模式,最大速度10MHZ
  • 10:输出模式,最大速度2MHZ
  • 11:输出模式,最大速度50MHZ

高两位中,若为输入模式,

  • 00:模拟输入
  • 01:浮空输入(复位后的状态)
  • 10:上拉/下拉输入(具体由GPIOx_ODR寄存器配置)
  • 11:保留

若为输出模式,

  • 00:推挽输出
  • 01:开漏输出
  • 10:复用推挽输出
  • 11:复用开漏输出
  1. GPIOx_IDR,GPIOx_ODR
  • GPIOx_IDR 位31:16,保留始终为0;位15:0,对应这一组16个GPIO的输入电平。这些位为只读并只能以字(16位)的形式读出;
  • GPIOx_ODR 位31:16,保留始终为0;位15:0,控制这一组16个GPIO的输出电平。设置为0,输出低电平;设置为1,输出为高电平。只能以字(16位)的形式进行操作。
    此外,当此IO口为输入模式时,通过将对应ODR中位设置为0,下拉输入;设置为1,上拉输入。
  1. GPIOx_BSRR,GPIOx_BRR
  • GPIOx_BSRR 位31:16,将某位设置为1,则对应ODR中位为0(位清除);设置为0,则对应ODR中位不受影响。位15:0,将某位设置为1,则对应ODR中位为1(位设置);设置为0,则对应ODR中位不受影响。
  • GPIOx_BRR 与BSRR高16位功能相同(位清除)

GPIO相关库函数

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

位带操作

把每个比特膨胀(映射)为一个32位的字,当访问这些字的时候就达到了访问比特的目的,比如说BSRR寄存器有32个位,那么可以映射到32个地址上,我们去访问(读-改-写)这32个地址就达到访问32个比特的目的。即如果要改写某个寄存器的某一位,通过改写这一位映射的地址即可,调用已封装好的相关函数,如PBout(5)=1;对应于GPIOB->ODR|=1<<5;

相关链接

参考资料

  1. 【STM32】GPIO工作原理(八种工作方式超详细分析,附电路图)
  2. 【正点原子】 手把手教你学STM32单片机教学视频