STM32F103RCT6学习之 -- GPIO

1、GPIO 常用的几个寄存器

GPIO可以简单理解为芯片的引脚,芯片有多少个引脚,就有多少个GPIO 口(简单理解),然后每个脚用来干嘛的,就要看手册,看资料了。

1.1 GPIOx_CRL(x=A…E) 配置某组GPIO口中低 8个引脚,例如GPIOC_5, 就是C组里面的第5个引脚

1.2 GPIOx_CRH (x=A…E) 配置某组GPIO口中高 8个引脚,例如GPIOC_12, 就是C组里面的第12个引脚

1.3 GPIOx_IDR (x=A…E) 端口输入数据寄存器,芯片读取引脚上的电平值,存放在这个寄存器里面

1.4 GPIOx_ODR (x=A…E) 端口输出数据寄存器

1.5 GPIOx_BSRR (x=A…E) 端口位设置/清除寄存器

1.6 GPIOx_BRR (x=A…E) 端口位清除寄存器,跟GPIOx_BSRR 重复了

2、GPIO的基地址:每个组(端口)的基地址不同:

Library\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h (芯片的不同型号,不同封装都会有差异)
A组(A端口)GPIOA 0x4001 0800
B组(B端口)GPIOB 0x4001 0C00
C组(C端口)GPIOC 0x4001 1000
D组(D端口)GPIOD 0x4001 1400
E组(E端口)GPIOE 0x4001 1800
F组(F端口)GPIOF 0x4001 1C00
G组(G端口)GPIOG 0x4001 2000
在这里插入图片描述

#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */

#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)

#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)

GPIOA 包含引脚PA0 ~ PA15
GPIOB 包含引脚PA0 ~ PA15
GPIOC 包含引脚PA0 ~ PA15
GPIOD 包含引脚PA0 ~ PA15
GPIOE 包含引脚PA0 ~ PA15

GPIOF 包含引脚PA0 ~ PA7
GPIOG 包含引脚PA0 ~ PA7

3、寄存器介绍

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

============================================== 分割线 =================================================


在这里插入图片描述

============================================== 分割线 =================================================

在这里插入图片描述


============================================== 分割线 =================================================

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


在这里插入图片描述
============================================== 分割线 =================================================

3.3、端口输入数据寄存器(GPIOx_IDR) (x=A…E)


在这里插入图片描述


3.4、端口输出数据寄存器(GPIOx_ODR) (x=A…E)

在这里插入图片描述

3.5、 端口位设置/清除寄存器(GPIOx_BSRR) (x=A…E)

在这里插入图片描述

3.6、 端口位清除寄存器(GPIOx_BRR) (x=A…E)

在这里插入图片描述
在这里插入图片描述

3.7GPIO 模块图

在这里插入图片描述

3.8、端口配置表,对GPIOx_CRL 和 GPIOx_CRH 两个寄存器配置的补充说明

在这里插入图片描述

3.9 GPIO的初始化,以GPIOC_12 为例

使用库函数对GPIO 端口初始化,最底层还是对上面几个寄存器进行配置,只是封装了一下而已。让用户使用起来方便一些。

Library\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)

Library\STM32F10x_StdPeriph_Driver\inc\stm32f10x_gpio.h

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */

Library\STM32F10x_StdPeriph_Driver\inc\stm32f10x_gpio.h

typedef enum
{
  GPIO_Mode_AIN = 0x0,  // 模拟输入模式
  GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入模式
  GPIO_Mode_IPD = 0x28, // 下拉输入模式
  GPIO_Mode_IPU = 0x48, // 上拉输入模式
  GPIO_Mode_Out_OD = 0x14, // 开漏输出模式
  GPIO_Mode_Out_PP = 0x10, // 推挽输出模式
  GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出模式
  GPIO_Mode_AF_PP = 0x18 // 复用推挽输出模式
} GPIOMode_TypeDef;

typedef enum
{ 
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

main.c

void func(void)
{
   GPIO_InitTypeDef GPIO_InitStructure; // stm32f10x_gpio.h 标准化的结构体
   
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; // 0x10 推挽输出
   GPIO_InitStructure.GPIO_Pin= GPIO_Pin_12; // GPIO_Pin_12 = 0x1000, GPIOC_12
   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; // 3
   
   GPIO_Init(GPIOC,&GPIO_InitStructure);
}

Library\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c

/**
  * @brief  Initializes the GPIOx peripheral according to the specified
  *         parameters in the GPIO_InitStruct.
  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
  * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
  *         contains the configuration information for the specified GPIO peripheral.
  * @retval None
  */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00;
  uint32_t pos = 0x00; // pin position: pin0, pin1, pin2, pin3, pin4, pin5, pin6, pin7, pin8, pin9, pin10, pin11, pin12, pin13, pin14, pin15
  uint32_t tmpreg = 0x00, pinmask = 0x00;
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
  assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  
  
/*---------------------------- GPIO Mode Configuration -----------------------*/
  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); // currentmode = 0x00 00 00 00
  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
  { 
    /* Check the parameters */
    assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
    /* Output mode */
    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; // currentmode = 0x00 00 00 03
  }
/*---------------------------- GPIO CRL Configuration ------------------------*/
  /* Configure the eight low port pins */
  if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
  {
    tmpreg = GPIOx->CRL;
    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    {
      pos = ((uint32_t)0x01) << pinpos; // operate pin0, pin1, pin2, pin3, pin4, pin5, pin6, pin7
      /* Get the port pins position */
      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
      if (currentpin == pos)
      {
        pos = pinpos << 2;
        /* Clear the corresponding low control register bits */
        pinmask = ((uint32_t)0x0F) << pos;
        tmpreg &= ~pinmask;
        /* Write the mode configuration in the corresponding bits */
        tmpreg |= (currentmode << pos);
        /* Reset the corresponding ODR bit */
        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
        {
          GPIOx->BRR = (((uint32_t)0x01) << pinpos);
        }
        else
        {
          /* Set the corresponding ODR bit */
          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
          {
            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
          }
        }
      }
    }
    GPIOx->CRL = tmpreg;
  }

4、 GPIO 的重映射功能

4.1 定时器TIM3 重映射

在这里插入图片描述


在这里插入图片描述

定时器 TIM3 完全重映射: 引脚PC6、7、8、9 原来是做其它用途的,完全重映射之后就变成了TIM3 的各个通道
引脚 PC6 变成了TIM3 的CH1 通道,(原来TIM3的CH1通道是PA6 引脚)
引脚 PC7 变成了TIM3 的CH2 通道,
引脚 PC8 变成了TIM3 的CH3 通道,
引脚 PC9 变成了TIM3 的CH9 通道,

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);  // TIM3 完全重映射

说白了,就是定时器TIM3 换了几个脚而已

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值