STM32速成笔记—GPIO

这篇具有很好参考价值的文章主要介绍了STM32速成笔记—GPIO。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


🎀 文章作者:二土电子

🌸 关注文末公众号获取其他资料和工程文件!

🐸 期待大家一起学习交流!


一、什么是GPIO

GPIO(英语:General-purpose input/output),通用型之输入输出的简称,可以用来输入高低电平或者输出高低电平。这里的高电平指的是3.3V,低电平指的是0V。通常称GPIO为IO口,或者引脚。

STM32F103ZET6有GPIOx_0~GPIOx_15,其中x = A,B,C,D,E,F,G。

二、GPIO的输入/输出模式

GPIO有多种输入输出模式,输入模式有

  • 输入浮空
    输入浮空指的是GPIO与外设之间既不接高电平,也不接低电平,呈高阻态。除了类似于在数据传输时将GPIO配置为输入浮空外,一般不配置为该模式。因为输入浮空状态的GPIO电压具有不确定性,可能是0V,也可能是VCC,或者是介于0V和VCC之间的某一个值。
  • 输入上拉
    输入上拉是通过一个上拉电阻,将GPIO拉至高电平状态,不受外接电路的影响。
  • 输入下拉
    输入下拉是通过一个下拉电阻,将GPIO拉至低电平,不受外接电路的影响。
  • 模拟输入
    模拟输入模式通常用在ADC采集,采集模拟信号。

输出模式有

  • 开漏输出
  • 推挽式输出
  • 推挽式复用功能
  • 开漏复用功能

对于一些输出模式这里就不再做详细介绍了,贴一篇大佬的文章深刻理解GPIO。这些模式在接下来的学习过程中会慢慢的介绍这些模式需要在什么时候使用,这里只需要知道就够了。

三、GPIO初始化配置

本专栏介绍的是使用库函数进行开发,很多内容都是库函数提供的,相对来讲非常方便。在初始化GPIO时有一个结构体,只需要对这个结构体进行配置即可。结构体中包括想要配置的GPIO引脚,GPIO速度,GPIO工作模式。

初始化GPIO的步骤主要有

  • 定义GPIO结构体
  • 开启时钟
    GPIO工作需要提供时钟信号,在初始化结构体之前需要将时钟打开
  • 配置结构体成员
    GPIO_Pin是想要配置的IO,GPIO_Speed,通常写GPIO_Speed_50MHz,GPIO_Mode是IO的工作模式
  • 写入配置

GPIO的工作模式在程序中有定义

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的例程如下

void Drv_Gpio_Init (void)
{
	GPIO_InitTypeDef GPIO_InitStructure;   // 定义结构体
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);

    // 配置结构体
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

这里初始化的是PA0,PA8和PB1,PB2。在开启时钟不必要写两遍相同的代码用来初始化GPIOA和GPIOB的时钟。写一句,用“ | ”同时开启两个GPIO的时钟。写Pin时也同理。

四、Boot引脚

这里简单介绍一下Boot引脚的配置,对于只是利用核心板编写程序的小伙伴来说Boot引脚的存在感较低,但是当我们需要绘制硬件电路图时,Boot引脚怎么连接就显得很重要。
中文参考手册中介绍如下
STM32速成笔记—GPIO

这里简单说一下本人经历得来的经验。如果想使用USB转TTL通过串口下载程序,Boot0需要通过KΩ级电阻接VCC,Boot1接地。下载完程序后再将Boot0接地。需要注意的是这个KΩ级别的电阻最好用10KΩ左右电阻,如果电阻太大会导致下载失败。

由于本人在使用自制板时只使用过串口下载,所以对于用调试器下载需要怎么配置Boot引脚,未测试。

五、一些特殊的GPIO

在使用GPIO时需要注意一些特殊的GPIO,否则你会疑惑,为什么一些引脚的高低电平无法控制。其实有些GPIO在上电后就有自己的默认设置,会稳定在高电平或者低电平。比如用作JTAG的几个GPIO——PB3,PB4,PA13,PA14和PA15。这几个GPIO在上电后就已经默认用作JTAG,即使用上面的GPIO初始化程序将这几个引脚初始化后,依旧无法控制(无法正常用程序拉高拉低)。

