stm32寄存器笔记

  参考资料: GPIO相关介绍

        STM32 GPIO的配置寄存器(CRL、CRH)快速学习

 

  stm32的寄存器都是32位的。

  每个GPIO口有7个寄存器来控制。从GPIO的 GPIO_TypeDef 定义中可以看出,分别是:CRL,CRH,IDR,ODR,BSRR,LCKR。

 

复制代码
/** 
  * @brief General Purpose I/O
  */

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;
复制代码

 

 

配置寄存器:CRL, CRH

 

  对于一组GPIO,工作模式配置用2个32位的寄存器实现(16个IO口每个分到4位)。第一个32位寄存器CRL(端口配置低寄存器)对应0到7的GPIO,第二个32位寄存器CRH(端口配置高寄存器)则对应着8到15.

  从手册出看出来,以低寄存器为例,每个IO口有4位寄存器,分别是两位的MODEx和两位CNFx,其中MODE是用来配置输出/输入以及最大速度的,而CNF用来配置具体的输入输出模式的,例如推挽输出之类。

        

     

 

 

 

 

输入数据寄存器:IDR

   IDR是端口输入数据寄存器,也是一个只读寄存器。它有32位,但是只用了16位。在库函数 GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 中,可以看见对于IDR的使用实例,在 GPIO_ReadInputData(GPIO_TypeDef* GPIOx) 中也有。前者是返回单个GPIO的状态,后者是直接返回一组GPIO的IDR(即返回一个16位数):

复制代码
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  uint8_t bitstatus = 0x00;
  
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); 
  
  if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
  {
    bitstatus = (uint8_t)Bit_SET;
  }
  else
  {
    bitstatus = (uint8_t)Bit_RESET;
  }
  return bitstatus;
}
复制代码

 

输出数据寄存器:ODR

  类似IDR,ODR也只用了16位。但是这是一个可读写寄存器。向其中写数据可以控制IO口的输出电平,读其中的数据可以得到IO口的电平状态。

 

    

 

 

 

  例如,点灯实验中,我们在采用按键控制LED灯的亮灭时,可以使用ODR与位运算异或操作来直接实现状态改变,不需要再判断当前状态了:

 

GPIOA->ODR^=GPIO_Pin_5;

 

 

置位/复位寄存器:BSRR  

  这也是一个可以设置GPIO口输出为1或0的寄存器。不过和ODR不同的是,在写入BSRR时,只有二进制1起作用,0没有作用。若用0到15位来写,有1的位置被设为高电平;若用16到31位来写,有1的位置被设为低电平,即被清楚为0。同时,如果一个位置同时被设了高低电平,那么就是被设为高电平。

   

 

posted @   wegret  阅读(680)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示