STM32入门教程第二讲

系列文章目录

STM32入门教程第二讲------介绍GPIO


目录

系列文章目录

前言

一、GPIO是什么?

1.简要介绍GPIO

2.GPIO基本结构

二.GPIO的模式介绍 (四种输入四种输出)

1.浮空输入_IN_FLOATING:

​编辑

2. 模拟输入_AIN ​编辑

3带上拉输入_IPU 

4 .带下拉输入_IPD

5.开漏输出_OUT_OD

6.推挽输出_OUT_PP

7.开漏复用输出_AF_OD

8. 推挽复用输出_AF_PP

 三、GPIO的使用步骤

           1.第一步,使用RCC开启GPIO时钟:

        2.第二步,使用GPIO_Init函数初始化GPIO:

         3.第三步,使用输出和输入的函数控制GPIO口,以点LED为例:

  



前言

前一篇我们学习了怎么建立一个stm32的keil工程,下面我们来详细介绍GPIO


一、GPIO是什么?

1.简要介绍GPIO

 首先介绍一下GPIO,GPIO(General Input Output)是通用输入输出口,可配置为八种输入输出模式,引脚电平:0—3.3V,部分引脚容忍5V。

输出模式——可控制端口输出高低电平,用以驱动LED,控制蜂鸣器,模拟通信协议输出时序等;

输入模式——可读取端口的高低电平或电压,用于读取按键输入,外界模块电平信号输入,AOC电压采集,模拟通信协议接收数据等。

2.GPIO基本结构

二.GPIO的模式介绍 (四种输入四种输出)

1.浮空输入_IN_FLOATING:


 

当GPIO采用浮空输入模式时,STM32的引脚状态是不确定的,I/O端口的电平信号直接进入输入数据寄存器。此时STM32得到的电平状态完全取决于GPIO外部的电平状态,所以说在GPIO外部的引脚悬空(无信号输入情况下)时,读取该端口的电平状态是个不确定的值。 

通常用于IIC、USART。

2. 模拟输入_AIN 

这个很好理解,最常用的场合是ADC模拟输入,不像其他输入模式只有0和1,模拟输入模式可以读取到很细微变化的值,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等。模拟信号一般:3.3v 5v 9v。 

3带上拉输入_IPU 

 

具有上升沿触发检测的外部中断模式 ,与前面介绍的浮空输入模式相比,仅仅是在数据通道上面,接入了一个上拉电阻,根据STM32的数据手册,这个上拉电阻阻值介于30K~50K 欧姆。同样,CPU可以随时在“输入数据寄存器”的另一端,通过内部的数据总线读出I/O 端口的电平变化的状态

4 .带下拉输入_IPD

 

 下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也是高电平。

5.开漏输出_OUT_OD

 

开漏输出模式下(上拉电阻+N-MOS管),通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。

可以输出0和1,适用于电平不匹配场合,要得到高电平需要上拉电阻才行。

6.推挽输出_OUT_PP

 推挽输出模式下(P-MOS管+N-MOS管),通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。

可以输出高低电平0和1,适用于双向IO使用。

7.开漏复用输出_AF_OD

开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。 

8. 推挽复用输出_AF_PP

推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。 

一句话区分开漏和推挽输出:

推挽输出高低电平都有驱动能力
开漏输出高电平无驱动能力,低电平有驱动能力

 三、GPIO的使用步骤

        1.第一步,使用RCC开启GPIO时钟:

        上代码:

	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);开始RCC时钟

        详细步骤:在libraries中--stm32f10x_rcc.h中:

找到如下库函数的定义: 

是关于GPIO的时钟开启库函数定义,选用哪一个取决于自己的项目需求 

以APB2为例,转到函数定义:

直接上代码:

/**
  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.
  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
  *   This parameter can be any combination of the following values:
  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     
  * @param  NewState: new state of the specified peripheral clock.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    RCC->APB2ENR |= RCC_APB2Periph;
  }
  else
  {
    RCC->APB2ENR &= ~RCC_APB2Periph;
  }
}

根据使用的I/O确定第一个函数参数,然后ENABLE为第二参数;

时钟启动成功。

2.第二步,使用GPIO_Init函数初始化GPIO:

上代码:

GPIO_Init(GPIOA,&GPIO_InitStructure);

详细步骤:转到GPIO_Init函数定义:

/**
  * @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, pos = 0x00;
  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));  

根据使用的I/O确定第一个函数参数,以GPIOA为例,因此第一个参数为GPIOA,根据函数定义,第二个参数需要定义结构体;

上代码:

GPIO_InitTypeDef GPIO_InitStructure;
定义结构体,如果报错268,可以把该行放在RCC时钟上边,放在RCC下边的话需要在编译器魔术棒-C/C++改为C99
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

第一行声明结构体后,在下边引出结构体的三个内容 ,下边详细介绍方法:

首先第一个GPIO_Mode

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出

转到GPIO_Mode定义: 

 GPIOMode_TypeDef GPIO_Mode;  
  /*!< Specifies the operating mode for the selected pins.
           This parameter can be a value of @ref GPIOMode_TypeDef*/

继续转到  GPIOMode_TypeDef:

是一个枚举 :

/** 
  * @brief  Configuration Mode enumeration  
  */

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;

根据项目需求选择,以推挽输出为例:选择  GPIO_Mode_Out_PP,因此,Mode搞定。

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出

同理操作 :GPIO_Pin和GPIO_Speed;

需要注意的是,转GPIO_Pin定义时选择member,如下图:

 全部写好后,结构体定义完成
 

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;

由此,GPIO_Init就写好了:

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//到上边为止,GPIO初始化完成

 3.第三步,使用输出和输入的函数控制GPIO口,以点LED为例:

先上代码:

	GPIO_SetBits(GPIOC,GPIO_Pin_13);//将PC13号口置为高电平		(灯灭)
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);//将PC13号口置为低电平 (灯亮)

转到函数定义根据项目需求写参数即可,就不详细介绍了,下一期详细讲解控制LED的操作

至此,GPIO介绍完成。


  

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值