发新帖本帖赏金 50.00元(功能说明)我要提问
返回列表
[STM32]

详解单片机GPIO输出模式配置-推挽与开漏

[复制链接]
431|0
手机看帖
扫描二维码
随时随地手机跟帖
forgot|  楼主 | 2023-2-7 13:41 | 显示全部楼层 |阅读模式
本帖最后由 forgot 于 2023-2-7 13:43 编辑

#申请原创#
现在的很多单片机在GPIO配置的时候,除了配置输入输出类型、速度以外,还需要配置一下模式,即GPIO_Mode。以STM32为例,有输入浮空、输入上拉、输入下拉、模拟输入、开漏输出、推挽式输出、 推挽式复用功能、开漏复用功能。

微信截图_20230207110536.png

GPIO_Mode_Out_PP原理说明:
在采用单片机系统做信号控制以及外部电路驱动时,为了加快控制速度和提高IO驱动能力,经常要使用推挽(push-pull)式输出模式,即GPIO_Mode_Out_PP。该模式根据输入不同,两个晶体管交替导通。在芯片内部采用CMOS工艺,是由两个场效应晶体管构成推挽式电路,STM32的内部的推挽电路由上P下N的MOSFET构成,MOSFET有3个极性,S源极、D漏极、G栅极。上P管的S接到电源VDD上,D接到下N管的D上,下N管的S接到电源地的VSS上。通过对于GPIO输出数据寄存器的数据写入,可以控制推挽式电路的栅极输出高低电平。当控制栅极为低电平时,上面的P沟道MOS管导通,下面的的N沟道MOS管截至,由于上管的S连接VDD,所以输出高电平。当控制栅极为高电平时,上面的P沟道MOS管截止,下面的的N沟道MOS管导通,由于下管的S连接VSS,所以输出低电平。对于STM32单片机,由于P沟道的MOS输出电流能力很强,所以推挽输出的电流最大可以输出20mA。对于驱动LED或者是蜂鸣器都是可以直接驱动的。

微信截图_20230207132429.png

GPIO_Mode_Out_OD原理说明:
当通过配置将输出模式配置成开漏输出时,即GPIO_Mode_Out_OD。芯片内部上方的P沟道MOS管被关闭,这导致当栅极为低时,无法出书高电平1,而是输出高阻态Z,相当于开路状态。但是当控制栅极为高电平时,下面的的N沟道MOS管仍然可以导通,由于下管的S连接VSS,所以可以输出低电平0。开漏输出是为了实现逻辑器件的线与逻辑,如果配置成这种开漏输出,在需要电流输出驱动外部电路时,往往需要上拉一个电阻来提供电路的驱动电流,驱动能力的大小由外部上拉电阻决定,电阻越大,驱动能力越小,电阻越小,驱动能力越大,但是不能超过单片机的GPIO电流能力范围。

微信截图_20230207133120.png

STM32单片机当端口被配置为输出的时候,输出缓冲器被激活。此时如果是开漏模式,输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将端口置于高阻状态,PMOS从不被激活。如果是推挽模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-MOS。并且每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)用来配置模式与速度,两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)用来存放端口的输入数据与端口的输出数据,一个32位置位/复位寄存器(GPIOx_BSRR)和一个16位复位寄存器(GPIOx_BRR)用来设置和清除端口数据,一个32位锁定寄存器(GPIOx_LCKR)用来所存端口当前配置。

推挽输出配置参考例程:
void PP_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

开漏输出配置参考例程:
void OD_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

使用特权

评论回复

打赏榜单

21ic小管家 打赏了 50.00 元 2023-03-13
理由:签约作者奖励

相关帖子

发新帖 本帖赏金 50.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1188

主题

10590

帖子

49

粉丝