0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MM32F0140 GPIO学习笔记

jf_pJlTbmA9 来源:灵动MM32MCU 作者:灵动MM32MCU 2023-09-26 16:42 次阅读

一、GPIO简介

GPIO作为通用输入输出端口,其全称为General Purpose Input Output,能够通过软件自由配置引脚状态及工作模式。除通用输入输出功能外,部分GPIO端口还可被用作第二功能的配置,即为复用功能。

每个通用I/O端口都可以通过软件自由配置为4种输入模式与4种输出模式。

输入模式

通过配置GPIOx_CRL寄存器或GPIOx_CRH寄存器中的MODEx[1:0]为00,即配置为输入模式,配置寄存器中的CNFx[1:0]选择工作模式(MM32F0140 的GPIOx中“x”的范围为A到D)。

poYBAGIPMLyAbSsEAACMdAhhNrc594.png 图1. 输入浮空/上拉输入/下拉输入/模拟输入配置

输入浮空:

浮空就是输入引脚即不接高电平也不接低电平,如图1所示,I/O端口的数据在每个AHB时钟被采样到输入数据寄存器,通过读访问输入数据寄存器获取当前I/O状态,输入浮空常用于复用功能。

上拉输入:

电阻与VDD相连,形成上拉电阻,I/O端口在空闲时为高电平,能够用于检测由高到低的电平变化,常用于按键检测。

下拉输入:

电阻与VSS相连,形成下拉电阻,I/O端口在空闲时为低电平,能够用于检测由低到高的电平变化。

模拟输入:

模拟输入是模拟信号的输入,在模拟输入模式下,上拉电阻、下拉电阻及斯密特触发器均被禁止。

输出模式

通过配置GPIOx_CRL寄存器或GPIOx_CRH寄存器中的CNFx[1:0]选择输出模式,配置GPIOx_CRL中的MODEx[1:0]选择输出速度(MODEx[1:0]不为00)。当I/O端口使用复用输出功能时,端口必须配置为复用功能输出模式(推挽或开漏),输出配置如图2所示。

pYYBAGIPMYqAbtnPAABy3Mf93n4282.png 图2. 输出配置

开漏输出:

在开漏输出模式中,输出控制寄存器配置为0时,数据经过输出控制模块,MOS管的栅极接收到高电平,MOS管导通,此时I/O端口接通在GND上,即对应引脚输出低电平;当输出控制寄存器配置为1,数据经过控制模块,给予MOS管的栅极一个低电平,此时MOS管不导通,对应的管脚处于高阻态。因此,开漏输出通常输出低电平,若要输出高电平则需外加上拉电阻。

推挽输出:

推挽输出一般指两个MOS管分别受两个互补信号的控制,总是在一个MOS管导通时另一个MOS管截止。当输出控制寄存器配置为0时,数据经过输出控制模块,MOS管的栅极接收到高电平,N-MOS管导通,P-MOS管不导通,此时I/O端口接通在VSS上,即对应引脚输出为低电平;当输出控制寄存器配置为1时,数据经过输出控制模块,MOS管的栅极接收到低电平,P-MOS管导通,N-MOS管不导通,此时I/O端口接通在VDD上,即对应引脚输出为高电平。因此,推挽输出可以输出高低电平。

poYBAGIPMc6Aa0N6AACgGSJitjc155.png 图3. 复用功能配置

复用开漏输出:

配置GPIOx_AFRH与GPIOx_AFRL寄存器的AFRLx[3:0]与AFRHx[3:0]选择复用功能。当GPIO被作为第二功能使用时,模式配置为复用模式,复用功能配置如图3所示。以图4为例,若要配置PB10引脚作为I2C_SCL,则在配置GPIO模式时要选择复用模式。通过片上外设复用功能,使用MOS管实现输出。通常I2C使用GPIO的复用功能时会使用复用开漏输出模式,由于I2C的一个主设备可挂载多个从设备,若不使用复用开漏输出,而使用复用推挽输出,数据传输时,两个从设备一个拉高,一个拉低,可能会造成短路。因此I2C大多使用GPIO的复用开漏输出模式。

pYYBAGIPMiuAbYObAAFQpPrKxOU703.png 图4. MM32F0140部分引脚复用功能

复用推挽输出:

