STM32F103寄存器配置相关学习 —— GPIO

本文详细介绍了STM32F103的GPIO寄存器,包括配置寄存器(CRL、CRH)、数据寄存器(IDR、ODR)、位设置/清除寄存器(BSRR)、锁定寄存器(LCKR)和位清除寄存器(BRR)。阐述了各个寄存器的功能和操作方法,如配置GPIO模式、数据读写及位操作。此外,还讲解了GPIO口的四种输入模式和四种输出模式,以及C语言位操作在GPIO配置中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  
  
  

1. GPIO相关寄存器

  对于每个GPI/O端口的寄存器:(32位)

  • 配置寄存器:GPIOx_CRLGPIOx_CRH
  • 数据寄存器:GPIOx_IDRGPIOx_ODR
  • 位设置/清除寄存器:GPIOx_BSRR
  • 锁定寄存器:GPIOx_LCKR
  • 位清除寄存器:GPIOx_BRR

  GPIO端口的每个位可以由软件分别配置成多种模式,I/0端口寄存器必须按32位字被访问(不允许半字或字节访问,如下文提到16位访问,是因为编译环境会自动补齐到32位),关于几种模式在后文介绍

1.1 配置寄存器(CRL、CRH)

  2个32位的配置寄存器分别为配置低寄存器(GPIOx_CRL)配置高寄存器(GPIOx_CRH)

① 端口配置低寄存器(GPIOx_CRL) (x=A…E)

  结合下图来说明,低位寄存器是用来配置GPIO0到GPIO7的,A~E共5组GPIO,相对应的可以知道高位寄存器则用来配置A ~ E组寄存器的GPIO8到GPIO15;可以发现,每一个GPIO引脚由4个比特位控制,其中第2位是MODE,用来配置该GPIO是输入还是输出模式,如果是输出,对应引脚输出的最大速度;其中的高2位是CNF,用来配置引脚输入/输出时的具体功能模式,不同应用需求对应不同的模式设置(后文解释)

② 端口配置高寄存器(GPIOx_CRH) (x=A…E)

  同上面的低位配置寄存器一样,只不过高位配置寄存器是用来配置GPIO8~GPIO15的;要知道,一般配置一个GPIO的输入输出模式时,先配置MODE,确定引脚是用来输入还是输出,其次再配置CNF来设置具体的工作模式

1.2 数据寄存器(IDR、ODR)

  2个32位的数据寄存器分别是输入数据寄存器(GPIOx_IDR)输出数据寄存器(GPIOx_ODR)

① 输入数据寄存器(GPIOx_IDR) (x=A…E)

1、输入数据寄存器是32位的,但是只用到0~15位,分别对应一组GPIO的16个引脚,仅可读;
2、0~15位组成一“字”,名为IDR,读的时候只能以字的形式读取,即一次读取16位的比特位;

② 输出数据寄存器(GPIOx_ODR) (x=A…E)
1、输出数据寄存器也是32位,只用到0~15位,分别对应一组GPIO的16个引脚,可读写;
2、读写寄存器时也只能以字的形式操作

1.3 位设置/清除寄存器(BSRR)

  这是一个32位的寄存器,低16位(BS)用来设置端口的位,高16位(BR)则是用来清除端口的位;两者均仅可写,写操作时需以字的形式写入
  如对于置位GPIO15时,令BS15为1表示置位,此时BR15就不能设为1了,如果BS为1时BR也为1,则默认BS生效

1.4 锁定寄存器(LCKR)

  锁定寄存器(GPIOx_LCKR) (x=A…E)是一个32位的寄存器,当设置了位16(LCKK)时,则会锁定端口位的配置,位[15:0]对应的GPIO的16个引脚,当对相应的端口位执行了LOCK后,在下次系统复位之前将不能再更改端口位的配置
  每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位,需要注意锁键的输入序列,顺序不要搞错,并且位[15:0]只能在LCKK为0时才可写

