stm32入门——GPIO工作原理

前言

本文内容基于整点原子mini也就是STM32F103RCT6这块芯片进行入门,在本文中笔者将详细介绍GPIO的八种工作方式以及对应寄存器的内容和操作方法。

一、GPIO基本结构和工作方式

1.1 GPIO基本结构

STM32F103RCT6

  • 一共有4组IO口
  • 一共16*3+3=51个IO

GPIOA0~A15

GPIOB0~B15

GPIOC0~C15

GPIOD0~D2

每个GPIO端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。 根据每个I/O端口的特定硬件特征, GPIO端口的每个位可以由软件分别配置成多种模式。

—— 输入浮空

—— 输入上拉

—— 输入下拉

—— 模拟输入

—— 开漏输出

—— 推挽式输出

—— 推挽式复用功能

—— 开漏复用功能

另外当GPIO进行输出操作时引脚的输频率包括三种最大翻转速度。

—— 2MHz

—— 10MHz

—— 50MHz    

每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。 下图给出了一个I/O端口位的基本结构。

图1 I/O端口位的基本结构 

STM32的IO口,绝大部分是兼容5V的,引脚描述(pin definitions)带有FT标志的IO口,都是兼容5V的。

1.2 GPIO工作模式

1.2.1 输入浮空模式 (GPIO_Mode_IN_FLOATING)

电流从IO端口输出到内部MCU,中间经过TTL施密特触发器以及输入数据寄存器。该输入不接高电平也不接低电平。一般实际使用时引脚不建议悬空,异受干扰。

浮空最大的特点就是电压的不确定性,它可能是0V,也可能是VCC,还可能是介于两者之间的某个值(最有可能)。浮空一般用来做ADC输入用,这样可以减少上下拉电阻对结果的影响。由于其输入阻抗比较大,一般把这种模式用于标准的通讯协议,比如IIC、USART等。

1.2.2 输入上拉模式 (GPIO_Mode_IPU)

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

电流输入路径与输入浮空模式相同,区别在于经过TTL施密特触发器之前接上拉电阻,从上图也可看出输入上拉就是直接从IO端口进来,通过上拉电阻将点平拉高,再经过施密特触发器转换成0、1信号,读取此时的引脚电平为高电平,然后就输入到数据寄存器里。

1.2.3 输入下拉模式

输入下拉:将电压拉到GND。

 输入路径与上拉相同。

1.2.4 模拟输入 (GPIO_Mode_AIN)

模拟输入是指传统方式的输入,数字输入是输入PCM数字信号,即0,1的二进制数字信号,通过数模转换,转换成模拟信号。不经过施密特触发器,也不需要上拉下拉电阻。模拟输入时电压为0~3.3V,同时施密特触发器截止。

 1.2.5 开漏输出 (GPIO_Mode_Out_OD)

开漏是用来兼容不同电平的器件用的,为了方便理解开漏输出,我们先看一个三极管电路图。

 在这里插入图片描述

当Vin没有电流,Q5断开时,LED亮。当Vin流入电流,Q5导通时,LED灭。

所以开漏输出就是通过控制我们内部输出的高低(0或者1)来控制外部电阻是否接地。

开漏引脚在其下方连接了一个n型mos管(GND),同时后面接输出控制电路,由MCU输出高低电平控制n型mos管截止或导通。正常情况下只能输出低电平,但外接vcc连上拉电阻就能输出高电平,当mos管导通,vcc被GND拉低,GPIO输出低电平,反之输出高电平,由于此时电平强弱由vcc决定,这样就实现了电平转换的效果。

写入路径经过的两个寄存器分别是位设置/清除寄存器(BSRR)和输出数据寄存器(ODR)。

1.2.6 开漏复用输出模式 (GPIO_Mode_AF_OD)

 与开漏输出不同的地方在于这里将输出控制电路的信号来源从MCU输出变为来自片上外设模块,即复用功能输出。

1.2.7 推挽输出 (GPIO_Mode_Out_PP)

 推挽输出可以输出高,低电平,连接数字器件,推挽结构一般是两个三极管分别收到互补信号的控制,总是在一个三极管导通的时候另一个截止,高低电平由IC的电源决定,下面是推挽输出的原理图。

在这里插入图片描述

当内部有电源为V+的时候,上方三极管导通,电流从上到下流动,并提供给负载,这就是推。

 在这里插入图片描述

 当内部有电源为V-的时候,下方三极管导通,电流从上到下流动,并提供给负载,这就是挽。