当GPIO被作为第二功能配置使用时,模式需配置为复用模式,通过配置GPIO_AFRH与GPIOx_AFRL寄存器的AFRLx[3:0]与AFRHx[3:0]选择复用功能,通过片上外设复用功能,使用两个MOS管来实现输出。与推挽输出不同,复用推挽输出模式下端口的I/O操作由对应复用的功能模块控制,而推挽输出模式下控制I/O端口需对GPIO内部的寄存器进行操作。

二、配置GPIO

首先,使能对应I/O口的时钟,根据所使用的外设对RCC的RCC_AHBENR寄存器进行赋值,将对应外设位置1即可使能时钟,详细外设如图5所示。

poYBAGIPMoGABuh8AAGQ8YMxoLE031.png 图5. MM32F0140 AHB外设

其次,配置所需的GPIO引脚、速度及工作模式。端口0到端口7使用GPIOx_CRL寄存器配置工作模式与速度,该寄存器中MODEx[1:0]位表示端口输入输出速度,CNFx[1:0]位表示端口工作模式(”MODEx”与”CNFx”的”x”表示指定端口号)。若配置GPIOx_CRL寄存器中的MODEx位等于00则端口为输入模式,此时CNFx位有四种配置方式,分别为:00(模拟输入模式),01(浮空输入模式),10(上拉/下拉输入模式);若MODEx位不为00,则对应端口为输出模式,此时CNFx具有四种配置方式:00(推挽输出模式),01(开漏输出模式),10(推挽复用模式),11(开漏复用模式)。端口8到端口15的配置使用GPIOx_CRH寄存器配置指定端口的工作模式与速度,详细配置方式与CPIOx_CRL寄存器相同。

若使用端口复用功能,需对GPIOx_AFRL(端口复用功能低位)寄存器与GPIOx_AFRH(端口复用功能高位)寄存器进行配置。端口号为0到7则使用GPIOx_AFRL寄存器,端口号为8到15则使用GPIOx_AFRH寄存器,根据端口号与复用功能表进行配置,例如若使用PA0引脚作为I2C1_SCL,则需将GPIOx_AFRL寄存器中AF3的对应位置1(GPIO的工作模式也要配置为复用模式),PA端口的复用功能表如图6所示。

poYBAGIPMp6ANC5dAAHq7pAnIeI421.png 图6 MM32F0140 PA端口复用功能表

三、实验

本实验通过使用GPIO获取按键状态控制LED亮灭,读取指定GPIO端口引脚的输入数据(读GPIOx_IDR寄存器)来获取当前的按键状态,通过对端口设置/清除寄存器(GPIOx_BSRR寄存器)与端口位清除寄存器(GPIOx_BRR寄存器)的对应端口赋值,使对应的LED亮灭。具体实验内容为配置PB3引脚对应LED2, PB4引脚对应LED3,PB2引脚对应的K2(如图7所示),若K2按下,则K2对应的端口输入低电平,设置实验现象为LED2灭、LED3亮,K2处于非按下时,K2对应的端口输入高电平,设置实验现象为LED2亮、LED3灭。

pYYBAGIPMtaAR3GuAAEfBUfMRUQ878.png 图7 引脚配置原理图

外设时钟初始化

GPIO在AHB线上,实验使用引脚均为GPIOB组的引脚,因此对RCC_AHBENR寄存器的GPIOB对应位置1。

RCC->AHB1ENR |= (1u << 18u);

按键初始化

实验使用引脚为PB2的K2按键,按键原理图如图8所示,若K2按键按下则与GND导通,因此在初始化按键时需配置该端口的工作模式为上拉输入。

pYYBAGIPMvCADsKTAAB9G2AR7ZE828.png 图8. 按键原理图

GPIOx_CRL寄存器为端口配置低寄存器,用于配置指定端口的速度与工作模式;GPIOx_BSRR寄存器用于设置/清除对应端口,该寄存器低16位的对应端口位置1会产生高电平。由图9所示,K2所使用的端口2为GPIOx_CRL寄存器内第8~11位。

poYBAGIPMzCAdK0cAAGyJ73y44I238.png 图9.端口配置低寄存器的比特位

