STM32通用复用IO详细解析

前言


GPIO通用输入输出,简称IO,每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL, GPIOx_CRH),两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。AFIO寄存器是用来复用IO的

一.GPIO功能描述 

1.GPIO模式

通过两个端口配置寄存器(CRL、CRH)可以配置GPIO的输入输出模式和输出速度

1>通用IO 

 

  1.  推挽输出:两个mos管,使得既可以输出高电平,也可以输出低电平,输出高电平的时候叫做灌电流,即推,输出低电平时叫做拉电流,即挽
  2. 开漏输出:外接一个上拉电阻,IO默认为高阻态,只能输出低电平,高电平驱动能力弱,具有线与的功能,一个为低,全为低,IIC通信的引脚就为开漏输出模式
  3. 模拟输入:一般用于A/D ,D/A数模转换,PWM方波输入
  4. 浮空输入:引脚电平浮空,具体是什么电平要看外部输入什么电平,一般按键的IO可以用浮空输入
  5. 上下拉输入:通过一个电阻,把引脚电平拉高/拉低,具体配置要看原理图的画法

        如上图,KEY接在了GND上,即KEY初始是低电平,即我们要检测高电平才能判断按键按下了,所以KEY可以给下拉输入,简单的说,如果你希望检测低(高)电平就上(下)拉

注意:当配置GPIO为模拟输入的时候(没有上下拉),比如我现在要用PA0连接到电位器测量电位器的电压,但是这个时候我并没有去连接,而是把PA0悬空了,什么也不接,这个时候读取PA0的电平也会有一个值,只不过并不确定这个值是多少,只有测了才知道,按经验来说,是1.6左右

2>复用IO

GPIO复用,GPIO的复用发生在片上外设之中,如IIC, TIM,USART等等

3>重映射

重映射即把外设默认的GPIO端口配置到其他的IO上,例如,PA0和PB0为默认IIC的引脚,但是PA0和PB0已经用在了其他的外设上,为了不引起引脚冲突,我们可以用重映射,把IIC的引脚重映射到PC0,PD0上来使用

关于IO的重映射表可以在参考手册中寻找 

使用重映射时,务必打开AFIO时钟

2. GPIO寄存器

1>单独的位设置或清除

当对GPIOx_ODR的个别位编程时,软件不需要禁止中断:在单次APB2写操作里,可以只更改一个或多个位。

这是通过对“置位/复位寄存器” (GPIOx_BSRR,复位是 GPIOx_BRR)中想要更改的位写’1’来实现的。没被选择的位将不被更改

2>端口配置寄存器CRL、CRH

 用来配置输入输出模式的寄存器

CRL配置低八位,CRH配置高八位

库函数里有一套初始化的函数,可以直接配置GPIO模式

3>端口输入输出寄存器ODR、IDR

可以利用库函数来读取IO的值GPIO_ReadInputDataBit() ,GPIO_ReadOutputDataBit()

也可以用寄存器操作,GPIOA->IDR/ODR

输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据

 

4.端口配置锁定寄存器

当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。
 

该寄存器用的较少

3.AFIO寄存器

复用重映射和调试I/O配置寄存器(AFIO_MAPR)

该寄存器用来配置重映射IO

当使用了重映射时,一定要记得开启AFIO的时钟

其他的寄存器将用来配置外部中断,GPIO的各个引脚都有一个中断线,就是通过AFIO寄存器来配置
 

二.库函数使用 

GPIO结构体

typedef struct
{
  uint16_t GPIO_Pin;            //选择引脚
  GPIOSpeed_TypeDef GPIO_Speed; //输出速度
  GPIOMode_TypeDef GPIO_Mode;   //模式
                   
}GPIO_InitTypeDef;

下面是我用LED为例子写的

#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;//定义GPIO结构体

	RCC_APB2PeriphClockCmd(LED_R_GPIO_CLK | LED_G_GPIO_CLK | LED_B_GPIO_CLK,ENABLE);//开启LED相关的GPIO外设时钟
	
	//设置速度和输出方式
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;//通用推挽输出,高低电平都可输出
	
	//绿灯
	GPIO_InitStruct.GPIO_Pin   = LED_G_GPIO_PIN;
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_InitStruct);
	
	//红灯
	GPIO_InitStruct.GPIO_Pin   = LED_R_GPIO_PIN;
	GPIO_Init(LED_R_GPIO_PORT,&GPIO_InitStruct);
	
	//蓝灯
	GPIO_InitStruct.GPIO_Pin   = LED_B_GPIO_PIN;
	GPIO_Init(LED_B_GPIO_PORT,&GPIO_InitStruct);
	
	//关所有灯
	GPIO_SetBits(LED_B_GPIO_PORT, LED_B_GPIO_PIN);
	GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
	GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_PIN);

}
#ifndef __BSP_LED_H
#define __BSP_LED_H

#include "stm32f10x.h"                  // Device header

#define LED_G_GPIO_PIN          GPIO_Pin_0
#define LED_G_GPIO_PORT			GPIOB
#define LED_G_GPIO_CLK			RCC_APB2Periph_GPIOB

#define LED_B_GPIO_PIN          GPIO_Pin_1
#define LED_B_GPIO_PORT			GPIOB
#define LED_B_GPIO_CLK			RCC_APB2Periph_GPIOB

#define LED_R_GPIO_PIN          GPIO_Pin_5
#define LED_R_GPIO_PORT			GPIOB
#define LED_R_GPIO_CLK			RCC_APB2Periph_GPIOB

//使用宏定义控制灯的亮灭
#define ON  1
#define OFF 0

// \    c语言中的续行符,其后面不能有空格和任何东西
// exp1?exp2:exp3 三目操作符			真 真 假
//													    假 假 真		

#define LED_G(a)	a?GPIO_ResetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN):	GPIO_SetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN)

					
#define LED_R(a)	if (a)	\
					GPIO_ResetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN);\
					else		\
					GPIO_SetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN)	
					
#define LED_B(a)	if (a)	\
					GPIO_ResetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN);\
					else		\
					GPIO_SetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN)
					
#define LED_G_TOGGLE /*翻转*/		  (LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_PIN)
					
// ^ 异或运算,相同为0,不同为1	
					
#define LED_Y  		LED_G(ON);LED_B(OFF);LED_R(ON)
#define LED_P  		LED_G(OFF);LED_B(ON);LED_R(ON)
#define LED_C  		LED_G(ON);LED_B(ON);LED_R(OFF)
#define LED_W  		LED_G(ON);LED_B(ON);LED_R(ON)
#define LED_OFF		LED_G(OFF);LED_B(OFF);LED_R(OFF)
void LED_GPIO_Config(void);
#endif //__BSP_LED_H

物联沃分享整理
物联沃-IOTWORD物联网 » STM32通用复用IO详细解析

发表评论