STM32初识及运用—GPIO

(本博客所有关于32的文章都是基于stm32f103c8t648引脚))

GPIO初识——理论讲解

一.GPIO的工作模式

的啊实打实

四种输入模式

上拉输入
若GPIO引脚配置为上拉输入模式,在默认情况下(GPIO引脚无输入),读取 得的GPIO引脚数据位1,高电平。
下拉输入
若GPIO引脚配置为下拉输入模式,在默认情况下(GPIO引脚无输入),读取 得的GPIO引脚数据位0,低电平。
浮空输入
在芯片内部既没有接上拉,也没有接下拉电阻,经由触发器输入。配置成这个模式直接用电压表测量其引脚电压为1点几伏,这是个不确定值。由于其输入阻抗较大,一般把这种模式用于标准的通信协议如I2C,USART的接收端。
模拟输入
关闭了施密特触发器,不接上,下拉电阻,经由另一线路把电压信号传送到片上外设模块。如传送至ADC模块,由ADC采集电压信号。所以使用ADC外设时,必须设置为模拟输入模式。

四种输出模式
开漏输出
此种输出方式,输出寄存器写1时,mos管不导通,此时电平为浮空状态不确定,写0的时候,mos管导通,此时为低电平。此种方式在没有外部电路辅助的时候只能输出低电平。但是利用他这种特性,我们可以外接一个上拉电阻,此时不但可以输出高低电平,而且由于上拉电阻的存在大大的增强了单片机的驱动能力。
推挽式输出
最常用的一种GPIO模式,输出寄存器写1的时候为高电平,写0为低电平。能够快速的切换高低电平,适合做开关控制。
推挽式复用功能
此种方式大体与推挽式输出相同,区别在于其提供片内外设功能(I2C的SCL,SDA)
开漏复用功能
同样的,此种方式大体上与开漏输出模式一样,区别在于其提供片内外设功能(TX1,MOSI,MISO.SCK.SS)

二.GPIO的寄存器介绍

GPIO总共有七种寄存器
一.端口配置低寄存器GPIOX_CPL
二.端口配置高寄存器GPIOX_CRH
三.端口输入寄存器GPIO_IDR
四.端口输出寄存器GPIO_ODR
五.端口设置/清除寄存器GPIO_BSRR
六.端口清除寄存器GPIO_BRR
七.端口配置锁定寄存器GPIO_LCKR

(1)端口配置寄存器(CPL和CPH)

对于端口配置寄存器而言,端口配置高寄存器配置GPIO口的高八位,端口配置低寄存器则配置GPIO口的低八位。(每个GPIO口总共由16位)
GPL寄存器和CPH寄存器都总共有32位,每四个字节操控一个GPIO口
四个字节中的低两位是端口的模式位(MODE),四个字节中的高两位为配置位(CNF)
模式位操控输入输出模式和输出速率
配置位则是配合模式位确定GPIO口是具体是何种输出模式或者输入模式

(2)端口输入寄存器(IDR)

是一个32位寄存器,但是只有低16位可以用,高16位保留。
是一个只读寄存器,寄存器的每一位都对应的GPIO口状态

(3)端口输出寄存器(ODR)

是一个32位寄存器,但是只有低16位可以用,高16位保留。
是一个可读可写寄存器,只能以字(16位)的形式进行操控。(也就是每次操作必须对整个GPIO口进行读写,不能对某个单独的位进行操作(不支持位操作))

(4)端口设置/清除寄存器(BSRR)

此寄存器分为低十六位和高十六位。只写寄存器
低十六位是设置位,写入1则对相应的位设置,写入0则没有影响
高十六位是清除位,写入1则对相应的位清除,写入0则没有影响
且同时设置低十六位和高十六位是第十六位(设置位)起作用
操作BSRR寄存器的实质就是操作ODR寄存器

(5)端口清除寄存器(BRR)

是一个32位寄存器,但只有低16位才起作用,高16位保留。只写寄存器
跟其名字一样,是一个清除寄存器,对应位写入1则该位清除

(6)端口配置锁定寄存器(GPIO_LCKR)

这个寄存器几乎不会用到,这里不做讨论