//对应端口的配置涉及到4位,后两位配置端口输入输出速度,前两位配置工作模式;清零端口2的配置位
GPIOB->CRL  = ~(0xf << 8u); 

//速度配置位为0,端口为输入模式,上拉输入的工作模式位为10,因此使用0x08.
GPIOB->CRL |= (0x08 << 8u); 

//配置PB2引脚为高电平
GPIOB->BSRR |= (1u << 2u); 

LED初始化

实验使用PB3、PB4,引脚,为观察LED的高低电平,在配置工作模式时使用可以输出高低电平的推挽输出。因为PB3与PB4对应端口在端口0~7中,所以使用GPIOx_CRL寄存器对LED进行初始化配置(若使用端口为8~15则使用GPIOx_CRH寄存器)。

如图9所示,端口3为GPIOx_CRL寄存器内第12~15位,端口4为GPIOx_CRL寄存器内第16~19位。由于LED为低电平点亮,设置GPIOx_BSRR寄存器中LED2与LED3的对应位置1使LED初始状态为灭。

//复位将要使用的端口3与端口4的配置位
GPIOB->CRL  = ~( (0xf << 12u) | (0xf << 16u) ); 

//端口输入输出速度配置位不为00时,端口为输出模式,配置最大速度为50MHz,推挽输出模式的配置为00.
GPIOB->CRL |= ( (0x01 << 12u) | (0x01 << 16u) );

//PB3对应的LED2初始化状态为灭
GPIOB->BSRR = (1u << 3u); 

//PB4对应的LED3初始化状态为灭
GPIOB->BSRR = (1u << 4u); 

按键扫描

读GPIOx_IDR寄存器获取对应端口输入数据,本实验中K2配置为上拉输入,即按键未按下时为高电平,按下按键后,K2对应端口输入为低电平。若GPIOx_BSRR寄存器的低16位的对应端口位置1,则该端口为高电平;若GPIOx_BRR寄存器的对应端口位置1,则该端口为低电平。实验设置按键未按下时,LED2(PB3)亮、LED3(PB4)灭;按下按键时LED2灭、LED3亮。

while(1)
{
    //K2的引脚为PB2,  1u<<2u = 0100u,将PB2的对应位置1,若读出GPIOx_IDR的对应端口数据为高电平则按键未按下
    if ( 0u != ( GPIOB->IDR   (1u << 2u) ) ) 
    {
    //PB4引脚对应的LED3灭
        GPIOB->BSRR = (1u << 4u);

        //PB3引脚对应的LED2亮
        GPIOB->BRR = (1u << 3u); 
    }
    else  //K2 按键按下
    {
        //PB4引脚对应的LED3亮
        GPIOB->BRR =(1u << 4u);

        //PB3引脚对应的LED2灭
        GPIOB->BSRR = (1u << 3u);
    }
}

Main()函数

综合上述寄存器配置到main函数中,图10为实验效果。

int main(void)
{
    //GPIOB时钟初始化
    RCC->AHB1ENR |= (1u << 18u);

    //清零端口2的配置位
    GPIOB->CRL  = ~(0xfu << 8u);
    //端口2配置为上拉输入
    GPIOB->CRL |= (0x08u << 8u);
    //端口2配置为高电平
    GPIOB->BSRR |= (1u << 2u);

    //端口3与端口4配置位清零
    GPIOB->CRL  = ~( (0xf << 12u) | (0xf << 16u) );
    //端口3与端口4配置为推挽输出,速度最大为50MHz
    GPIOB->CRL |= ( (0x01 << 12u) | (0x01 << 16u) );

    //PB3对应的LED2初始化状态为灭
    GPIOB->BSRR = (1u << 3u);
    //PB4对应的LED3初始化状态为灭
    GPIOB->BSRR = (1u << 4u);

    while(1)
    {
        //K2的引脚为PB2,  1u << 2u = 0100u,将PB2的对应位置1,若读出GPIOx_IDR的对应端口数据为高电平则按键未按下
        if ( 0u != ( GPIOB->IDR   (1u << 2u) ) ) 
        {
            // PB4引脚对应的LED3灭
            GPIOB->BSRR = (1u << 4u);

            //PB3引脚对应的LED2亮
            GPIOB->BRR = (1u << 3u); 
        }
        else  //按下按键K2
        {
            // PB4引脚对应的LED3亮
            GPIOB->BRR = (1u << 4u);

            // PB3引脚对应的LED2灭
            GPIOB->BSRR = (1u << 3u); 
        }
    }
}

