GPIO

发布于 2023-08-11  768 次阅读


内容纲要

GPIO笔记

GPIO简介

•GPIO(General Purpose Input Output)通用输入输出口

•可配置为8种输入输出模式

•引脚电平:0V~3.3V,部分引脚可容忍5V

•输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等

•输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等


GPIO基本结构

打通步骤(以LED灯为例)

一、RCC开启时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 正点原子红LED灯
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 正点原子绿LED灯

二、配置GPIO口

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitTypeDef GPIO_InitStructure2;
    GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOE, &GPIO_InitStructure2);

三、设置高电平关灯(LED灯)

    GPIO_SetBits(GPIOB, GPIO_Pin_5);
    GPIO_SetBits(GPIOE, GPIO_Pin_5);

GPIO位结构

简单了解即可

GPIO的八种输入输出模式

对应参数

typedef enum
{ GPIO_Mode_AIN = 0x0, // 模拟输入
  GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入
  GPIO_Mode_IPD = 0x28, // 下拉输入(In Pull Down)
  GPIO_Mode_IPU = 0x48, // 上拉输入(In Pull Up)
  GPIO_Mode_Out_OD = 0x14, // 开漏输出(Out Open Drain)
  GPIO_Mode_Out_PP = 0x10, // 推挽输出(Out Push Pull)
  GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出(Atl Open Drain)
  GPIO_Mode_AF_PP = 0x18 // 复用推挽输出(Atl Push Pull)
}GPIOMode_TypeDef;

部分API

void GPIO_DeInit(GPIO_TypeDef* GPIOx);  // 复位GPIO外设 ——(参数:GPIOx)
void GPIO_AFIODeInit(void);  // 复位AFIO外设
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);  // 初始化GPIO口(先定义一个结构体变量,再赋值,再调用)
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); // 给结构体变量赋默认值
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // GPIO读取函数
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); // GPIO读取函数
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // GPIO读取函数
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); // GPIO读取函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // GPIO写入函数,将指定端口设置为高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // GPIO写入函数,将指定端口设置为低电平
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); // GPIO写入函数,根据第三个参数值来指定端口
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); // GPIO写入函数 (参数一:选择外设,参数二:对最多16个端口进行写入操作)
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState); //引脚重映射
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); 
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

实验部分

LED和蜂鸣器简介

•LED:发光二极管,正向通电点亮,反向通电不亮

•有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定

•无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音

按键简介

传感器模块简介

代码部分

板子为正点原子精英版V2

延迟函数

直接从B站江科大那里拿的

#include "stm32f10x.h"

/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
    SysTick->LOAD = 72 * xus;                //设置定时器重装值
    SysTick->VAL = 0x00;                 //清空当前计数值
    SysTick->CTRL = 0x00000005;              //设置时钟源为HCLK,启动定时器
    while(!(SysTick->CTRL & 0x00010000));    //等待计数到0
    SysTick->CTRL = 0x00000004;              //关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
    while(xms--)
    {
        Delay_us(1000);
    }
}

/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
    while(xs--)
    {
        Delay_ms(1000);
    }
} 
经典跑马灯
LED模块
#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 时钟初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO口结构体
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置为开漏推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // 对应PIN口
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitTypeDef GPIO_InitStructure2;
    GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOE, &GPIO_InitStructure2);

    GPIO_SetBits(GPIOB, GPIO_Pin_5); // 设置高电平默认关灯
    GPIO_SetBits(GPIOE, GPIO_Pin_5);
}

void LED1_ON(void)
{
    GPIO_ResetBits(GPIOB, GPIO_Pin_5); // 设置低电平开灯
}

void LED1_OFF(void)
{
    GPIO_SetBits(GPIOB, GPIO_Pin_5); // 设置高电平关灯
}

void LED1_Turn(void)
{
    if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5) == 0) // 读取输出数据(0为低电平,1为高电平,等于0即当前为开灯)
    {
        GPIO_SetBits(GPIOB, GPIO_Pin_5);
    }
    else
    {
        GPIO_ResetBits(GPIOB, GPIO_Pin_5);
    }
}

void LED2_ON(void)
{
    GPIO_ResetBits(GPIOE, GPIO_Pin_5);
}

void LED2_OFF(void)
{
    GPIO_SetBits(GPIOE, GPIO_Pin_5);
}

void LED2_Turn(void)
{
    if (GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_5) == 0)
    {
        GPIO_SetBits(GPIOE, GPIO_Pin_5);
    }
    else
    {
        GPIO_ResetBits(GPIOE, GPIO_Pin_5);
    }
}
主函数
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"

int main(void){
    while(1){
        LED1_ON();
        Delay_ms(1000); 
        LED1_OFF();
        Delay_ms(1000);
    }
}
按键控制LED
按键模块
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void Key_Init(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //时钟初始化

    GPIO_InitTypeDef GPIO_InitStructure; //初始化GPIO口
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //采用上拉输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOE,&GPIO_InitStructure);
}

uint8_t Key_GetNum(void){
    uint8_t KeyNum = 0;
    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0){ //按下时判断式子为0,即返回值为1,识别按键1成功(0为低电平,即按下)
        Delay_ms(20); //延迟消抖
        while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0);
        Delay_ms(20);
        KeyNum = 1;
    }
    if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0){ //按下时判断式子为0,即返回值为2,识别按键2成功
        Delay_ms(20);
        while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0);
        Delay_ms(20);
        KeyNum = 2;
    }
    return KeyNum;
}
世界のネズミは彼らが望むものに依存し、彼らは彼ら自身から誰も求めません
最后更新于 2023-08-27