对通用输入输出GPIO的深入理解

本文详细介绍了通用输入输出(GPIO)的工作原理及应用,包括高阻输入、推挽输出、开漏输出等模式的特点与区别,以及GPIO在嵌入式系统中的重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对通用输入输出GPIO的深入理解

ARM技术 2009-10-31 10:14:39 阅读1 评论0   字号: 订阅

一.GPIO简介
        I/O(Input/Output)接口是一颗微控制器必须具备的最基本外设功能。通常在ARM里,所有I/O都是通用的,称为 GPIO(General Purpose Input/Output)。每个GPIO端口包含8个管脚,如PA端口是PA0~PA7。GPIO模块支持多个可编程输入/输出管脚(具体取决于与 GPIO复用的外设的使用情况)。GPIO模块包含以下特性:
z 1)可编程控制GPIO中断
?     ---屏蔽中断发生
?     ---边沿触发(上升沿、下降沿、双边沿)
?     ---电平触发(高电平、低电平)
z 2)输入/输出可承受5V
z 3)在读和写操作中通过地址线进行位屏蔽
z 4)可编程控制GPIO管脚配置:
?     ---弱上拉或弱下拉电阻
?     ---2mA、4mA、8mA驱动,以及带驱动转换速率(Slew Rate)控制的8mA驱动
?     ---开漏使能
?     ---数字输入使能

二.GPIO的各种模式
   GPIO管脚可以被配置为多种工作模式,其中有3种比较常用:高阻输入、推挽输出、开漏输出

1. 高阻输入(Input)
点击看大图
图1.1 GPIO高阻输入模式结构示意图
       为减少信息传输线的数目,大多数计算机中的信息传输线采用总线形式,即凡要传输的同类信息都在同一组传输线,且信息是分时传送的。在计算机中一般有三组总线,即数据总线、地址总线和控制总线。为防止信息相互干扰,要求凡挂到总线上的寄存器或存储器等,它的输入输出端不仅能呈现0、1两个信息状态,而且还应能呈现第三个状态----高阻抗状态,即此时好像它们的输出被开关断开,对总线状态不起作用,此时总线可由其他器件占用。三态缓冲器即可实现上述功能,它除具有输入输出端之外,还有一控制端。

       如图1.1所示,为GPIO管脚在高阻输入模式下的等效结构示意图。这是一个管脚的情况,其它管脚的结构也是同样的。输入模式的结构比较简单,就是一个带有施密特触发输入(Schmitt-triggered input)的三态缓冲器(U1),并具有很高的输入等效阻抗。施密特触发输入的作用是能将缓慢变化的或者是畸变的输入脉冲信号整形成比较理想的矩形脉冲信号。执行GPIO管脚读操作时,在读脉冲(Read Pulse)的作用下会把管脚(Pin)的当前电平状态读到内部总线上(Internal Bus)。在不执行读操作时,外部管脚与内部总线之间是隔离的。

2. 推挽输出(Output)
点击看大图
图1.2 GPIO推挽输出模式结构示意图
           推挽输出原理:在功率放大器电路中大量采用推挽放大器电路,这种电路中用两只三极管构成一级放大器电路,两只三极管分别放大输入信号的正半周和负半周,即用一只三极管放大信号的正半周,用另一只三极管放大信号的负半周,两只三极管输出的半周信号在放大器负载上合并后得到一个完整周期的输出信号。

      推挽放大器电路中,一只三极管工作在导通、放大状态时,另一只三极管处于截止状态,当输入信号变化到另一个半周后,原先导通、放大的三极管进入截止,而原先截止的三极管进入导通、放大状态,两只三极管在不断地交替导通放大和截止变化,所以称为推挽放大器(armjishu.com)。

        如图1.2所示,为GPIO管脚在推挽输出模式下的等效结构示意图。U1是输出锁存器,执行GPIO管脚写操作时,在写脉冲(Write Pulse)的作用下,数据被锁存到Q和/Q。T1和T2构成CMOS反相器,T1导通或T2导通时都表现出较低的阻抗,但T1和T2不会同时导通或同时关闭,最后形成的是推挽输出。在推挽输出模式下,GPIO还具有回读功能,实现回读功能的是一个简单的三态门U2。注意:执行回读功能时,读到的是管脚的输出锁存状态,而不是外部管脚Pin的状态。

