GPIO简介

GPIO**—general purpose input output,**是通用输入输出端口的简称,简单来说就是软件可控制的引脚,STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。
STM32 芯片的GPIO被分成很多组,每组有16 个引脚,如型号为STM32F103VET6 型号的芯片有GPIOA、GPIOB、 GPIOC 至GPIOE 共5 组GPIO。芯片一共100 个引脚,其中GPIO 就占了一大部分,所有的GPIO 引脚都有基本的输入输出功能。
image.png
最基本的输出功能是由STM32 控制引脚输出高、低电平,实现开关控制,如把GPIO 引脚接入到LED 灯,那就可以控制LED 灯的亮灭,引脚接入到继电器或三极管,那就可以通过继电器或 三极管控制外部大功率电路的通断。
最基本的输入功能是检测外部输入电平,如把GPIO 引脚连接到按键,通过电平高低区分按键是否被按下。

(未完待续)

点亮LED

image.png
以点亮绿灯为例
图中从3 个LED 灯的阳极引出连接到3.3V 电源,阴极各经过1 个限流电阻引入至STM32 的3 个 GPIO 引脚中,所以我们只要控制这三个引脚输出高低电平,即可控制其所连接LED 灯的亮灭。

将GPIO配置成输出模式

首先我们把连接到LED 灯的GPIO 引脚PB0 配置成输出模式,即配置GPIO 的端口配置低寄存器CRL。CRL 中包含0-7 号引脚,每个引脚占用4 个寄存器位。MODE 位用来配置输出的速度,CNF 位用来配置各种输入输出模式。
image.png
在代码中,我们先把控制PB0的端口位,即CRL的最后4位清0,然后再向它赋值“0001 b”,从而使GPIOB0 引脚设置成输出模式,速度为10M.
在《1-STM32F10x-中文参考手册文档》 2.3 存储器映像 中可以找到GPIOB的地址范围
image.png
另外,CRL寄存器的地址偏移为0x00,所以CRL寄存器的地址就是 0x40010C00

  1. //清空控制PB0的端口位
  2. *(unsigned int *)0x40010C00 &= ~(0x0F<<(4*0));
  3. //配置 PB0为通用推挽输出,速度为 10M
  4. *(unsigned int *)0x40010C00 |= (1<<(4*0));

有关C语言的位操作,可以参考另外一篇笔记
C语言位操作


输出低电平

将PB0设置成输出模式以后,我们还需要让PB0输出低电平。我们可以直接控制GPIOB的ODR寄存器来控制每一位输出的数据。GPIOB有16个引脚,每一个引脚的输出就分别对应ODR寄存器的低16位的每一位。
image.png
image.png
我们把ODR寄存器的最后一位设置为0即可让PB0输出低电平。
ODR寄存器的地址偏移为0x0C

  1. *(unsigned int *)0x40010C0C &=~(1<<0);

启动时钟

由于STM32的外设很多,为了降低功耗,每个外设都对应着一个时钟,在芯片刚上电的时候这些时钟都是被关闭的,如果想要外设工作,必须把相应的时钟打开。STM32 的所有外设的时钟由一个专门的外设来管理,叫RCC(reset and clockcontrol)
由系统框图可知,
image.png

所有的GPIO 都挂载到APB2总线上,具体的时钟由APB2 外设时钟使能寄存器(RCC_ APB2ENR) 来控制。
image.png
image.png
RCC_APB2ENR的地址是0x40021018

  1. *(unsigned int *)0x40021018 |=(1<<3);

完整程序

  1. #include "stm32f10x.h"
  2. int main(void)
  3. {
  4. // 使能时钟
  5. *(unsigned int *)0x40021018 |=(1<<3);
  6. //清空控制PB0的端口位
  7. *(unsigned int *)0x40010C00 &= ~(0x0F<<(4*0));
  8. //配置 PB0为通用推挽输出,速度为 10M
  9. *(unsigned int *)0x40010C00 |= (1<<4*0);
  10. //PB0输出低电平
  11. *(unsigned int *)0x40010C0C &=~(1<<0);
  12. }
  13. void SystemInit(void)
  14. {
  15. }

Build之后下载程序,会发现绿灯已点亮。

宏定义