STM32的GPIO口的几种输入输出模式的区别和适用场合,有详细的解说吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32的GPIO口的几种输入输出模式的区别和适用场合,有详细的解说吗相关的知识,希望对你有一定的参考价值。

参考技术A STM32的GPIO口的几种输入输出模式的区别和适用场合
输出模式只有4种哦,另外4种是输入模式,这个问题很常见:
下面是引用文字:
(1)
浮空输入_IN_FLOATING
——浮空输入,可以做KEY识别,RX1
(2)带上拉输入_IPU——IO内部上拉电阻输入
(3)带下拉输入_IPD——
IO内部下拉电阻输入
(4)
模拟输入_AIN
——应用ADC模拟输入,或者低功耗下省电
(5)开漏输出_OUT_OD
——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能
(6)推挽输出_OUT_PP
——IO输出0-接GND,
IO输出1
-接VCC,读输入值是未知的
(7)复用功能的推挽输出_AF_PP
——片内外设功能(I2C的SCL,SDA)
(8)复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS)
通俗的说,输出模式就2种,开漏和推挽,我通俗的说下这两种方式
推挽:当IO口输出高电平时,相当于供电电源上(一般为3.3V)通过三极管或MOS管接到了IO口上;同理,当IO口输出低电平时,相当于IO口通过三极管或MOS管接到了GND上面。
开漏,就是当IO口输出低电平时,相当于IO口通过三极管或MOS管接到了GND上面;当IO口输出高电平时,此引脚内部悬空。

stm32寄存器版学习笔记01 GPIO口的配置(LED按键)

  STM32的I/O口可以由软件配置成如下8种模式:输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽输出、推挽式复用功能及开漏复用功能。每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CRL和CRH(模式、速度);数据寄存器IDR和ODR;置位/复位寄存器BSRR;复位寄存器BRR;锁存寄存器LCKR。

 

I/O口模式:

GPIO的8种模式
通用输出 推挽输出(Push-Pull) 可以输出高、低电平,连接数字器件  
开漏输出(Open-Drain) 开漏引脚不连接外部的上拉电阻时,只能输出低电平;如果需要同时具备输出高电平的功能,则需要接上拉电阻  
复用功能输出 复用功能推挽输出 片内外设功能(I2C的SCL,SDA) GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)
复用功能开漏输出 片内外设功能(TX1,MOSI,MISO,SCK,SS)
输入 模拟输入 应用ADC模拟输入,或者低功耗下省电  
浮空输入 可以做KEY识别,外部按键输入 IO的电平状态是不确定,完全由外部输入决定
下拉输入 IO内部下拉电阻输入 不确定信号->低电平
上拉输入 IO内部上拉电阻输入 不确定信号->高电平

 

  

 



 

 

 

 

 

 

 

1.GPIO口配置步骤

①使能PORTx(x=A~G)

  APB2外设时钟使能寄存器(RCC_APB2ENR)

置1开启。清0关闭。

8-2位使能GPIO G-A

  Eg:RCC->APB2ENR| = 1 << 2;  //使能PORTA时钟

②配置IO口模式 低8位(CRL) 高8位(CRH)

  端口配置低寄存器(GPIOx_CRL) (x=A..E)

  Eg:GPIOA->CRL |= 0x00000003;  //PA0推挽输出

③配置端口输入和输出电平

  端口输入数据寄存器(GPIOx_IDR) (x=A..E)

 

  端口输出数据寄存器(GPIOx_ODR) (x=A..E)

Eg: GPIOA->ODR |= 1 <<8;  //PA8输出高

 

2.GPIO配置相关寄存器

  端口位设置/清除寄存器(GPIOx_BSRR) (x=A..E)

ODR寄存器只进行置1操作,不支持写0操作。用BSRR寄存器进行清除。

 

  端口位清除寄存器(GPIOx_BRR) (x=A..E)

 

  端口位清除寄存器(GPIOx_BRR) (x=A..E)  具体参看数据手册

  当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。 每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。

 

3.LED

//led.c                    
//LED IO口初始化
void LED_Init(void)
{
    RCC->APB2ENR|=1<<2;      //使能PORTA时钟        
    RCC->APB2ENR|=1<<5;      //使能PORTD时钟         
    GPIOA->CRH&=0XFFFFFFF0; 
    GPIOA->CRH|=0X00000003;//PA8推挽输出     
  GPIOA->ODR|=1<<8;                //PA8输出高
                                              
    GPIOD->CRL&=0XFFFFF0FF;
    GPIOD->CRL|=0X00000300;//PD2推挽输出
    GPIOD->ODR|=1<<2;         //PD2输出高
}

