#STM32 GPIO编程详解

硬件环境:stm32f407zet6 软件环境:mdk5

1.GPIO概述

GPIO,翻译为通用输入输出,也就是软件可编程引脚,也就是MCU通过控制GPIO来完成一系列的功能。

GPIO属于引脚,但引脚还包含电源、晶振、下载、boot、复位等,这一部分组成的电路同时也叫做单片机最小系统

同一个GPIO可以作为多种外设功能的引脚,在芯片对应的数据手册中有比较详细的引脚功能说明

在STM32F407中,除了ADC引脚,其他引脚都是可以5V容忍
所谓5V容忍就是可以正常识别5V的逻辑电平信号而不至于因为逻辑电平电压高于自身的3.3V标准而损坏芯片

在STM32中,将GPIO分为多组,每组最多16个,每个GPIO都可以进行输出类型、模式、上下拉、输出速度的配置。

看图
在STM32中所有的GPIO操作均是围绕下图展开的。
#STM32 GPIO编程详解_第1张图片

  1. 输出类型
    输出类型可以分为推挽输出和开漏输出。

    推挽输出
    当输出一个低电平,首先经过反相器变成一个高电平,当为高电平时,NMOS管工作,IO口与地线短接,从而输出低电平,此时电源电流输出到负载,也叫灌电流,可以理解为推
    当输出一个高电平,首先经过反相器变成一个低电平,当为低电平时,PMOS管工作,IO口与VDD短接,从而输出高电平,此时负载电流流入到芯片,也叫拉电流,可以理解为挽
    推挽输出电流驱动能力是很大的,因为MOS管在工作的时候,其内阻非常小,因此VDD输入电流可近似等于IO口输出电流

    开漏输出
    开漏模式下,PMOS管不工作,只能输出低电平,同推完输出,输出高电平时IO口将呈现高组态的状态。

  2. 模式
    可以设置为输入、输出、复用、模拟四种工作模式
    输入模式下,TTL施密特触发器工作,本质就是将引脚上电压转换成开关量,当电压低于一个值判断为逻辑0,高于一个值判断为逻辑1.
    模拟模式分为输入和输出模式,分别工作在ADC采集和DAC输出的时候,配置为此模式时外设引脚直接连接到对应的模拟线路上
    输出电平可以通过设置数据寄存器来控制,也可以用过置位复位寄存器控制,后者的优势在于不用考虑当前寄存器的值

  3. 上下拉
    可以选择是否启用上下拉电阻,比如开漏模式下需要输出高电平,则需要外接上拉电阻来实现

  4. 输出速度
    可以设置为 2M、25M、50M、100M(30 pF 时为 100 MHz(高速)(15 pF 时为 80 MHz 输出(最大速度)))。
    100M输出速度是什么意思?
    对于CMOS工艺的集成电路而言,输入阻抗是非常高的,主要功耗来自于绝缘栅等效的电容充放电效应。既然是电容的充放电,考虑信号源的内阻(基于标准CMOS电路的输出),根据RC充电常数和逻辑门限电平就能得出一个最小周期,其对应一个最高IO频率。

2.GPIO寄存器分析

直接看数据手册不就好了嘛,干嘛要抄一遍,费时费力又没有什么意义

3.GPIO编程实例

以标准的LED控制程序为例

  1. 固件库
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);						//开启GPIOF的时钟
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;								//设置为输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;								//设置为推挽输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;								//设置为上拉模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;							//设置输出速度为100M
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_Init(GPIOF, &GPIO_InitStructure);	
    
  2. BB库
    //定义LED
    typedef enum
    {
    	LED1 = 0,
    	LED2
    } LEDx_t;
    
    //LED状态
    typedef enum
    {
    	LED_OFF = 0,
    	LED_ON
    } LED_Status_t;
    
    //LED引脚
    typedef enum
    {
    	LED1_PIN = BB_GPIO_PIN_9,
    	LED2_PIN = BB_GPIO_PIN_10
    } LED_Pin_t;
    
    //定义GPIO引脚
    typedef enum
    {
    	BB_GPIO_PIN_0 = 0,
    	BB_GPIO_PIN_1,
    	BB_GPIO_PIN_2,
    	BB_GPIO_PIN_3,
    	BB_GPIO_PIN_4,
    	BB_GPIO_PIN_5,
    	BB_GPIO_PIN_6,
    	BB_GPIO_PIN_7,
    	BB_GPIO_PIN_8,
    	BB_GPIO_PIN_9,
    	BB_GPIO_PIN_10,
    	BB_GPIO_PIN_11,
    	BB_GPIO_PIN_12,
    	BB_GPIO_PIN_13,
    	BB_GPIO_PIN_14,
    	BB_GPIO_PIN_15
    } BB_GPIO_Pin_t;
    
    BB_RCC_AHB1_PeriphClock_Enable(RCC_AHB1Periph_GPIOF);						//开启GPIOF的时钟
    
    BB_GPIO_Mode(GPIOF, (BB_GPIO_Pin_t)LED1_PIN, GPIO_Mode_OUT); 				//设置为输出模式
    BB_GPIO_OType(GPIOF, (BB_GPIO_Pin_t)LED1_PIN, GPIO_OType_PP);				//设置为推挽输出
    BB_GPIO_Speed(GPIOF, (BB_GPIO_Pin_t)LED1_PIN, GPIO_Speed_100MHz);			//设置输出速度为100M
    BB_GPIO_PuPd(GPIOF, (BB_GPIO_Pin_t)LED1_PIN, GPIO_PuPd_UP);					//设置为上拉模式
    
    BB_GPIO_Mode(GPIOF, (BB_GPIO_Pin_t)LED2_PIN, GPIO_Mode_OUT); 
    BB_GPIO_OType(GPIOF, (BB_GPIO_Pin_t)LED2_PIN, GPIO_OType_PP);
    BB_GPIO_Speed(GPIOF, (BB_GPIO_Pin_t)LED2_PIN, GPIO_Speed_100MHz);
    BB_GPIO_PuPd(GPIOF, (BB_GPIO_Pin_t)LED2_PIN, GPIO_PuPd_UP);
    
    BB_GPIO_SetBits(GPIOF, (BB_GPIO_Pin_t)LED1_PIN);							//默认熄灭LED
    BB_GPIO_SetBits(GPIOF, (BB_GPIO_Pin_t)LED2_PIN);
    

你可能感兴趣的:(#,STM32)