这个时候我们需要对这几个GPIO进行复用重映射,关掉其默认的功能,才能作为普通的GPIO使用。针对JTAG/SWD复用功能重映射,中文参考手册描述如下
STM32速成笔记—GPIO
图中说明这几个GPIO有几种模式,完全SWJ,表中的五个IO均不可作为普通IO使用。完全SWJ但是没有JNTRST,PB3和PB4可用,依此解读。上图是针对寄存器开发描述的内容,使用库函数开发时有封装好的函数,但是需要注意的是需要提前开启AFIO时钟(对于AFIO是指什么,大家可以自行了解)。使用库函数开发时针对特殊引脚进行重映射的操作步骤为

  • 定义GPIO结构体
  • 开启GPIO时钟和AFIO时钟
  • 重映射引脚(根据所需情况设定引脚模式)
  • 配置GPIO结构体初始化GPIO

库函数中提供了可以选择的三种引脚模式

GPIO_Remap_SWJ_NoJTRST          // 完全SWJ(恢复引脚的默认功能)
GPIO_Remap_SWJ_JTAGDisable      // 关闭JTAG,启用SW-DP
GPIO_Remap_SWJ_Disable          // 关闭JTAG-DP,关闭SW-DP

提供了一个函数,可以进行重映射操作

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

当需要使用到上述的五个GPIO时,初始化程序需要修改,举例如下

void Drv_Gpio_Init (void)
{
	GPIO_InitTypeDef GPIO_InitStructure;   // 定义结构体
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | 
	                       RCC_APB2Periph_AFIO,ENABLE);

    // 关闭JTAG-DP,关闭SW-DP
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
    
    // 配置结构体
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

STM32F103ZET6芯片GPIO资源较为丰富,平时开发时尽量不要使用这几个特殊引脚。

六、点亮LED

学习完GPIO后我们就可以利用GPIO进行一些简单的操作,比如点亮LED,使用蜂鸣器,用IO驱动小黄电机,检测按键等。

点亮LED比较简单,但是也有一些需要注意的点

  • 根据硬件电路确定LED是高电平点亮还是低电平点亮
  • 初始化GPIO后要先将所有的LED

1. 硬件电路

下图所示电路中,LED右侧接3.3V,左侧接IO口。此时如果想点亮LED,需要将对应的IO电平拉低。相反如果右侧接的是地,如果想要点亮LED,需要将对应IO电平拉高。
STM32速成笔记—GPIO

2. 拉高/拉低GPIO

如何将GPIO电平拉高拉低?库函数提供了封装好的函数

// 设置为高电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

// 设置为低电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

3. 程序设计

点亮LED很简单,只需要初始化相应的GPIO,输入模式设置为推挽式输出,然后设定电平即可。

这里给出点亮LED的例程,LED电路为一侧接3.3V,另一侧接GPIO。

这里给出的只是一些必要的函数,如果需要工程模板可私信联系。

需要注意的是,初始化GPIO时需要开启时钟,开启时钟之前需要确认GPIO挂载的总线。

/*
 *==============================================================================
 *函数名称:Drv_Led_Init 
 *函数功能:初始化LED的GPIO
 *输入参数:无
 *返回值:无
 *==============================================================================
*/
void Drv_Led_Init (void)
{
	GPIO_InitTypeDef GPIO_InitStructure;   // 定义结构体
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    // 配置结构体
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_SetBits(GPIOA,GPIO_Pin_1);   // 熄灭LED
}

/*
 *==============================================================================
 *函数名称:Med_Led_On 
 *函数功能:点亮LED
 *输入参数:无
 *返回值:无
 备注:如果有多个LED可以定义一个结构体或者使用swtich,增加一个输入变量
      来确定开启哪个LED
 *==============================================================================
*/
void Med_Led_On (void)
{
    GPIO_ResetBits(GPIOA,GPIO_Pin_1);   // 熄灭LED
}

七、GPIO的位带操作

对于什么是“位带”这里就不做解释了,大家可以自行搜索。这里只介绍如何使用。位带操作可以使操作GPIO变得更加简单。在模板程序的sys.h文件中已经定义好了各个IO的位带操作所需内容