3. 开漏输出(OutputOD)
点击看大图
图1.3 GPIO开漏输出结构示意图
            如图1.3所示,为GPIO管脚在开漏输出模式下的等效结构示意图。开漏输出和推挽输出相比结构基本相同,但只有下拉晶体管T1而没有上拉晶体管。同样,T1实际上也是多组可编程选择的晶体管。开漏输出的实际作用就是一个开关,输出“1”时断开、输出“0”时连接到GND(有一定内阻)。回读功能:读到的仍是输出锁存器的状态,而不是外部管脚Pin的状态。因此开漏输出模式是不能用来输入的。

        开漏输出结构没有内部上拉,因此在实际应用时通常都要外接合适的上拉电阻(通常采用4.7~10kΩ)。开漏输出能够方便地实现“线与”逻辑功能,即多个开漏的管脚可以直接并在一起(不需要缓冲隔离)使用,并统一外接一个合适的上拉电阻,就自然形成“逻辑与”关系。开漏输出的另一种用途是能够方便地实现不同逻辑电平之间的转换(如3.3V到5V之间),只需外接一个上拉电阻,而不需要额外的转换电路。典型的应用例子就是基于开漏电气连接的I2C总线。

4. 钳位二极管
        GPIO内部具有钳位保护二极管,如图1.4所示。其作用是防止从外部管脚Pin输入的电压过高或者过低。VDD正常供电是3.3V,如果从Pin 输入的信号(假设任何输入信号都有一定的内阻)电压超过VDD加上二极管D1的导通压降(假定在0.6V左右),则二极管D1导通,会把多于的电流引到 VDD,而真正输入到内部的信号电压不会超过3.9V。同理,如果从Pin输入的信号电压比GND还低,则由于二极管D2的作用,会把实际输入内部的信号电压钳制在-0.6V左右。
点击看大图
图1.4 GPIO钳位二极管示意图
        假设VDD=3.3V,GPIO设置在开漏模式下,外接10kΩ上拉电阻连接到5V电源,在输出“1”时,我们通过测量发现:GPIO管脚上的电压并不会达到5V,而是在4V上下,这正是内部钳位二极管在起作用。虽然输出电压达不到满幅的5V,但对于实际的数字逻辑通常3.5V以上就算是高电平了 (armjishu.com)。
点击看大图
图1.5 解决开漏模式上拉电压不足的方法
        如果确实想进一步提高输出电压,一种简单的做法是先在GPIO管脚上串联一只二极管(如1N4148),然后再接上拉电阻。参见图1.5,框内是芯片内部电路。向管脚写“1”时,T1关闭,在Pin处得到的电压是3.3+VD1+VD3=4.5V,电压提升效果明显;向管脚写“0”时,T1导通,在 Pin处得到的电压是VD3=0.6V,仍属低电平。

设计一个用STM32F407VET6单片机作为控制器的220V交流到3-24V直流开关电源涉及到硬件选型、电路设计以及软件编程。这里是一个简化的步骤说明: **硬件部分:** 1. **电源输入部分**:使用隔离放大器(如LTC4365)将高压交流电转换为安全电压,供给单片机工作。 2. **降压模块**:采用DC-DC开关稳压模块(例如LM2596),将来自隔离放大器的电压降至所需范围(比如TPS62850)。 3. **STM32F407VET6**:连接到降压模块的控制信号线,通过编程调节输出电压。 4. **保护电路**:包括过电压、过电流保护及短路保护。 **软件部分(使用Keil MDK或其他IDE):** 1. **初始化**:配置STM32的GPIO口作为数字输入和输出,用于监控输入状态和调整输出电压。 2. **主循环**: - **读取输入信号**:检查接收到的电源开关闭合信号。 - **控制降压模块**:如果输入为开(高电平),设置输出电压目标;如果输入为关(低电平),关闭输出。 - **设置PWM**:通过调整STM32的PWM输出,精确控制降压模块的占空比,进而改变输出电压。 - **保护措施**:定期检测电流和电压,如有异常,触发相应的保护动作并停止输出。 注意,这只是一个基本的设计概述,实际项目需要考虑更多细节,如错误处理、中断管理等,并需要详细的电路图和驱动程序。以下是部分关键代码片段: ```c // 定义输入和输出GPIO GPIO_InitTypeDef GPIO_InitStructure; // PWM定时器结构体 TIM_HandleTypeDef TimHandle; // 初始化GPIO GPIO_InitStructure.Pin = GPIO_PIN_x; // 输入信号对应的GPIO pin GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOx, &GPIO_InitStructure); // 初始化PWM TimHandle.Instance = TIMx; // ...其他PWM初始化配置 void control_output(uint8_t voltage_level) { uint16_t duty_cycle = (uint16_t)((float)voltage_level * PWM_MAX_DUTY / OUTPUT_VOLTAGE_RANGE); HAL_TIM_PWM_ConfigChannel(&TimHandle, &PWM_ChannelConfig); // 配置通道 HAL_TIM_PWM_Start(&TimHandle, NULL); // 开始PWM HAL_TIM_PWM_SetDutyCycle(&TimHandle, &duty_cycle); // 设置PWM占空比 } int main(void) { while(1) { if (HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x)) { // 输入接通 control_output(Voltage_Level_3V_to_24V); // 输出对应电压 } else { // 输入断开 HAL_TIM_PWM_Stop(&TimHandle); // 关闭输出 } // 检查电流和电压 // 如果超过阈值,执行保护措施并跳转至错误处理 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值