• STM32 GPIO详细篇(基于HAL库)


    一、基础认识

    GPIO全名为General Purpose Input Output,即通用输入输出。有时候简称为“IO口”。通用,说明它是常见的。输入输出,就是说既能当输入口使用,又能当输出口使用。端口,就是元器件上的一个引脚。

    输入模式和输出模式是GPIO的基本特性,当然GPIO还有其它模式可选。

    (一) IO耐压问题

    STM32是一款3.3V电压的芯片,IO输出是3.3V,但IO大部分都是可以容忍5V电压输入。一般在芯片手册的“引脚定义”章节可以查看到有FT标识表示该IO可以容忍5V电压输入。

    二、在标准库中GPIO的模式

    (一)模式汇总

    输入模式:

    l  浮空输入(GPIO_Mode_IN_FLOATING):引脚电平是真实的外部连接器件电压,电平有不确定性

    l  上拉输入 (GPIO_Mode_IPU):默认通过电阻上拉到VCC,不接外部器件时可以读出高电平

    l  下拉输入 (GPIO_Mode_IPD):默认通过电阻下拉到GND,不接外部器件时可以读出低电平

    l  模拟输入 (GPIO_Mode_AIN):将外部信号直接传输到数模转换通道上

    输出模式:

    l  开漏输出(GPIO_Mode_Out_OD):只能输出低电平,高电平由电阻上拉决定

    l  开漏复用功能(GPIO_Mode_AF_OD):用于外设功能使用

    l  推挽式输出(GPIO_Mode_Out_PP):可以输出强高和强低,通常使用该功能控制LED

    l  推挽式复用功能(GPIO_Mode_AF_PP):用于外设功能使用

    GPIO的基本结构:

    TTL肖特基触发器其实可以理解为用肖特基管构成的施密特触发器,作用简单说就是将相对缓慢变化的模拟信号变成矩形(方波)信号,便于后面读取。这里有一个阈值电压的概念,比如从低到高达到多少才会导通,从高到底多少才会关闭。

    (二)   浮空输入(GPIO_Mode_IN_FLOATING)

    浮空就是逻辑器件与引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构和外部引脚所接的器件决定电平状态。一般实际运用时,引脚不建议悬空,易受干扰。通俗讲就是浮空就是浮在空中,就相当于此端口在默认情况下什么都不接,呈高阻态,这种设置在数据传输时用的比较多。浮空最大的特点就是电压的不确定性,它可能是0V,页可能是VCC,还可能是介于两者之间的某个值(最有可能) 浮空一般用来做ADC输入用,这样可以减少上下拉电阻对结果的影响。

    (三)  上拉输入 (GPIO_Mode_IPU)

    上拉就是把点位拉高,比如拉到Vcc。上拉就是将不确定的信号通过一个电阻嵌位在高电平。电阻同时起到限流的作用。弱强只是上拉电阻的阻值不同,没有什么严格区分。

    电阻通常为30-50KΩ

    (四) 下拉输入 (GPIO_Mode_IPD)

    下拉就是把点位拉低,比如拉到GND。下拉就是将不确定的信号通过一个电阻嵌位在低电平。电阻同时起到限流的作用。弱强只是下拉电阻的阻值不同,没有什么严格区分

    (五) 模拟输入 (GPIO_Mode_AIN)

    模拟输入是指传统方式的输入,数字输入是输入PCM数字信号,即0,1的二进制数字信号,通过数模转换,转换成模拟信号,经前级放大进入功率放大器,功率放大器还是模拟的

    (六)  开漏输出(GPIO_Mode_Out_OD)

    IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能。

    只能输出强低电平。

    (七) 开漏复用功能(GPIO_Mode_AF_OD)

    用于外设使用

    (八)推挽式输出(GPIO_Mode_Out_PP)

    IO输出0-接GND, IO输出1 -接VCC。这是使用最多的了。控制LED基本都是使用这种模式。

    可以输出强高低电平,连接外部数字器件

    (九)推挽式复用功能(GPIO_Mode_AF_PP)

    用于外设使用

    三、配置输入输出IO

    (一)输入

    (1).   GPIO Pull-up/Pull-down:

    IO上下拉配置

    l  No pull-up and no pull-down,浮空输入,配置为不上拉和下拉

    l  Pull-up,上拉输入

    l  Pull-down,下拉输入

    (二)输出

    (1).   GPIO output level

    l  Low:IO初始化默认输出低电平

    l  High:IO初始化默认输出高电平

    (2).   GPIO mode

    l  Output Open Drain,开漏输出,可以输出低电平

    l  Output Push Pull,推挽输出,可以输出低电平和高电平 

    (3).   GPIO Pull-up/Pull-down:

    IO上下拉配置

    l  No pull-up and no pull-down,浮空输入,配置为不上拉和下拉

    l  Pull-up,上拉输入

    l  Pull-down,下拉输入

    (4).   Maximum output speed

    l  Low,GPIO速度为低速,通常为2MHZ

    l  Medium,GPIO速度为中速,通常为10MHZ

    l  High,GPIO速度为高速,通常为50MHZ

    四、 输出编程

    测试有GPIOA1和GPIOA2设置为输出测试

    (一)CubeMx设置

     

    (二) 初始化函数

    宏定义

    #define DONG_OUT_1_Pin GPIO_PIN_1
    #define DONG_OUT_1_GPIO_Port GPIOA
    #define DONG_OUT_2_Pin GPIO_PIN_2
    #define DONG_OUT_2_GPIO_Port GPIOA

    初始化函数是自动生成的

    void MX_GPIO_Init(void)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA时钟
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//设置上电电平为低
    
      /*Configure GPIO pins : PAPin PAPin */
      GPIO_InitStruct.Pin = DONG_OUT_1_Pin|DONG_OUT_2_Pin;//两个GPIO_PIN
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出模式
      GPIO_InitStruct.Pull = GPIO_NOPULL;//浮空,不上拉也不下拉
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//低速
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }

    (三)输出相关函数

    设置或清除选定的数据端口位

    void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

    参数:

    GPIOx :其中x可以(A..G取决于所使用的设备)来选择GPIO外设

    GPIO_Pin :指定要写入的端口位。此参数可以是GPIO_PIN_x之一,其中x可以是( 0..15 )

    PinState :指定要写入选定位的值。此参数可以是GPIO_PinState枚举值之一:

    l  GPIO_PIN_RESET:清除端口Pin,低电平

    l  GPIO_PIN_SET:设置端口Pin,高电平

    例子:

    HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//两个设置为低电平
    HAL_Delay(1000);//1s
    HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin, GPIO_PIN_SET);//单独设置为高电平
    HAL_GPIO_WritePin(GPIOA,DONG_OUT_2_Pin, GPIO_PIN_SET);//单独设置为高电平
    HAL_Delay(1000);//1s

    切换指定的GPIO pin

    void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

    参数:

    GPIOx :其中x可以(A..G取决于所使用的设备)来选择GPIO外设

    GPIO_Pin :指定要写入的端口位。此参数可以是GPIO_PIN_x之一,其中x可以是(0..15 )

    例子:

    HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin);//两个输出电平取反
    HAL_Delay(1000);//1s
    HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin);//单独输出电平取反
    HAL_GPIO_TogglePin(GPIOA,DONG_OUT_2_Pin);//单独输出电平取反
    HAL_Delay(1000);//1s

    五、输入编程(轮询检测)

    (一)CubeMX设置

     (二)初始化函数

    宏定义

    #define DONG_IN_1_Pin GPIO_PIN_3
    #define DONG_IN_1_GPIO_Port GPIOA

    初始化部分

    GPIO_InitTypeDef GPIO_InitStruct = {0};//初始化结构体
    __HAL_RCC_GPIOA_CLK_ENABLE();//GPIO时钟开启
    GPIO_InitStruct.Pin = DONG_IN_1_Pin;//引脚
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//输入模式
    GPIO_InitStruct.Pull = GPIO_PULLUP;//上拉
    HAL_GPIO_Init(DONG_IN_1_GPIO_Port, &GPIO_InitStruct);

    (三)输入相关函数

    读取指定的输入端口引脚

    GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

    参数:

    GPIOx :其中x可以(A..G取决于所使用的设备)来选择GPIO外设

    GPIO_Pin :指定要写入的端口位。此参数可以是GPIO_PIN_x之一,其中x可以是(0..15 )

    返回:

    typedef enum
    {
      GPIO_PIN_RESET = 0u,//低电平
      GPIO_PIN_SET//高电平
    } GPIO_PinState;

    例子:

    GPIO_PinState res=HAL_GPIO_ReadPin(DONG_IN_1_GPIO_Port,DONG_IN_1_Pin);//读取电平
    if(res==GPIO_PIN_RESET){
         HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_SET);//两个设置为高电平
    }else{
         HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//两个设置为低电平
    }

    六、输入编程(中断检测)

    (一)CubeMX设置

     

    GPIO mode:

    l  上升沿触发检测的外部中断模式(External Interrupt Mode with Rising edge trigger detection)

    l  下降沿触发检测的外部中断模式(External Interrupt Mode with Falling edge trigger detectiort)

    l  上升/下降沿触发检测的外部中断模式(External Interrupt Mode with Risinq/Falling edge trigger detection)

    l  上升沿触发检测的外部事件模式(External Event Mode with Rising edge trigger detection)

    l  下降沿触发检测的外部事件模式(External Event Mode with Falling edge trigger detection)

    l  上升/下降沿触发检测的外部事件模式(External Event Mode with Rising/Falling edge trigger detectiont)

    中断和事件的区别:

    l  中断是当IO达到中断条件后会向CPU产生中断请求

    l  事件是事先设置好的任务,当单片机达到要求将通过硬件的方式处理事先设置好的任务,而不向CPU请求中断,比如DMAAD转换等

    (二)初始化函数

    宏定义

    #define KEY1_Pin GPIO_PIN_3
    #define KEY1_GPIO_Port GPIOA
    #define KEY1_EXTI_IRQn EXTI3_IRQn

    初始化部分

    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    /*Configure GPIO pin : PtPin */
    GPIO_InitStruct.Pin = KEY1_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
    /* EXTI interrupt init*/
    HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI3_IRQn);

    (三)中断输入相关函数

    中断回调函数

    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

    参数:

    GPIO_Pin :指定连接EXTI线的引脚

    例子:

    //GPIO中断回调函数
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
    //判断进入中断的GPIOs
    if(KEY1_Pin==GPIO_Pin){
                HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin);//单独输出电平取反
                HAL_GPIO_TogglePin(GPIOA,DONG_OUT_2_Pin);//单独输出电平取反
         }
    }

    其它

    关于按键防抖的问题:

    l  软件防抖可以检测到电平延时一段时间再确认电平,延时时间一般为10-20ms

    l  硬件防抖可以在按键上并联一个电容,一般为0.1uf


     参考:

    https://blog.csdn.net/baidu_37366055/article/details/80060962

  • 相关阅读:
    How to provide highlighting with Spring data elasticsearch
    Android——仿QQ聊天撒花特效
    Android 仿新版QQ的tab下面拖拽标记为已读的效果
    GitHub控件之BadgeView(数字提醒)
    Android之基于百度云推送IM
    Android消息推送完美解决方案全析
    android asmack 注册 登陆 聊天 多人聊天室 文件传输
    android:TextAppearance.Material.Widget.Button.Inverse问题
    Android 高仿微信实时聊天 基于百度云推送
    Gradle DSL method not found: 'android()
  • 原文地址:https://www.cnblogs.com/dongxiaodong/p/14128088.html
Copyright © 2020-2023  润新知