STM32的GPIO处理

以STM32F103VET6点亮LED为例简单记录一下STM32的GPIO如何控制。

GPIO控制原理

片上外设挂载有三条总线,APB1、APB2、AHB。GPIO挂载在APB2总线上。共有七组GPIO(端口),每个GPIO有16个引脚(位)。

GPIO的行为通过7个寄存器来控制,每个寄存器为32bit。

七个寄存器分别为CRL(低八位的控制寄存器)、CRH(高八位的控制寄存器)、IDR(输入数据寄存器)、ODR(输出数据寄存器)、BSRR(端口位设置/清除寄存器)、BRR、LCKR。

CRH和CRL:每四位为一组控制一位的IO。其中低两位控制运行模式(输入、2MHz输出、10MHz输出、50MHz输出),高两位控制IO配置(输入:模拟、浮空、上/下拉。输出:推挽、开漏)。使用宏定义的工作模式时,每一个宏使用8bit数字表示,实际写入的时候写入的是bit[3:2]。

BSRR(端口位设置/清除寄存器):低16位触发时表示ODR对应位置1,高16位触发时表示ODR对应位置0。

BRR(端口位清除寄存器):低16位触发时表示ODR对应的位置0。

ODR(输出数据寄存器):对应的位置0或置1表示对应引脚高低电平。

IDR(输入数据寄存器):使用上下拉输入的时候保存输入引脚的值0或1。

需要注意的是,GPIO使用前要进行时钟的使能,此时使用RCC_APB2ENR寄存器激活APB2总线上的对应外设。其中bits[8:2]表示七个GPIO。

使用寄存器操作

开启GPIOB的0号引脚

// 开启GPIOB的时钟
RCC_APB2ENR |= (1 << 3);
// GPIOB的0号引脚控制位全部置0
GPIOB_CRL &= ~(0x0F << (4*0));
// GPIOB的0号引脚设置为10MHz推挽输出
GPIOB_CRL |= (1 << (4*0));
// GPIOB的0号引脚拉低
GPIOB_ODR |= (0 << 0);

使用标准库操作

使用标准库开启时钟并设置引脚

// 初始化结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 开启时钟
RCC_ARB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 设置引脚和工作模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// 写入工作模式
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 引脚置位
GPIO_SetBits(GPIOB, GPIO_Pin_0);
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
// 或者使用BSRR、BRR、ODR设置
GPIOB->BSRR |= 0x01;
GPIOB->BRR |= 0x01;
GPIOB->ODR |= 0x01;
Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.