这里推挽输出利用npMOS管实现电平的拉高和拉低,由MCU输出电平到输出控制电路来决定,输出高电平就是直接接我们的单片机到VDD(3.3V),输出低电平就是直接接单片机到VSS(0V),最直接的输出方式,让“输出控制”变为了VDD/VSS输出,使得输出电流增大,提高了输出引脚的驱动能力,提高了电路的负载能力和开关的动作速度。

1.2.8 推挽复用输出模式

复用推挽输出的电平来源不是输出寄存器而改为了片上外设的复用功能输出,芯片内外设功能(I2C、SCL、SDA)。

1.3 GPIO工作方式

推挽输出:

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

开漏输出:

只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。

二、GPIO寄存器说明

每组GPIO端口的寄存器包括:

两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),

两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),

一个32位置位/复位寄存器(GPIOx_BSRR),

一个16位复位寄存器(GPIOx_BRR),

一个32位锁定寄存器(GPIOx_LCKR)。

每个I/O端口位可以自由编程,然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)。

2.1 GPIO相关配置寄存器

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

表1 端口位配置

 ​​​​​

表2 输出模式位

 

表3 寄存器结构表

复位期间和刚复位后,复用功能未开启,I/O端口被配置成浮空输入模式(CNFx[1:0]=01, MODEx[1:0]=00)。

2.1.2 端口配置高寄存器(GPIO_CRH)

表4 寄存器结构表

 端口配置高寄存器与低寄存器基本一致,区别在于寄存器位对应下标不同,高寄存器GPIO位为8~15。

2.1.3 端口输入数据寄存器(GPIOx_IDR)

表5 寄存器结构表

 每组GPIO共有16位IO口,对应表上每个位的位置,当某个位为0或为1时,说明当前该IO口输入的值对应为0或1。

2.1.4 端口输出数据寄存器(GPIOx_ODR)

表6 寄存器结构表

表7 寄存器配置表

GPIO在输入模式下,它的上拉或下拉取决于ODR寄存器的最低位取值即ODR0。

反之GPIO在输出模式下,它输出的电平同样取决于该寄存器的取值。

2.1.5 端口位设置/清除寄存器(GPIOx_BSRR)

表8 寄存器配置表

 BSRR的低16位,对应位设置为1,IO口输出高电平,对应位为0,不产生任何影响;高16位作用相反。

下面通过开漏输出模式的原理图来讲解BSRR的作用。

在原理图中MCU的输出可以通过BSRR和片上外设,BSRR能够直接控制ODR输出值,而通过片上外设则能够直接设置ODR寄存器。

 设置BSRR寄存器的好处在于能够单独的设置每一个IO口的值,例如对低16位进行赋值则可以直接将需要的位设为1其余位设置为0即可,高16位作用相反。

2.1.6 端口位清除寄存器(GPIOx_BRR)

表9 寄存器配置表

 

 BRR寄存器的作用类似BSRR,相当于BSRR的低16位。

三、STM32F10x GPIO引脚说明

  • 端口复用功能

STM32的大部分端口都具有复用功能。

所谓复用,即使一些短裤不仅仅可以作为通用IO口,还可以复用位一些外设引脚,详细引脚复用细节见技术手册,复用的作用是最大限度的利用端口资源

  • 端口重映射功能

就是可以把某些功能引脚映射到其他引脚,作用是方便布线

  • STM32所有IO口都可以作为中断输入

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于STM32GPIO输出实验,点亮三色LED,您可以按照以下步骤进行操作: 1. 首先,您需要在STM32的开发环境中创建一个新的工程。 2. 在工程中,您需要包含相应的头文件,如"stm32f10x.h"。 3. 接下来,配置相应的引脚为输出模式。假设红色LED连接到GPIOA的Pin0引脚,绿色LED连接到GPIOA的Pin1引脚,蓝色LED连接到GPIOA的Pin2引脚,您可以使用以下代码进行配置: ``` GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置红色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置绿色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蓝色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` 4. 现在,您可以使用相应的寄存器来控制LED的点亮和熄灭。例如,要点亮红色LED,可以使用以下代码: ``` GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置高,点亮红色LED ``` 要熄灭红色LED,可以使用以下代码: ``` GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置低,熄灭红色LED ``` 同样的方法,您可以控制绿色和蓝色LED的点亮和熄灭。 这就是点亮三色LED的基本步骤。希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值