首页 > 其他分享 >2. GPIO读写

2. GPIO读写

时间:2024-07-29 22:39:06浏览次数:13  
标签:Pin 引脚 读写 电平 GPIOA GPIO 输入

GPIO简介

GPIO(全称为General Purpose Input/Output),即通用输入/输出,可以认为GPIO是片外外设与片内的通信接口,通过控制GPIO的电平状态,可以实现片外外设与片内的通信以及数据的输入输出。

对于st32F103系列的GPIO,其命名规则为GPIO+端口号,如GPIOA,GPIOB。对于每个端口又有着16个引脚(pin),编号为0~15。

以下便是一个GPIO引脚的结构图:
image

通过对不同寄存器的配置,可以切换GPIO的工作模式。

GPIO工作模式

从大致上分,GPIO有两种工作模式:

  • 输入模式:GPIO可以作为输入,通过读取GPIO的电平状态来获取外设的输入信号。
  • 输出模式:GPIO可以作为输出,通过控制GPIO的电平状态来驱动外设的输出信号。

而输入模式又可以分为:

  • 上拉输入模式(GPIO_MODE_IPU):通过内部上拉电阻,引脚悬空时默认为高电平,当输入低电平时,GPIO的电平状态为低电平。
  • 下拉输入模式(GPIO_MODE_IPD):通过内部下拉电阻,引脚悬空时默认为低电平,当输入高电平时,GPIO的电平状态为高电平。
  • 浮空输入模式(GPIO_MODE_IN_FLOATING):内部无上拉电阻或下拉电阻,易受外部电平干扰,精度不高,可外接上拉或下拉电阻来实现输入电平的上拉或下拉。
  • 模拟输入模式(GPIO_MODE_AIN):通过ADC模块,将模拟信号转换为数字信号,输入到GPIO。

输出模式又可以分为:

  • 推挽输出模式(GPIO_MODE_OUT_PP):输出高电平或低电平(三极管导通压降),通过控制GPIO的电平状态来驱动外设的输出信号。输出的高低电平均有驱动能力。
  • 开漏输出模式(GPIO_MODE_OUT_OD):该模式下,高电平无驱动能力(高阻态),低电平有驱动能力。
  • 复用推挽输出模式(GPIO_MODE_AF_PP)和复用开漏输出模式(GPIO_MODE_AF_OD),用到再学。

使用标准库来实现GPIO读写

image

由上图GPIO的结构可知,GPIO算是stm32的片内外设,且挂载在APB2总线上。在
stm32结构中,可以知道想要使用stm32的片内外设,必须先使能外设对应的时钟,这样才能让外设运行。

这里使用标准库来实现GPIO的各种操作。

以下给出使用标准库使能GPIOA第0引脚的例子。

#include "stm32f10x.h"

int main(void)
{
    // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    // 设置GPIO的各种参数
    GPIO_InitTypeDef GPIO_InitStructure;
    // 设置GPIO为推挽输出模式
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    // 设置GPIO初始化第0引脚 
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
    // 设置GPIO速度为50MHz
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    // 调用GPIO初始化函数,并指定初始化的GPIO,传入参数结构
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    while(1)
    {

    }
}

RCC_APB2PeriphClockCmd函数中,传入需要使能的外设名称,具体参数的名称可以在函数定义中找到,第二个参数选择ENABLE或DISABLE,即使能或失能时钟。

而在GPIO_Init函数中,需要指定初始化的GPIO代号,如GPIOA等,而第二个参数接受一个GPIO_InitTypeDef结构体,该结构体中包含了GPIO的各种参数,如GPIO模式、引脚号、速度等,需要提前定义并配置好该结构,并以结构指针的形式传入。

值得注意的是GPIO_InitTypeDef的结构体变量一般命名为GPIO_InitStructure,这样可以使得代码更加易读。

初始化后,可以通过几个库函数来实现对应引脚的输入输出操作。

/*输入读取操作*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

/*输出设置操作*/
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

在这些函数中,GPIOx参数代表GPIO的代号,如GPIOA等,GPIO_Pin参数代表GPIO的引脚号,如GPIO_Pin_0等。

对于有后缀Bits / Bit的函数,可以设置或读取单个引脚的电平状态,而对于没有后缀的函数,可以设置或读取整个端口的电平状态。

最后实现使用GPIO读取光敏传感器输入,并通过输入控制另一个GPIO的输出来控制Led亮灭。

代码如下

#include "stm32f10x.h"                  // Device header
#define true 1
#define false 0
typedef unsigned int uint;