1.5 位清除寄存器(BRR)

  位清除寄存器(GPIOx_BRR) (x=A…E) 的高16位保留,不使用;低16位以字的形式进行写入,写入1时才会对位有影响

  
  

2. ODR, BSRR, BRR控制位的区别

  • 三者均为32位寄存器,均可写,需以字形式写
  • ODR[0,15]对应位写1,输出高电平,0对应低电平
  • BSRR[16,31]对应位写1输出低电平,0无效
    BSRR[0,15]对应位写1输出高电平,0无效
  • BRR[0,15]对应位写1输出低电平,写0无效(仅低电平)

1、BRR和BSRR的最显著用处就是可以只改变某一个或某几个针脚的值而不改变其他(因为0无效)
2、ODR改变时则是改变全部位的状态(仅可以字形式写)

//对于ODR操作GPIO的伪代码如下:
disable_irq() //关闭中断
save_gpio_pin_sate = read_gpio_pin_state();
save_gpio_pin_sate = xxxx;
chang_gpio_pin_state(save_gpio_pin_sate);
enable_irq();

  可见当控制GPIO的状态时最好不要使用ODR,关闭中断明显会延迟或丢失一事件的捕获

3、BSRR的高16位和BRR的低16位具有相同功能,举例:

对GPIOE的16个IO,改变低8位的数据而保持高8位不变
① GPIOE->BSRR = (0x34) & 0xff;  //操作BSRR[0,15]
② GPIOE->BRR = ~(0x34) & 0xff;
  
一次完成对8位的操作:
GPIOE->BSRR = ((0x34) & 0xff) | ( (~(0x34) & 0xff)<<16 );
  
一次完成对16位的操作:
GPIOE->BSRR = ((0x34)& 0xffff) | ( (~(0x34))<<16 );
  
BSRR的高16位并非是多余的,对GPIOE的位7置’1’,位6置’0’:
GPIOE->BSRR = 0x400080;
  
不使用BSRR高16位,要分2次操作,造成位7和位6的变化不同步
GPIOE->BSRR = 0x80;
GPIOE->BRR = 0x40;

4、有些IO时序要求非常严格,同时对一个GPIO置1和对另一个GPIO清0是很必要的

5、BSRR还有一个特点,就是Set比Reset的级别高

  
  

3. GPIO口的几种模式总结

3.1 常见名词解释

内置外设:如串口、ADC、DCA等等(属于stm32内部功能模块)

端口复用:当一个GPIO作为内置外设的功能引脚时,称为复用。比如说,STM32的串口1的引脚对应的I/O位PA9、PA10。而PA9、PA10默认的功能都是GPIO,所以说当PA9、PA10引脚作为串口1使用的时候就是端口复用

端口重映射:把引脚的内置外设功能映射到其他的引脚上,但不是可以随便映射的,需要参照数据手册

推挽结构:两个参数相同的三极管或MOS管分别受两互补信号的控制,总是在一个三极管或MOS管导通的时候另一个截止。高低电平由输出电平决定。有推有拉,任何时候IO口的电平都是确定的,不需要外接上拉或者下拉电阻

开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极。适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内);

GPIO内部电路结构

FT:代表GPIO口兼容3.3V和5V

保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入

P-MOS、N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式

TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号

GPIO支持4种输入模式,三种最大翻转速度(2MHz、10MHz、50MHz)

  

3.2 四种输入模式

① 浮空输入(GPIO_Mode_IN_FLOATING)
  逻辑器件与引脚即不接高电平,也不接低电平,相当于浮在空中呈高阻态,上面用绳子一拉就上去了,下面用绳子一拉就沉下去了,一般用来做ADC输入用,这样可以减少上下拉电阻对结果的影响

② 输入上拉(GPIO_Mode_IPU)
  上拉就是通过上拉电阻把电位拉高,比如拉到Vcc,将输入的不确定的信号嵌位在高电平

③ 输入下拉(GPIO_Mode_IPD)
  下拉就是把电压拉低,拉到GND,下拉电阻另一端接地即可,原理与上拉的一样

