嵌入式系统(五):GPIO(输入输出端口扩展器)接口
1. GPIO结构及特点;
STM32F103RB芯片通用GPIO端口有PA、PB、PC和PD,统一可写成Px。每个端口包括16个引脚,可以表示为Px0~Px15。
STM32F103RB芯片的每个引脚可以由软件配置输入和输出模式:什么是开漏和推挽?(下文会详细讲),对于开漏输出和推挽输出的区别最普遍的说法就是开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动。
上拉输入、下拉输入、浮空输入、模拟输入的区别(同样,下文会详细讲)
(1)GPIO功能模式
(i)GPIO复用功能(AFIO,Alternate function)
- 指除传输I/O并行数据外,还可用于串口、定时器接口和I2C等其它端口使用
- 使用默认复用功能前必须对端口位配置寄存器编程
- 为了使不同器件封装的外设I/O功能的数量达到最优,可以把一些复用功能重新映射到其他一些脚上。这可以通过软件配置相应的寄存器来完成。这时,复用功能就不再映射到它们的原始引脚上了
(ii)GPIO数字输入模式
- 通过一个带有施密特触发的缓冲器,将缓慢变化或畸变的输入脉冲信号整形成比较理想的矩形脉冲信号。
- GPIO模式把数据输入到输入寄存器中
- 复用功能输入模式把数据输入到此复用功能的片上外设
- 并且根据软件配置,可以配置为浮空输入、上拉输入和下拉输入模式。
(iii)模拟输入模式
模拟输入模式直接接收模拟电压信号,其中模拟电压输入范围在0V~Vref(标准参考电压)之间,由于STM32芯片供电电压为3.3V,所以模拟电压的输入不超过3.3V。
(iii)推挽输出模式
- 推挽电路是指两个参数相同的MOS管或晶体管,分别受两个互补信号的控制,在一个晶体管导通时,另一个截止;由于每次只有一个管导通,所以导通损耗小,效率高。
- 推挽电路既可以向负载灌电流,也可以从负载抽取电流,推挽式输出既提高电路的负载能力,又提高开关速度。
- 推挽输出包括:通用推挽输出,用于GPIO输出;复用推挽输出,供片内外设引脚使用。
(iv)开漏输出模式
- 开漏输出模式就是不输出电压,低电平时接地,高电平时不接地。如果外接上拉电阻,则在输出高电平时,电压会拉到上拉电阻的电源电压。
- 这种方式适合连接的外设电压比单片机电压低的情况。
- 其中,通用开漏输出,GPIO输出0时引脚接GND,GPIO输出1时引脚悬空,该引脚需要外接上拉电阻,才能实现输出高电平;复用开漏输出,此模式供片内外设使用。
(v)输出速度与钳位功能
- GPIO输出模式下,有3种输出速度可选,分别为2MHz、10MHz和50MHz。
- GPIO内部具有钳位保护二极管,其作用是防止从外部引脚输入的电压过高或过低。
- 因此,虽然STM供电电压是3.3V,由于内部钳位二极管的作用,对电压进行降低从而对GPIO起保护作用,因此,STM32单片机可以承受外接5V电压。
(2)STM32芯片GPIO特点:
- I/O口电平兼容性,模拟口最大承受3.6V,数字口承受5V,且所有I/O口兼容CMOS和TTL。
- I/O口驱动能力,GPIO口最大可以吸收25mA电流,但是总吸收电流不能超过150mA。
- I/O口可内部上拉/下拉设置:当所有GPIO口引脚配置成输入时,可配置内部上拉或下拉功能,以简化外部输入电路设计。
- I/O口可配置为外部中断口:每个GPIO口都可以作为外部中断的输入。
- 具有独立的唤醒I/O口,例如一个从待机模式中唤醒的专用引脚PA0。
- I/O口具有锁存功能:当配置好GPIO后,可以通过程序锁住配置组合,直到下次芯片复位,从而避免对GPIO寄存器的误操作。
- 具有侵入检测引脚:当PC13/TAMPER引脚上的信号从0变成1或从1变成0,会产生一个侵入检测事件,会将所有数据备份寄存器内容清除。
2. GPIO寄存器和库函数;
- 芯片硬件驱动是经过一系列控制寄存器的写入以及状态寄存器的读出操作,实现程序代码对硬件的操作。
- 传统单片机,如51单片机,由于寄存器较简单,大多数直接配置寄存器,如控制一个引脚为高电平,只要在对应引脚的寄存器相应位写入“1”即可;读一个引脚的状态,只要直接读取对应寄存器相应的位即可。
- STM32单片机,寄存器相对复杂,厂家针对每个寄存器的操作封装了相应的库函数供用户使用。
(1) GPIO寄存器
注意:GPIO寄存器必须以32位字的形式访问,寄存器GPIOx_BSRR和GPIO_BRR寄存器允许对任何时刻GPIO端口的读/写独立访问。
(2)GPIO库函数
STM32固件库提供GPIO库函数,这些函数的声明都包含在头文件stm_32f10x_gpio.h
中
-
GPIO_init
函数:对引脚进行初始化的操作 -
GPIO_SetBits
函数:设置输出引脚为高电平
配置GPIO B口引脚1和引脚15为高电平:GPIO_SetBits(GPIOB, GPIO_Pin1|GPIO_Pin_15)
-
GPIO_ResetBits
函数:设置输出引脚为低电平
配置GPIO B口引脚1和引脚15位低电平:GPIO_ResetBits(GPIOB, GPIO_Pin_1|GPIO_Pin_15)
-
GPIO_ReadInputDataBit
函数:读指定端口具体引脚输入数据
读取PORTB端口引脚5的数值:ReadValue=GPIO_ReadInputDatBit(GPIOB, GPIO_Pin_5)
3. GPIO应用实例
与本实例相关的GPIO寄存器,主要包括:端口配置低寄存器(GPIOx_CRL:因为我们只用到了PA扩展器接口)、端口输入数据寄存器(GPIOx_IDR)和端口输出数据寄存器(GPIOx_ODR),其它GPIO相关寄存器的说明,可参见《STM32F10xxx系列芯片开发手册》对寄存器的描述。
(1)端口配置低寄存器(GPIOx_CRL),用于配置引脚的功能模式。
- PA0控制按钮。因此是输入模式,我们给他配置一个上拉电平。
/*设置PA0为输入,配置上拉电阻,
CNF0=10,MODE0=00*/
GPIOA_CRL |= 0x00000008; //配置上拉电阻
GPIOA_CRL &= ~(0x00000007); //将后7位搞为0,此时CNF[1:0]=1000 MODE0[1:0]=0000,高位不变.
- 设置PA1为输出模式(即LED的工作状态),最大速度10MHz , CNF1=00,MODE1=01
GPIOA_CRL |= 0x00000010;//MODE1[1:0]=01
GPIOA_CRL &= ~(0x000000E0);//将4-7位除了第4位的1其余全部置零
(2)端口输入数据寄存器(GPIOx_IDR),用于读取输入口状态。
/*检测PA0的状态*/
if((GPIOA_IDR & 0x01)== 0)
/*如果检测为低电平,即按钮按下*/
(3)端口输出数据寄存器(GPIOx_ODR),用于控制引脚的输出。
GPIOA_ODR &= ~(0x0002); /*控制PA1输出为低电平,LED亮*/
GPIOA_ODR |= 0x0002; /*控制PA1输出为高电平,LED灭*/
(4)主要程序段
if((GPIOA_IDR & 0x01)== 0) //若检测为低电平,即按钮按下
GPIOA_ODR &= ~(0x0002); //控制PA1输出为低,LED亮
else
GPIOA_ODR |= 0x0002; //控制PA1输出为高电平,LED灭
上一篇: linux系统中C语言中的清空scanf输入缓冲区
下一篇: 重新编译linux内核,全程实录(一)