GPIO简介
GPIO**—general purpose input output,**是通用输入输出端口的简称,简单来说就是软件可控制的引脚,STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。
STM32 芯片的GPIO被分成很多组,每组有16 个引脚,如型号为STM32F103VET6 型号的芯片有GPIOA、GPIOB、 GPIOC 至GPIOE 共5 组GPIO。芯片一共100 个引脚,其中GPIO 就占了一大部分,所有的GPIO 引脚都有基本的输入输出功能。
最基本的输出功能是由STM32 控制引脚输出高、低电平,实现开关控制,如把GPIO 引脚接入到LED 灯,那就可以控制LED 灯的亮灭,引脚接入到继电器或三极管,那就可以通过继电器或 三极管控制外部大功率电路的通断。
最基本的输入功能是检测外部输入电平,如把GPIO 引脚连接到按键,通过电平高低区分按键是否被按下。
点亮LED
以点亮绿灯为例
图中从3 个LED 灯的阳极引出连接到3.3V 电源,阴极各经过1 个限流电阻引入至STM32 的3 个 GPIO 引脚中,所以我们只要控制这三个引脚输出高低电平,即可控制其所连接LED 灯的亮灭。
将GPIO配置成输出模式
首先我们把连接到LED 灯的GPIO 引脚PB0 配置成输出模式,即配置GPIO 的端口配置低寄存器CRL。CRL 中包含0-7 号引脚,每个引脚占用4 个寄存器位。MODE 位用来配置输出的速度,CNF 位用来配置各种输入输出模式。
在代码中,我们先把控制PB0的端口位,即CRL的最后4位清0,然后再向它赋值“0001 b”,从而使GPIOB0 引脚设置成输出模式,速度为10M.
在《1-STM32F10x-中文参考手册文档》 2.3 存储器映像 中可以找到GPIOB的地址范围
另外,CRL寄存器的地址偏移为0x00,所以CRL寄存器的地址就是 0x40010C00
//清空控制PB0的端口位
*(unsigned int *)0x40010C00 &= ~(0x0F<<(4*0));
//配置 PB0为通用推挽输出,速度为 10M
*(unsigned int *)0x40010C00 |= (1<<(4*0));
有关C语言的位操作,可以参考另外一篇笔记
C语言位操作
输出低电平
将PB0设置成输出模式以后,我们还需要让PB0输出低电平。我们可以直接控制GPIOB的ODR寄存器来控制每一位输出的数据。GPIOB有16个引脚,每一个引脚的输出就分别对应ODR寄存器的低16位的每一位。
我们把ODR寄存器的最后一位设置为0即可让PB0输出低电平。
ODR寄存器的地址偏移为0x0C
*(unsigned int *)0x40010C0C &=~(1<<0);
启动时钟
由于STM32的外设很多,为了降低功耗,每个外设都对应着一个时钟,在芯片刚上电的时候这些时钟都是被关闭的,如果想要外设工作,必须把相应的时钟打开。STM32 的所有外设的时钟由一个专门的外设来管理,叫RCC(reset and clockcontrol)。
由系统框图可知,
所有的GPIO 都挂载到APB2总线上,具体的时钟由APB2 外设时钟使能寄存器(RCC_ APB2ENR) 来控制。
RCC_APB2ENR的地址是0x40021018
*(unsigned int *)0x40021018 |=(1<<3);
完整程序
#include "stm32f10x.h"
int main(void)
{
// 使能时钟
*(unsigned int *)0x40021018 |=(1<<3);
//清空控制PB0的端口位
*(unsigned int *)0x40010C00 &= ~(0x0F<<(4*0));
//配置 PB0为通用推挽输出,速度为 10M
*(unsigned int *)0x40010C00 |= (1<<4*0);
//PB0输出低电平
*(unsigned int *)0x40010C0C &=~(1<<0);
}
void SystemInit(void)
{
}
Build之后下载程序,会发现绿灯已点亮。