int main(void)
{   
    // 使能GPIOA, GPIOB时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    
    // 配置GPIO模式
    GPIO_InitTypeDef GPIO_InitStructureA;
    GPIO_InitTypeDef GPIO_InitStructureB;

    // 配置输入GPIOA_Pin_0, 连接到光敏传感器
    GPIO_InitStructureA.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    GPIO_InitStructureA.GPIO_Pin  = GPIO_Pin_0;
    GPIO_InitStructureA.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructureA);

    // 配置输出GPIOB_Pin_0,控制Led亮灭
    GPIO_InitStructureB.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_InitStructureB.GPIO_Pin  = GPIO_Pin_0;
    GPIO_InitStructureB.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructureB);

    // 变量区
    uint8_t light = 0;
    while(true)
    {
        light = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
        if (light == 1)
            GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
        else
            GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
    }
}

引脚连接: Led正极连接到3.3V,负极连接到GPIOB_Pin_0, 光敏传感器的VCC连接3.3V,GND连接GND,信号端DO连接GPIOA_Pin_0。当未被遮挡时,DO端一直将引脚下拉至0,当被遮挡时,DO端将保持高电平。

标签:Pin,引脚,读写,电平,GPIOA,GPIO,输入
From: https://www.cnblogs.com/CrescentWind/p/18331234

相关文章

  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-19 读写I2C接口EEPROM实验
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述前面的课程中,我们......
  • [米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-20 读写I2C接口的RTC时钟芯片
    软件版本:Anlogic-TD5.9.1-DR1_ES1.1操作系统:WIN1064bit硬件平台:适用安路(Anlogic)FPGA实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板板卡获取平台:https://milianke.tmall.com/登录"米联客"FPGA社区http://www.uisrc.com视频课程、答疑解惑! 1概述    本节课继续利用I......
  • 关于GPIO输出模式下3种频率的解释
    配置GPIO输出模式时,有3种频率可以选择:2MHz、10MHz和50MHz,如下图:此处频率指的是I/O口驱动电路的响应频率而不是输出信号的频率。芯片的内部做了多个响应频率不同的输出驱动电路,可以根据需要选择合适的驱动电路。通过选取不同频率的输出驱动电路达到最佳的控制噪声和降低功耗的效......
  • 【linux】【设备树】具有 GPIO 控制器和连接器的硬件配置的备树(Device Tree)代码讲解
    具有GPIO控制器和连接器的硬件配置的备树(DeviceTree)代码讲解背景-学习Linux设备树代码soc{soc_gpio1:gpio-controller1{#gpio-cells=<2>;};soc_gpio2:gpio-controller2{#gpio-cells=<2>;};};connector:connect......
  • 【C语言】文件操作,文件读写详细介绍
    目录为什么要使用文件?文件概念1.什么是文件?2.程序文件3.数据文件4.文件名文件的使用1.文件指针2.文件的打开与关闭文件的顺序读写 1.顺序读写函数2.scanf系列与printf系列文件的随机读写 1.fseek2.ftell3.rewind文本文件,二进制文件 文件读取结......
  • 【嵌入式开发之标准I/O】二进制文件的读写及实验
    文本文件和二进制的区别文本文件和二进制文件的区别主要在于它们的编码方式和数据组织方式。‌编码方式:‌文本文件是基于字符编码的文件,‌常见的编码有ASCII编码、‌UNICODE编码等。‌这些编码将字符映射到特定的二进制值,‌使得字符可以在计算机中存储和传输。‌相比之下,‌......
  • pinctrl&gpio介绍
    目的:实现IO口功能设置的软硬件分离pinctrl:通过设备树节点,记录不同板级硬件信息;Pinctrl遵循的是platform框架实现实现设备总线。gpio:  通过一些列的API接口,读取设备树中pinctrl节点的硬件信息,设置相应的引脚功能。 pinctrl文件位置:Linux文件结构的dri......
  • easyexcel的读写操作
    easyexcel是基于java的读写excel的开源项目--读写也可理解为上传和下载写操作一、引入依赖<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency>二、封装相应对象@Data@AllArgsConst......
  • STM32读写FLASH
    要点:读写前要解锁并擦除整页才可以重新写入 测试代码#include"my_flash.H"/***@brief往内部FLASH写入数据*@paramaddr写入地址*@parampdata存储待写数据*@retvalNone*/voidFLASH_Inside_Wr(uint32_taddr,uint32_tPdata){//定义局部变......
  • python里读写excel等数据文件的几种常用方式
    python处理数据文件第一步是要读取数据,文件类型主要包括文本文件(csv、txt等)、excel文件、数据库文件、api等。下面整理下python有哪些方式可以读取数据文件。1.python内置方法(read、readline、readlines)read():一次性读取整个文件内容。推荐使用read(size)方法,size越大......