STM32F407标准库学习笔记-GPIO

本文详细介绍了STM32F407微控制器中GPIO的基本概念、配置方法及常用操作。包括GPIO的枚举类型、结构体定义、初始化函数、读写操作等,并解释了相关寄存器的工作原理。

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

STM32F407标准库学习笔记-GPIO

头文件 gpio.h

  1. 枚举-列举同一寄存器的不同选项
typedef enum
{ 
  GPIO_Low_Speed     = 0x00, /*!< Low speed    */
  GPIO_Medium_Speed  = 0x01, /*!< Medium speed */
  GPIO_Fast_Speed    = 0x02, /*!< Fast speed   */
  GPIO_High_Speed    = 0x03  /*!< High speed   */
}GPIOSpeed_TypeDef;

/* Add legacy definition */
#define  GPIO_Speed_2MHz    GPIO_Low_Speed    
#define  GPIO_Speed_25MHz   GPIO_Medium_Speed 
#define  GPIO_Speed_50MHz   GPIO_Fast_Speed 
#define  GPIO_Speed_100MHz  GPIO_High_Speed
//具体功能可以用宏定义进一步封装  
  1. 枚举-用来体现状态(函数执行、引脚高低、位数据)
typedef enum
{ 
  Bit_RESET = 0,
  Bit_SET
}BitAction;
  1. 结构体-将配置一个引脚所需描述的信息进行封装
typedef struct
{
  uint32_t GPIO_Pin;              
                                       
  GPIOMode_TypeDef GPIO_Mode;    

  GPIOSpeed_TypeDef GPIO_Speed;   

  GPIOOType_TypeDef GPIO_OType;   

  GPIOPuPd_TypeDef GPIO_PuPd;  
     
}GPIO_InitTypeDef;
  1. 宏定义-对引脚在寄存器中对应的位数进行封装
#define GPIO_Pin_0                 ((uint16_t)0x0001)  
#define GPIO_Pin_1                 ((uint16_t)0x0002)  
#define GPIO_Pin_2                 ((uint16_t)0x0004)  
#define GPIO_Pin_3                 ((uint16_t)0x0008)  
#define GPIO_Pin_4                 ((uint16_t)0x0010)  
#define GPIO_PIN_MASK              ((uint32_t)0x0000FFFF) /* PIN mask for assert test */
  1. 宏定义-对引脚的复用功能进行封装
//@brief   AF 0 selection  
#define GPIO_AF_RTC_50Hz      ((uint8_t)0x00)  /* RTC_50Hz Alternate Function mapping */
#define GPIO_AF_MCO           ((uint8_t)0x00)  /* MCO (MCO1 and MCO2) Alternate Function mapping */
#define GPIO_AF_TAMPER        ((uint8_t)0x00)  /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */
#define GPIO_AF_SWJ           ((uint8_t)0x00)  /* SWJ (SWD and JTAG) Alternate Function mapping */
#define GPIO_AF_TRACE         ((uint8_t)0x00)  /* TRACE Alternate Function mapping */
  1. 声明GPIO相关函数
void GPIO_DeInit(GPIO_TypeDef* GPIOx);

C文件 gpio.c

1.初始化与配置段

void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
  if (GPIOx == GPIOA)
  {
    RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE);
  }
  else if (GPIOx == GPIOB)
gpio复位函数
借用RCC中的外设复位功能直接对相关引脚组(模块)全盘复位;
传入引脚组名,借助引脚组宏定义对应的地址进行判断;
先使能复位,后失能复位。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
  uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
  /* ------------------------- Configure the port pins ---------------- */
  /*-- GPIO Mode Configuration --*/
  for (pinpos = 0x00; pinpos < 0x10; pinpos++)
  {
    pos = ((uint32_t)0x01) << pinpos;
    /* Get the port pins position */
    currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
    if (currentpin == pos)
    {
      GPIOx->MODER  &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
      GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
      if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF))
    }
  }
}
gpio初始化函数
传入引脚组名、引脚初始化结构体;
pinpos代表引脚标号,使pos的1左移到对应的bit位;
利用for循环和&处理GPIO_Pin和pos,寻找选定的引脚;
根据引脚组名和结构体,对寄存器赋值;先复位,后置位。
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
{
  /* Reset GPIO init structure parameters values */
  GPIO_InitStruct->GPIO_Pin  = GPIO_Pin_All;
  GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
gpio初始化结构体复位
与硬件寄存器无关,只是修改引脚初始化结构体里的值
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  __IO uint32_t tmp = 0x00010000;
  
  tmp |= GPIO_Pin;
  /* Set LCKK bit */
  GPIOx->LCKR = tmp;
  /* Reset LCKK bit */
  GPIOx->LCKR =  GPIO_Pin;
  /* Set LCKK bit */
  GPIOx->LCKR = tmp;
  /* Read LCKK bit*/
  tmp = GPIOx->LCKR;
  /* Read LCKK bit*/
  tmp = GPIOx->LCKR;
}
锁定引脚配置函数
tmp初始值和函数内部的流程与锁定引脚的读写寄存器有关;
最后要读两次完成锁定,第二次的LCKK位的值可信,用来确认锁定。

2.读与写

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  uint8_t bitstatus = 0x00;
  
 if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
  {
    bitstatus = (uint8_t)Bit_SET;
读取特定引脚输入值
将 输入数据寄存器 与 引脚在寄存器中的对应位 的 1 相于,取出特定位的值;
函数有返回值,uint8类型。
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
  return ((uint16_t)GPIOx->IDR);
}
读取特定引脚组输入值
直接返回一组IDR。
uint8_t  GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
读取输入数据
同上。
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
   GPIOx->BSRRL = GPIO_Pin;
}
特定引脚输出1
向BSRR低16位的特定位写1,影响引脚输出。
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  GPIOx->BSRRH = GPIO_Pin;
}
特定引脚输出0
向BSRR高16位的特定位写1,影响引脚输出。
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
{
  if (BitVal != Bit_RESET)
  {
    GPIOx->BSRRL = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRRH = GPIO_Pin ;
  }
}
将以上两个函数使用if和头文件中的bit状态枚举变量进行结合。
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  GPIOx->ODR ^= GPIO_Pin;
}
输出翻转
对一组输出数据寄存器中的值进行按位取反。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值