STM32学习笔记——GPIO,点灯之路第一步

学习B站上江科大stm32教学视频作的笔记

本文将从工作原理相关固件库函数来介绍GPIO。

工作原理

GPIO简介

GPIO,(General-purpose input/output),是由STM32控制的输入输出引脚,能够与外设进行交互,输出高低电平或者与外部通讯、采集和捕获数据等等。
stm32单片机的引脚被分为很多组,每个组别又有16个引脚,各个单片机型号有着不同的引脚数,笔者的单片机是stm32f103c8t6,只有PA、PB和PC的13、14、15引脚,总的引脚数是48。在这里插入图片描述
STM32F103C8T6

IO口的基本结构

在这里插入图片描述最右边的IO引脚就是单片机引出的GPIO引脚,左边接了两个保护二极管,可以防止芯片被外部过高或者过低的输入电压烧坏,当外部电压过高,上端的保护二极管导通,当电压低于VSS,下端的二极管导通。再往左边的电路决定了GPIO的工作模式。

GPIO工作模式

图中从上到下分别是AIN模拟输入,Floating浮空输入,IPD下拉输入,IPU上拉输入,OutOD开漏输出,OutPP推挽输出,AFOD复用开漏输出,AFPP复用推挽输出。
在这里插入图片描述
模拟输入一般用于AD输入;浮空输入很少使用,因为极容易受外部干扰而电平跳动,输入常用上拉输入;开漏输出和推挽输出命名是根据内部的PMOS和NMOS管,在该结构中输入高电平时,经过反向后,上方的P-MOS导通,下方的N-MOS关闭,对外输出高电平;

推挽输出:芯片输出低电平,N-MOS导通,P-MOS截止,因此引脚输出低电平。芯片输出高电平,P-MOS导通,N-MOS截止,因此引脚输出高电平。

开漏输出:当芯片输出高电平,此时NMOS管截止,此时引脚输出类似浮空的高阻态,当输出低电平,此时NMOS管导通,电流被强行拉到VSS,因此引脚输出强低电平。

推挽和开漏的区别是:推挽具有强的高低电平驱动能力,而开漏只有强的低电平驱动能力。且一般情况下都是使用推挽输出,除非某些特殊场景必须使用开漏,例如I2C的通信。

端口配置一图解

GPIO端口的复用和重映射

在这里插入图片描述
如图所示,PA6、7等端口具有自身的主功能,又有默认的复用功能,也有重定义的功能。

主功能:本身就是作为GPIO口。

复用功能:既能作为GPIO使用,又具有其他功能,例如PA6,可以作为SPI通信1口的MISO(Master Input Slave Output)、ADC模数转换器的端口、定时器3的1通道。

重定义:可以把指定的别的引脚的功能挪到这个引脚上来使用,需要在程序中调用库函数配置。

GPIO库函数

在这里插入图片描述
如图是GPIO库中的函数,常用的有:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
//初始化函数
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//输入读取函数,指定某一引脚
uint16_t  GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
//输入读取函数,指定某一组GPIO全部引脚
uint8_t  GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//输出读取函数,指定某一引脚
uint16_t  GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
//输出读取函数,指定某一组GPIO全部引脚
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//写函数,指定某一引脚将其置1
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//写函数,指定某一引脚将其置0
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
//初始化函数,默认初始化一组GPIO

在这里插入图片描述
配置GPIO需要用到结构体,设置结构体的值,之后将结构体传参给结构体初始化函数,初始化指定的一组GPIO口。例如:

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;		//PB7
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);

而在配置GPIO之前,要先开启时钟。
在这里插入图片描述
复位和时钟控制RCC是挂载在AHB总线的,课间APB2负责的是GPIOA和GPIOB以及复用IO口AFIO的配置。示例:

	//先初始化时钟,GPIO和AFIO
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	//注意参数和函数名都要是APB2

点亮一个LED灯

GPIO配置

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	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);
  • 首先要开启RCC时钟,由于GPIO口是由APB2管理,这里函数调用要注意。
  • 初始化结构体,选择输出方式是推挽输出,引脚选择GPIOA的0脚,速度选择50MHz,一般50MHz即可,除非对功耗有要求,可另行选择。
  • 最后调用初始化函数,把刚刚创建的局部结构体的地址传过去,GPIO_Init函数再取结构体的成员参数来操作相应的GPIO寄存器,传址是为了减少拷贝,提高效率。

设置引脚电平

这里采用上文提到的函数就可以设置引脚的电平

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//写函数,指定某一引脚将其置1
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//写函数,指定某一引脚将其置0
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
Delay_ms(500);
GPIO_SetBits(GPIOA, GPIO_Pin_0);
Delay_ms(500);

将函数放在while循环里就可以实现LED灯的闪烁,引脚置1或置0点亮LED取决于LED的连接方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值