pYYBAGIPM_uAZ5oNAE3b__SbHbw971.gif 图9.实验效果

来源:灵动MM32MCU

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5308

    浏览量

    119978
  • 端口
    +关注

    关注

    4

    文章

    953

    浏览量

    32008
  • GPIO
    +关注

    关注

    16

    文章

    1196

    浏览量

    51896
收藏 人收藏

    评论

    相关推荐

    灵动微课堂 (第201讲) | MM32F0140 GPIO 学习笔记

    模式。图4. MM32F0140部分引脚复用功能复用推挽输出:当GPIO被作为第二功能配置使用时,模式需配置为复用模式,通过配置GPIO_AFRH与GPIOx_AFRL寄存器的AFRLx[3:0
    发表于 02-18 13:53

    AN0052从MM32F0130移植到MM32F0140(英文版)

    AN0052 从MM32F0130移植到MM32F0140(英文版)
    发表于 02-22 18:43 0次下载
    AN0052从<b class='flag-5'>MM32F</b>0130移植到<b class='flag-5'>MM32F0140</b>(英文版)

    MM32F0140 产品手册(中文版)

    MM32F0140 产品手册(中文版)
    发表于 02-22 18:45 0次下载
    <b class='flag-5'>MM32F0140</b> 产品手册(中文版)

    MM32F0140 产品手册(英文版)

    MM32F0140 产品手册(英文版)
    发表于 02-22 18:45 0次下载
    <b class='flag-5'>MM32F0140</b> 产品手册(英文版)

    MM32F0140 用户手册(中文版)

    MM32F0140 用户手册(中文版)
    发表于 02-22 18:46 0次下载
    <b class='flag-5'>MM32F0140</b> 用户手册(中文版)

    MM32F0140 用户手册(英文版)

    MM32F0140 用户手册(英文版)
    发表于 02-22 18:46 0次下载
    <b class='flag-5'>MM32F0140</b> 用户手册(英文版)

    MM32F0140 勘误表(中文版)

    MM32F0140 勘误表(中文版)
    发表于 02-22 18:47 0次下载
    <b class='flag-5'>MM32F0140</b> 勘误表(中文版)

    MM32F0140 勘误表(英文版)

    MM32F0140 勘误表(英文版)
    发表于 02-22 18:48 0次下载
    <b class='flag-5'>MM32F0140</b> 勘误表(英文版)

    基于MM32F0140的UDS Bootloader学习笔记

    基于MM32F0140的UDS Bootloader学习笔记
    的头像 发表于 10-30 17:11 712次阅读
    基于<b class='flag-5'>MM32F0140</b>的UDS Bootloader<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>

    MM32F0140学习笔记——CRC

    MM32F0140学习笔记——CRC
    的头像 发表于 11-10 18:27 569次阅读
    <b class='flag-5'>MM32F0140</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>——CRC

    MM32F0140学习笔记——窗口看门狗(WWDG)

    MM32F0140学习笔记——窗口看门狗(WWDG)
    的头像 发表于 10-27 09:45 583次阅读
    <b class='flag-5'>MM32F0140</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>——窗口看门狗(WWDG)

    MM32F0140学习笔记——FlexCAN 控制器局域网

    MM32F0140学习笔记——FlexCAN 控制器局域网
    的头像 发表于 10-27 09:25 1416次阅读
    <b class='flag-5'>MM32F0140</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>——FlexCAN 控制器局域网

    MM32F0140 SPI学习笔记

    MM32F0140 SPI学习笔记
    的头像 发表于 09-26 16:51 566次阅读
    <b class='flag-5'>MM32F0140</b> SPI<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>

    MM32F0140 DMA学习笔记

    MM32F0140 DMA 学习笔记
    的头像 发表于 09-18 16:57 680次阅读
    <b class='flag-5'>MM32F0140</b> DMA<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>

    MM32F0140 UART学习笔记

    MM32F0140 UART学习笔记
    的头像 发表于 09-26 16:45 732次阅读
    <b class='flag-5'>MM32F0140</b> UART<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>