GPIO初识——实际运用

注意:为了提高32在进行小项目开发的速度,本篇文章所用的代码都是笔者自己基于32标准库进行二次开发 ,方便能够快速调用单片机外设

关于代码,工程文件会附在文章的末尾。

一.GPIO的初始化

//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPIO初始化
//  @param      pin         选择的引脚 (可选择范围由 HYJ_GPIO.h 内PIN_enum枚举值确定)
//  @param      GPIO_Mode   引脚的模式  
//  @param      dat         引脚初始化时设置的电平状态,输出时有效 0:低电平 1:高电平
//  @return     void
//  Sample usage:       HYJ_GPIO_Init(PA0,GPIO_Mode_Out_PP,1);//PA0初始化为GPIO功能、推挽输出、输出高电平
//  @note					需要特别注意P20_2是不能用于输出的,仅仅只有输入的功能
//-------------------------------------------------------------------------------------------------------------------
void HYJ_GPIO_Init(PIN_enum pin ,GPIOMode_TypeDef GPIO_Mode,int8_t data)
{

	GPIO_InitTypeDef  GPIO_InitStructure;//定义GPIO配置结构体  
	
	RCC_APB2PeriphClockCmd(get_clock(pin),ENABLE);//时钟使能

	//GPIO的端口配置	
	GPIO_InitStructure.GPIO_Pin = get_pin(pin);				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode; 		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(get_port(pin), &GPIO_InitStructure);//将上述结构体传入真正的初始化函数(本质上在操作CPL CPH寄存器)					 

	if(GPIO_Mode==GPIO_Mode_Out_OD||GPIO_Mode==GPIO_Mode_Out_PP||GPIO_Mode==GPIO_Mode_AF_OD||GPIO_Mode==GPIO_Mode_AF_PP)
  HYJ_GPIO_Set(pin,data);//GPIO口初始化配置后,默认拉高电平(本质上在操作BSRR寄存器)						 	
}

(1)对引脚所拖挂的外设模块进行使能
(2)再利用一个结构体变量,将引脚的选择和GPIO的工作模式进行设置,这里实际上操作的是端口配置寄存器(CPL和CPH)
(3)再根据需求将端口初始化为低电平或者高电平**

二.GPIO的调用和实例

初始化完成后就可以进行调用

//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPIO输出设置
//  @param      pin         选择的引脚 (可选择范围由 HYJ_GPIO.h 内PIN_enum枚举值确定)
//  @param      dat         0:低电平 1:高电平
//  @return     void
//  Sample usage:           HYJ_GPIO_Set(PA0, 1);//P00_0 输出高电平
//-------------------------------------------------------------------------------------------------------------------
void HYJ_GPIO_Set(PIN_enum pin,int8_t data)
{	
		if(data==1)  get_port(pin)->BSRR = get_pin(pin);
	  else				 get_port(pin)->BRR = get_pin(pin);
}
//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPIO状态获取
//  @param      pin         选择的引脚 (可选择范围由 HYJ_GPIO.h 内PIN_enum枚举值确定)
//  @return     uint8       0:低电平 1:高电平
//  Sample usage:           uint8 status = gpio_get(PA0);//获取P00_0引脚电平
//-------------------------------------------------------------------------------------------------------------------
uint8_t HYJ_GPIO_Read(PIN_enum pin)
{
	return GPIO_ReadInputDataBit(get_port(pin),get_pin(pin));
}

根据初始化的模式,选择调用输出设置函数void HYJ_GPIO_Set(PIN_enum pin,int8_t data)还是状态读取函数uint8_t HYJ_GPIO_Read(PIN_enum pin)

示例:

 int main(void)
 {	
	HYJ_GPIO_Init(PA0,GPIO_Mode_Out_PP,1);
  while(1)		
	{
		HYJ_GPIO_Set(PA0, 1);
	}
 }

此时PA0引脚就被设置成输出高电平

工程文件链接地址:
链接:https://pan.baidu.com/s/1abTvUt44NiH5B_o7IiPa3Q
提取码:cxm6
复制这段内容后打开百度网盘手机App,操作更方便哦–来自百度网盘超级会员V1的分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值