④ 模拟输入(GPIO_Mode_AIN)
  模拟输入是指0,1的二进制数字信号,通过数模转换,转换成模拟信号,模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号&

### STM32F103 GPIO 寄存器配置教程 STM32F103GPIO 配置主要涉及几个关键寄存器:`CRL` `CRH`(用于配置模式)、`ODR`(输出数据寄存器)、`IDR`(输入数据寄存器)以及 `BSRR`(位设置/重置寄存器)。以下是关于这些寄存器及其工作模式的详细介绍。 #### 1. CRL CRH 寄存器 这两个寄存器分别用来配置 GPIO 引脚的工作模式。其中: - **CRL** 控制 GPIO0 到 GPIO7 的模式。 - **CRH** 控制 GPIO8 到 GPIO15 的模式。 每两个比特表示一个引脚的模式,分为两部分: - **Mode**: 定义引脚的速度方向(输入或输出)。 - **CNF**: 进一步细化具体的输入或输出行为。 例如,在 PA0 配置为通用推挽输出模式、最大速度 10 MHz 的情况下,可以通过以下方式实现: ```c GPIOA->CRL &= ~(0x0F << (0 * 4)); // 清零 PA0 的配置 GPIOA->CRL |= (0x01 << (0 * 4)); // 设置 PA0 为通用推挽输出模式、最大速度 10 MHz ``` 这里的 `(0x01 << (0 * 4))` 表示将 Mode 设为 Output at 10 MHz 并 CNF 设为 Push-Pull 输出[^1]。 #### 2. ODR 寄存器寄存器用于设置或读取某个 IO 口的输出电平。仅当引脚处于输出模式时有效。其前 16 位对应各个 I/O 口的状态,后 16 位保留并始终为 0。 例如,要将 PA0 设置为高电平: ```c GPIOA->ODR |= GPIO_ODR_ODR0; // 或者直接写成 GPIOA->ODR |= 0x01; ``` 如果需要检查当前 PA0 是否为高电平,则可通过如下代码完成: ```c if (GPIOA->ODR & GPIO_ODR_ODR0) { // PA0 是高电平 } else { // PA0 是低电平 } ``` 此操作依赖于之前已正确配置好 PA0 的模式[^4]。 #### 3. IDR 寄存器 与 ODR 不同的是,IDR 提供了实际检测到的外部信号状态。无论引脚是否被设定为输入模式,都可以通过它获取实时电压水平。 假设我们想了解 PA0 当前的实际物理连接情况: ```c uint32_t pinState = GPIOA->IDR & GPIO_IDR_IDR0; if (pinState != 0) { // 输入端检测到了逻辑 '1' } else { // 输入端检测到了逻辑 '0' } ``` 这适用于任何类型的输入配置,比如浮空输入、上拉或下拉电阻等情形下的监测需求[^1]。 #### 4. BSRR 寄存器 为了简化程序设计流程,STM32 提供了一个特殊的寄存器——Bit Set/Reset Register (`BSRR`) 来单独处理每一位的高低切换而无需额外考虑其他位的影响。 例如,利用 BSRR 将 PA0 置为高电平可以直接这样编写: ```c GPIOA->BSRR = GPIO_BSRR_BR0_Set; // 使用宏定义更清晰易懂 // 或者简单地写作 GPIOA->BSRR = 0x0001; ``` 同样地,若需将其拉回到低电平则只需改变目标位置即可: ```c GPIOA->BSRR = GPIO_BSRR_BR0_Reset; // 对应复位动作 // 或者直接赋值为 0x0001 << 16; ``` 这种方法避免了多次访问同一内存单元所带来的潜在竞争条件问题[^4]。 --- ### 总结 以上介绍了 STM32F103GPIO 寄存器的主要组成部分及其用途,并给出了相应的实例说明如何针对不同场景灵活运用它们来满足特定的应用需求。无论是简单的 LED 控制还是复杂的通信接口搭建,掌握这些基础知识都是不可或缺的第一步。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值