//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

有了位带操作后,就不需要再使用前面介绍的拉高拉低函数来操作GPIO。比如需要拉d低PA1

PAout(1) = 0;   // 拉低PA1

有了位带操作后也可以对GPIO进行宏定义,用自己想要的名字来操作它。还是拿上面的拉低PA1举例文章来源地址https://www.toymoban.com/news/detail-492554.html

#define LED   PAout(1)   // 将PA1宏定义为LED

LED = 1;   // 拉高PA1
LED = 0;   // 拉低PA1

到了这里,关于STM32速成笔记—GPIO的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32速成笔记—RTC

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! RTC(Real Time Clock)实时时钟,它是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当

    2024年02月11日
    浏览(27)
  • STM32速成笔记—DMA

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! DMA全程Direct Memory Access,即直接存储器访问。简单来讲,它的功能是把数据从一个地址搬运到另一个地址。通常有三个传输方向,分别是内存到内存,内存到外设和外设到内

    2024年02月11日
    浏览(25)
  • STM32速成笔记—Flash闪存

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! 快闪存储器(flash memory),是一种电子式可清除程序化只读存储器的形式,允许在操作中被多次擦或写的存储器。它是一种非易失性存储器,即断电数据也不会丢失。 STM32

    2024年02月16日
    浏览(26)
  • STM32速成笔记—低功耗模式

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! STM32提供了一些低功耗模式。默认情况下,系统复位或上电复位后,微控制器进入运行模式。在运行模式下,HCLK 为CPU提供时钟,并执行程序代码。当 CPU 不需要继续运行(例如

    2024年02月12日
    浏览(38)
  • STM32速成笔记—定时器

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! 关于什么是定时器,简单来讲,就是是用来定时的。STM32F103ZET6有两个基本定时器TIM6和TIM7,四个通用定时器TIM2~TIM5和两个高级定时器TIM1,TIM8。每一个定时器都是完全独立的

    2024年02月09日
    浏览(40)
  • STM32速成笔记—EEPROM(AT24C02)

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! AT24C01/02/04/08/16…是一个1K/2K/4K/8K/16K位电可擦除PROM,内部含有128/256/512/1024/2048个8位字节,AT24C01有一个8字节页写缓冲器,AT24C02/04/08/16有一个16字节页写缓冲器。电压可允许低

    2024年02月11日
    浏览(45)
  • 蓝桥杯嵌入式STM32 G431 hal库开发速成——ADC与DAC

    模数转换器(ADC):它将模拟信号转换为单片机能够处理的数字信号。在很多应用中,比如温度传感器、压力传感器等,信号最初都是模拟形式的。ADC 读取这些模拟信号,然后将它们转换为数字形式,以便单片机可以读取和处理。 数模转换器(DAC):它执行相反的操作,将

    2024年02月01日
    浏览(43)
  • 蓝桥杯STM32 G431 hal库开发速成——按键+PWM综合案例——按键控制PWM驱动舵机

    适用于学习了TIM输出比较(PWM)跟GPIO输入(按键)的新手作为练习的综合项目! PWM(Pulse Width Modulation,脉冲宽度调制)是一种常用的技术,用于通过调节电信号的脉冲宽度(即脉冲的持续时间)来控制模拟系统的电源。在数字电子系统中,由于只能输出固定的高(通常为

    2024年01月21日
    浏览(48)
  • 【STM32】STM32学习笔记-STM32简介(02)

    STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器 STM32常应用在嵌入式领域,如智能车、无人机、机器人、无线通信、物联网、工业控制、娱乐电子产品等 STM32功能强大、性能优异、片上资源丰富、功耗低,是一款经典的嵌入式微控制器 1.1 STM32是什么 STM32是一系列由ST Micro

    2024年02月04日
    浏览(29)
  • stm32学习笔记-1 STM32简介

    注:笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注:工程及代码文件放在了本人的Github仓库。 本教程使用STM32最小系统板(STM32F103C8T6)+面包板硬件平台进行学习。使用面包板可以完成任意硬件的连接,相比于成品的开发板方式,使用面包板更

    2024年02月02日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包