//led.h
#ifndef __LED_H
#define __LED_H     
#include "sys.h"

//LED端口定义
#define LED0 PAout(8)    // PA8
#define LED1 PDout(2)    // PD2    

void LED_Init(void);    //初始化                         
#endif 

//main.c
#include "sys.h"
#include "usart.h"        
#include "delay.h"    
#include "led.h" 
int main(void)
{         
    Stm32_Clock_Init(9); //系统时钟设置
    delay_init(72);             //延时初始化
    LED_Init();        //初始化与LED连接的硬件接口
    while(1)
    {
        LED0=0;
        LED1=1;
        delay_ms(300);
        LED0=1;
        LED1=0;
        delay_ms(300);
    }     
}

 

4.按键KEY输入

//key.c
#include "key.h"
#include "delay.h"
//按键初始化函数
//PA0 PA15 PC5设置成输入
void KEY_Init(void)
{
    RCC->APB2ENR|=1<<2;     //使能PORTA时钟
    RCC->APB2ENR|=1<<4;     //使能PORTC时钟
    JTAG_Set(SWD_ENABLE);    //关闭JTAG 开启SWD PA15占用了JTAG一个口
    GPIOA->CRL&=0XFFFFFFF0;    //PA0设置成输入  
    GPIOA->CRL|=0X00000008;   
    GPIOA->CRH&=0X0FFFFFFF;    //PA15设置成输入
    GPIOA->CRH|=0X80000000;              
    GPIOA->ODR|=1<<15;           //PA15上拉 PA0默认下拉
    GPIOC->CRL&=0XFF0FFFFF;    //PC5设置成输入  
    GPIOC->CRL|=0X00800000;   
    GPIOC->ODR|=1<<5;           //PC5上拉
} 
//按键处理函数
//mode:0不支持连续按;1,支持连续按
//响应优先级KEY0>KEY1>WK_UP
u8 KEY_Scan(u8 mode)
{     
    static u8 key_up=1;//按键按松开标志
    if(mode)key_up=1;  //支持连按      
    if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
    {
        delay_ms(10);//去抖动
        key_up=0;
        if(KEY0==0)
                    return KEY0_PRES;
        else if(KEY1==0)
                    return KEY1_PRES;
        else if(WK_UP==1)
                    return WKUP_PRES; 
    }else if(KEY0==1&&KEY1==1&&WK_UP==0)
            key_up=1;          
    return 0;// 无按键按下
}

//key.h
#ifndef __KEY_H
#define __KEY_H     
#include "sys.h"

#define KEY0_PRES    1        //KEY0按下
#define KEY1_PRES    2        //KEY1按下
#define WKUP_PRES    3        //WK_UP按下

#define KEY0  PCin(5)          //PC5
#define KEY1  PAin(15)         //PA15 
#define WK_UP PAin(0)          //PA0  WK_UP
     
void KEY_Init(void);        
u8 KEY_Scan(u8 mode);        
#endif

//main.c
#include "sys.h"
#include "usart.h"        
#include "delay.h"    
#include "led.h" 
#include "key.h" 

int main(void)
{         
    u8 t;      
    Stm32_Clock_Init(9);     
    delay_init(72);            
    LED_Init();                   
    KEY_Init();          
    LED0 = 0;                    
    while(1)
    {
        t=KEY_Scan(0);        
        switch(t)
        {                 
            case KEY0_PRES:
                LED0=!LED0;
                break;
            case KEY1_PRES:
                LED1=!LED1;
                break;
            case WKUP_PRES:                
                LED0=!LED0;
                LED1=!LED1;
                break;
            default:
                delay_ms(10);    
        } 
    }         
}

                    

 

以上是关于STM32的GPIO口的几种输入输出模式的区别和适用场合,有详细的解说吗的主要内容,如果未能解决你的问题,请参考以下文章

stm32中GPIO口的最大输出速度如何理解?

STM32的GPIO口的复用功能

stm32寄存器版学习笔记01 GPIO口的配置(LED按键)

STM32--GPIO口的八种工作模式

如何实现gpio口模式的配置?

stm32如何判读输入IO口的高低电平