STM32学习笔记——GPIO

GPIO——General Purpose Input Output——通用输入输出出口

特点:通用性、快速翻转、中断支持、支持多种工作模式。

8种输入输出模式

模式 性质 特征 应用 标识

浮空输入

数字输入

可读取引脚电平,若引脚悬空,则电平不确定

适用于需要读取外部信号的场景,但外部信号状态不确定。

GPIO_Mode_IN_FLOATING

上拉输入

数字输入

可读取引脚电平,内部连接上拉电阻,悬空时默认高电平

用于外部信号默认为高电平的情况,如按钮按下时会拉低信号。

GPIO_Mode_IPU

下拉输入

数字输入

可读取引脚电平,内部连接下拉电阻,悬空时默认低电平

适用于外部信号默认为低电平的情况,如按钮按下时会拉高信号。

GPIO_Mode_IPD

模拟输入

模拟输入

GPIO无效,引脚直接接入内部ADC

适用于需要进行模拟信号处理的场景。

GPIO_Mode_AIN

开漏输出 数字输出

可输出引脚电平,高电平为高阻态,低电平接VSS

适用于需要多个输出端口共享同一信号线的场景,例如I2C的SDA、SCL线。

GPIO_Mode_Out_OD

推挽输出 数字输出

可输出引脚电平,高电平接VDD,低电平接VSS

适用于需要输出到外部设备,需要较大驱动能力的场景。

GPIO_Mode_Out_PP

复用开漏输出 数字输出

由片上外设控制,高电平为高阻态,低电平接VSS

适用于需要实现外设功能,同时共享信号线的场景,例如硬件I2C的SDA、SCL线

GPIO_Mode_AF_OD

复用推挽输出 数字输出 由片上外设控制,高电平接VDD,低电平接VSS 适用于需要实现外设功能,同时需要提供较大驱动能力的场景,例如SPI的SCK、MISO、MOSI线。 GPIO_Mode_AF_PP

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

GPIO的库函数位置

 

 
函数 解释
void GPIO_DeInit(GPIO_TypeDef* GPIOx) gpio的反初始化函数,该函数的作用是把GPIO相关的寄存器配置成上电复位后的默认状态,在第一次初始化前或者不在使用某一接口后,可以调用该函数。
void GPIO_AFIODeInit(void) 外设映射设置恢复为默认状态,以重新初始化外设映射配置。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)  GPIO的初始化函数,该函数的作用是对io进行初始化。
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)  GPIO结构体的初始化。对GPIO_InitStruct结构体进行默认配置。
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)  读取io输入管脚的值
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) 读取输入io数据,该函数用于读取一个io分组的所有数据
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 读取io输出管脚的值
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)  读取输出io数据,该函数用于读取一个io分组的所有数据
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 对io管脚进行置位(输出高电平)
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 对io管脚进行复位(输出低电平)
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) 对某一位进行写入操作。
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) 对GPIO端口进行写入操作,适用于对统一端口的多个管脚的写入。
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 锁定GPIO寄存器,锁定的寄存器是GPIOx_MODER,   GPIOx_OTYPER,    GPIOx_OSPEEDR,   GPIOx_PUPDR,    GPIOx_AFRL    and    GPIOx_AFRH。在下一次复位前,被锁定的管脚不能被修改。
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) 配置GPIO引脚作为事件输出,用于特定的事件通知机制。

void GPIO_EventOutputCmd(FunctionalState NewState)

启用或禁用GPIO事件输出功能。
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState) 重新映射指定引脚,以实现不同的引脚功能。(重映射和IO口的复用一样,需要开启AFIO的时钟。)
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) 配置外部中断线的GPIO端口和引脚。
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) 配置以太网介质接口。

 

 

通用外设驱动模型:

初始化→读函数→写函数→设置中断

初始化(常用):

void __GPIO_Init(void){            
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    //RCC_APB2Periph_GPIOB-》这里选择的是STM上的B0和B10,所以是GPIOB   ENABLE-》使能
    GPIO_InitTypeDef GPIO_InitStructure;                    //定义结构体
    GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU;            //输入模式
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_10;//端口 可同时定义多个
    GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;        //选择速率
    GPIO_Init(GPIOB,&GPIO_InitStructure);                    //初始化
}

STM32按键控制开关灯实例:

LED灯的配置

#include "stm32f10x.h"

void LED_Init(void){
    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_Pin_2 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //初始化GPIOA口的PA0、PA2、PA5端口,设置推挽输出
    GPIO_SetBits(GPIOA,GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_5);
    //PA0、PA2、PA5端口输出高电平
}

void LED1_ON(void){
    GPIO_ResetBits(GPIOA,GPIO_Pin_0);
}
void LED1_OFF(void){
    GPIO_SetBits(GPIOA,GPIO_Pin_0);
}
void LED2_ON(void){
    GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
void LED2_OFF(void){
    GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
void LED3_ON(void){
    GPIO_ResetBits(GPIOA,GPIO_Pin_5);
}
void LED3_OFF(void){
    GPIO_SetBits(GPIOA,GPIO_Pin_5);
}
//3个LED开关灯操作,低电平点亮,高电平熄灭


void LED1_Turn(void){
    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 0){
        GPIO_SetBits(GPIOA,GPIO_Pin_0);
    }else{
        GPIO_ResetBits(GPIOA,GPIO_Pin_0);
    }
}
//读取PA0端口的LED状态,进行翻转操作

void LED2_Turn(void){
    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0){
        GPIO_SetBits(GPIOA,GPIO_Pin_2);
    }else{
        GPIO_ResetBits(GPIOA,GPIO_Pin_2);
    }
}
//读取PA2端口的LED状态,进行翻转操作

void LED3_Turn(void){
    if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0){
        GPIO_SetBits(GPIOA,GPIO_Pin_5);
    }else{
        GPIO_ResetBits(GPIOA,GPIO_Pin_5);
    }
}
//读取PA5端口的LED状态,进行翻转操作

开关的配置

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void Key_Init(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    //初始化PB0和PB10端口,分别连接了两个开关,使用上拉输入模式
}


uint8_t Key_GetNum(void){
    uint8_t KeyNum = 0;
    
    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0){            //读取PB0端口数据判断是否为0(低电平)
        Delay_ms(20);                                        //延时过滤
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0);    //当为0时跳出循环
        Delay_ms(20);                                        //延时过滤
        KeyNum = 1;                                            //标志位置1
    }

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0){
        Delay_ms(20);
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0);
        Delay_ms(20);
        KeyNum = 2;
    }
    
    return KeyNum;                                            //返回标志位
}

主函数

#include "stm32f10x.h"
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;

int main(void)
{
    LED_Init();        //灯初始化
    Key_Init();        //开关初始化
    
    while(1){
        KeyNum = Key_GetNum();    //获取标志位
        
        if(KeyNum == 1){        
            LED1_Turn();
        }
        if(KeyNum == 2){
            LED2_Turn();
            LED3_Turn();
        }
                                //标志位为1时,翻转LED1,为2时翻转LED2和LED3
    }
}
posted @ 2024-09-06 13:29  菠菜面筋  阅读(52)  评论(0编辑  收藏  举报