STM32小笔记(一) GPIO口的配置

GPIO口的使用:

1.GPIO和AFIO 全系列支持

 

GPIO寄存器

(1)两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH);

(2)两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR);

(3)一个32位置为/复位寄存器(GPIOx_BSRR);

(4)一个16位复位寄存器(GPIOx_BRR);

(5)一个32位锁存器(GPIOx_LCKR);

 

  输入配置

当I/O端口配置为输入时:

●  输出缓冲器被禁止

●  施密特触发输入被激活

●  根据输入配置(上拉,下拉或浮动)的不同,弱上拉和下拉电阻被连接

●  出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器

●  对输入数据寄存器的读访问可得到I/O状态

 

输出配置

当I/O端口被配置为输出时:

●  输出缓冲器被激活

─  开漏模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将端口置于高阻状态(PMOS从不被激活)。

─  推挽模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-MOS。

●  施密特触发输入被激活

●  弱上拉和下拉电阻被禁止

●  出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器

●  在开漏模式时,对输入数据寄存器的读访问可得到I/O状态

●  在推挽式模式时,对输出数据寄存器的读访问得到最后一次写的值。

 

STM32中的配置寄存器在固件函数库中早已生成,因此无需再对寄存器的每个设定写定义,而是直接调用关键字。这样我们可以不再关心寄存器的具体配置(因为那已经在固件配置好了);因此直观的从配置函数中去看,更能有效的提高。

 

GPIO相关的库函数如下,位于在“stm32f10x_gpio.h”

GPIO相关函数如下:

 

void GPIO_DeInit(GPIO_TypeDef* GPIOx);

void GPIO_AFIODeInit(void);

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

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);

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

void GPIO_EventOutputCmd(FunctionalState NewState);

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

 

以下将逐个说明函数功能及注释说明:

·void GPIO_DeInit(GPIO_TypeDef* GPIOx);

 

该函数原型在"stm32f10x_gpio.C"当中,类似C++ 的注释说明如下:

 

  * @brief  Deinitializes the GPIOx peripheral registers to their default reset values.

  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.

  * @retval None

其中是为不同组的IO口进行寄存器值的初始化。

初始化语句如下:

“  RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);

RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);”

再追根溯源到这个函数,位于“stm32f10x_rcc.C”当中

"void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)"

{

  

  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));

  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)

  {

    RCC->APB2RSTR |= RCC_APB2Periph;

  }

  else

  {

    RCC->APB2RSTR &= ~RCC_APB2Periph;

  }

}

函数注释如下:

 

一目了然,即配置IO口时钟状态为使能或者失效。

 

当然在其中此函数作为一个初学实例还是值得深究的:

  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));

  assert_param(IS_FUNCTIONAL_STATE(NewState));

此处两句即类似于C++中的断言函数,作为函数运行的先决条件。这里将断言函数直接说明,在后续的实例中,仍旧会有使用到的地方。

 

  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))

 

  void assert_failed(uint8_t* file, uint32_t line);

#else

  #define assert_param(expr) ((void)0)

#endif 

#endif 

若满足断言值为"1"的条件,否则判定失败输出 文件名和所在行。不为"0"返回0.

 

再返回“assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));”此句中。“IS_RCC_APB2_PERIPH”如下定义:

·#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))

此处使用到的是AP2 进入该函数还可以看到AP2AP1AP三个高速时钟族的各项定义。姑且在这里认为是判定开启对应时钟前的时钟功能验证。

·#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))

只为考虑还是的形参是否是“DISABLEorENABLE” 两个状态。

 

“ if (NewState != DISABLE)

  {

    RCC->APB2RSTR |= RCC_APB2Periph;

  }

  else

  {

    RCC->APB2RSTR &= ~RCC_APB2Periph;

  }

APB2RSTR则即将牵扯到RCC的设置问题,我们下一节再讲。

 

 

·void GPIO_AFIODeInit(void);功能复用,重新映射事件控制。

同样调用“RCC_APB2PeriphResetCmd”。也是串口初始化判断

·void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

寄存器手册中记为:根据GPIO_InitStruct中指定参数初始化外设GPIOx寄存器

不想在此处在赘述此函数,主要通过写寄存器的值来配置GPI0x,GPIO_pin,GPIO_Mode,GPIO_speed,以及写GPIO CRL/CRH寄存器。

·void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);被上一结构体调用

GPIO_Speed  描述

GPIO_Speed_10MHz  最高输出速率10MHz 

GPIO_Speed_2MHz  最高输出速率2MHz 

GPIO_Speed_50MHz  最高输出速率50MHz 

 

GPIO_Mode_AIN  模拟输入

GPIO_Mode_IN_FLOATING  浮空输入

GPIO_Mode_IPD  下拉输入

GPIO_Mode_IPU  上拉输入

GPIO_Mode_Out_OD  开漏输出

GPIO_Mode_Out_PP  推挽输出

GPIO_Mode_AF_OD  复用开漏输出

GPIO_Mode_AF_PP  复用推挽输出

 

·

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);,

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

读取指定管脚输入/输出,读取管脚输入/输出数据值。 一个读取的是管脚的状态,而一个读取的输入or 输出数据寄存器的值。这一点要分清

·

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

"bitval must be Bit_RESET or Bit_SET“

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

 “Portval为将写入数据寄存器的值”

设定/清除指定的数据位

·void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

锁存管脚寄存器,锁存指定GPIO组指定引脚。

·void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

  void GPIO_EventOutputCmd(FunctionalState NewState);

配置GPIO为事件输出,其后我们来解决这个疑问。

·void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

此函数决定了IO口的重新映射,实际是IO复用功能的实现,GPIO_Remap选择输入引脚,NewState的配置值如下:GPIO_Remap_SPI1  SPI1复用功能映射

GPIO_Remap_I2C1  I2C1复用功能映射

GPIO_Remap_USART1  USART1复用功能映射

GPIO_PartialRemap_USART3  USART2复用功能映射

GPIO_FullRemap_USART3  USART3复用功能完全映射

GPIO_PartialRemap_TIM1  USART3复用功能部分映射

GPIO_FullRemap_TIM1  TIM1复用功能完全映射

GPIO_PartialRemap1_TIM2  TIM2复用功能部分映射1 

GPIO_PartialRemap2_TIM2  TIM2复用功能部分映射2 

GPIO_FullRemap_TIM2  TIM2复用功能完全映射

GPIO_PartialRemap_TIM3  TIM3复用功能部分映射

GPIO_FullRemap_TIM3  TIM3复用功能完全映射

GPIO_Remap_TIM4  TIM4复用功能映射

GPIO_Remap1_CAN  CAN复用功能映射1 

GPIO_Remap2_CAN  CAN复用功能映射2 

GPIO_Remap_PD01  PD01复用功能映射

GPIO_Remap_SWJ_NoJTRST  除JTRST外SWJ完全使能(JTAG+SW-DP)

GPIO_Remap_SWJ_JTAGDisable  JTAG-DP失能+ SW-DP使能

GPIO_Remap_SWJ_Disable  SWJ完全失能(JTAG+SW-DP)

每个功能在后面小节的应用中体现。

·void GPIO_EXTILineConfig(u8 GPIO_PortSource, u8 GPIO_PinSource)

GPIO配置为外部中断,两个值分别为端口值和引脚。

·void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) 

最后一个配置以太网接口。该函数只有两行语句。此处不作介绍。

你可能感兴趣的:(STM32学习笔记)