stm32寄存器笔记

发布时间 2023-04-02 17:28:56作者: wegret

  参考资料: 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的使用实例:

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。同时,如果一个位置同时被设了高低电平,那么就是被设为高电平。