RT1064学习笔记-GPIO

GPIO

GPIO配置基本过程

配置IO复用功能→配置IO属性→IO口配置

IO 复用功能选择器(IOMUXC)的寄存器非常多,主要可以分为四组:

① IOMUXC_GPR 寄存器组,用于通用控制设置。

② IOMUXC_SNVS 组,主要用于 GPIO5 的控制。 ③ IOMUXC_SNVS_GPR 寄存器组,暂时没用到。

④ IOMUXC 组,用于指定 IO 的复用功能选择和 IO 属性设置。

在 IO 设置的时候,实际上我们只用到了②和④,①和③没用到,所以①和③,我们这里不做介绍。

所以,我们可以把②和④一起介绍,任意一个 IO,都是由 2 个寄存器(SW_MUX_CTL_PAD / SW_PAD_CTL_PAD)控制的。

IOMUXC_SW_MUX_CTL_PAD_

IOMUXC_SW_PAD_CTL_PAD_

红色:用于定义IO所属分组

蓝色:SW_MUX_CTL_PAD——IO复用功能选择寄存器;SW_PAD_CTL_PAD——IO属性配置寄存器

:引脚名

具体模式查看:IOMUXC Memory Map/Register Definition;具体寄存器名:(IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_05)

SW_MUX_CTL_PAD——IO复用功能选择寄存器

RT1064学习笔记-GPIO_第1张图片
SION位:强制输入位,一旦设置,无论MUX_MODE设置什么模式总可以从PSR中读取到该引脚的状态

在IOMUXC的分组下还有一类特殊的寄存器:IOMUXC_xxxxx_SELECT_INPUT
RT1064学习笔记-GPIO_第2张图片

xxxxx代表为某一IO口的复用功能,但这个复用功能一般有多个IO口可以选择

SW_PAD_CTL_PAD——IO属性配置寄存器

RT1064学习笔记-GPIO_第3张图片
RT1064学习笔记-GPIO_第4张图片
IO口具体属性

RT1064学习笔记-GPIO_第5张图片
输出部分

OBE,输出缓冲使能,这个属性是内部自动设置的,我们无法直接通过软件修改,当 IO 配置成输出模式时,OBE 自动使能;当 IO 配置成输入模式时,OBE 自动失能;相当于间接设置,其他功能也自动失效

DSE,输出驱动能力,需软件设置,总共有 8 个等级:关闭和 R0/1~R0/7。由 R0 决定 IO 口的驱动能力,在 3.3V 条件下,R0 的值为 150Ω。最小的输出电阻(可以获得最大的驱动能力)为:R0/7=21.4Ω。

SRE,压摆率,需软件设置。共有 2 个等级:Fast 和 Slow。压摆率控制电平跳变的时间,压摆率越高,波形越陡,压摆率越低,波形越缓。这个设置,在过 EMC 测试的时候,比较有用。比如要过 EMC 可以设置压摆率低一些(slow),得到比较平缓的边沿,从而降低电磁辐射。

SPEED,输出速率(带宽),需软件设置,总共有 3 个等级:50M、100M 和 200M。

ODE,开漏输出使能,需软件设置,当设置 ODE=0 且 GPIO 设置成输出模式,为推挽输出;当设置 ODE=1 且 GPIO 设置成输出模式,为开漏输出,开漏输出时:IO 口只能输出低电平/三态输出,无法直接输出高电平,需要使用上拉电阻(内部/外部)才可以输出高电平。当GPIO 设置成输入模式时,ODE 设置直接被忽略。

输入部分

IBE,输入缓冲使能,这个属性是内部自动设置的,我们无法直接通过软件修改,当 IO 配置成输入模式时,IBE 自动使能;当 IO 配置成输出模式时,IBE 自动失能;相当于间接设置。当 IBE 失能时(GPIO 为输出模式时),HYS 等设置无效。

IND,输入信号,读取到的 IO 口状态,由这个口传入 MCU 内部的。

HYS,迟滞比较使能,需软件设置,用于设置是否使能输入接收器的施密特触发器(滞后模式),施密特触发可以对波形进行整形,可以在一定程度上滤除误触发。一般可以不设置。

上拉/下拉/保持控制逻辑

PUS:用于设置上/下拉电阻,可选设置有:100K 下拉、47K 上拉、100K 上拉和 22K 上拉。

PKE:用于使能/禁止上下拉电阻和状态保持器,当设置为 1 时,使能上下拉电阻/状态保持器;当设置为 0 时,关闭上下拉电阻/状态保持器

另外,还有一个 PUE 信号,在图 6.3.3 中没有标出,是用于控制选择使用上下拉电阻还是使用状态保持器,当设置为 0 的时候,选择使用状态保持器(上下拉关闭);当设置为 1 的时候,选择使用上下拉电阻(状态保持器关闭),因此上下拉和状态保持器只能二选一。

关于状态保持器(KEEPER)的说明

RT1052 的每个 IO 口,都有一个状态保持器,但是它在输入模式下,叫输入状态保持器,用于当外部电路断电时(此时 MCU 还是供电的),维持 IO 口的状态,有利于低功耗应用。而在输出模式下,它又叫输出状态保持器,用于当内核断电时,维持 IO 口的输出状态,同样有利于低功耗应用。

一般情况下,当我们使用 IO 口做输入模式的时候,设置上下拉模式(PUE=1);当我们使用 IO 口作为输出模式的时候,设置状态保持器模式(PUE=0);

GPIO配置

GPIO_DR——GPIO数据寄存器

RT1064学习笔记-GPIO_第6张图片
GPIO_DR 数据寄存器在输出模式(GDIR=1)下,写入 DR 的数据将会输出到对应的 IO 引脚,用于控制 IO 的高低电平。

在输入模式(GDIR=0)下,通过读取 DR 寄存器对应位,可以读取对应 IO 引脚的状态值。

GPIO_GDIR——GPIO方向控制寄存器

RT1064学习笔记-GPIO_第7张图片
GPIO_GDIR 方向控制寄存器用于控制 IO 口的输入/输出方向,当 GDIR 对应位设置为 0时,对应 IO 为输入模式。当 GDIR 对应位设置为 1 时,对应 IO 为输出模式。

GPIO_GDIR 方向控制寄存器用于控制 IO 口的输入/输出方向,当 GDIR 对应位设置为 0时,对应 IO 为输入模式。当 GDIR 对应位设置为 1 时,对应 IO 为输出模式。

GPIO_ESR——GPIO引脚状态寄存器

RT1064学习笔记-GPIO_第8张图片

GPIO_PSR引脚状态寄存器用于读取IO口的状态,相当于输入模式下的GPIO_DR寄存器。

注意:当 IOMUXC 开启 IO 口的强制输入(SION=1)时,可以通过 GPIO_PSR
读取 IO 口的状态。

GPIO_ICR1/2——GPIO 中断配置寄存器

RT1064学习笔记-GPIO_第9张图片
GPIO_ICR1 用于配置 IO0~IO15 的中断触发条件,总共有 4 种触发条件可选:00,低电平触发;01,高电平触发;10,上升沿触发;11,下降沿触发。

GPIO_IMR——GPIO 中断屏蔽寄存器

RT1064学习笔记-GPIO_第10张图片
GPIO_IMR 中断屏蔽寄存器用于使能/禁止 IO 的中断功能,当 GPIO_IMR 对应位设置成 1的时候,使能对应 IO 口的中断功能,反之则禁止。

GPIO_EDGE_SEL——GPIO边沿选择寄存器

RT1064学习笔记-GPIO_第11张图片
GPIO_EDGE_SEL 边沿选择寄存器用于设置上升沿&下降沿触发中断。

注意:该寄存器的设置,会覆盖 ICR1/ICR2 的设置。

RT1064的IO口不能容忍5V。

如果需要和 5V 设备连接,输出模式:请使用开漏输出模式配合上拉电阻(接 5V)实现,且灌电流越小越好,最大单个 IO 的灌电流不要超 过 1mA,整个芯片的灌电流不要超过 10mA。输入模式:请串联大电阻!

GPIO函数示例

FSL库中的API函数

  1. IOMUXC_SetPinMux 函数 (fsl_iomuxc.h)

    用于设置IO的复用功能

static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
                                    uint32_t muxMode,
                                    uint32_t inputRegister,
                                    uint32_t inputDaisy,
                                    uint32_t configRegister,
                                    uint32_t inputOnfield)

muxRegister:IO复用功能选择寄存器的地址

muxMode:选择的复用的模式

inputRegister:选择的输入寄存器

inputDaisy:DAISY 位

configRegister:配置寄存器

inputOnfield:设置是否为强制输入

若这些参数要一个个找会很麻烦,在fsl_iomuxc.h中1188行之前

  1. IOMUXC_SetPinConfig函数 (fsl_iomuxc.h)

    此函数用来配置 IO 的驱动能力、速度、驱动能力等

static inline void IOMUXC_SetPinConfig(uint32_t muxRegister,
                                       uint32_t muxMode,
                                       uint32_t inputRegister,
                                       uint32_t inputDaisy,
                                       uint32_t configRegister,
                                       uint32_t configValue)

前5个参数与上个函数一样

configValue:写入到IOMUXC_SW_PAD_CTL_PAD_寄存器中的值,对着寄存器写值

  1. GPIO_PinInit 函数 (fsl_gpio.h)

    设置指定 GPIO 引脚的功能

void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config)

base:要设置的GPIO的组

pin:组内编号

Config:配置参数

typedef struct _gpio_pin_config
{
 gpio_pin_direction_t direction; //方向,输入还是输出?
 uint8_t outputLogic; //默认输出电平 
 gpio_interrupt_mode_t interruptMode; //中断模式
} gpio_pin_config_t;

direction:

typedef enum _gpio_pin_direction
{
    kGPIO_DigitalInput  = 0U, /*!< Set current pin as digital input.*/
    kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output.*/
} gpio_pin_direction_t;

outputLogic:0 or 1

interruptMode:六种设置

typedef enum _gpio_interrupt_mode
{
    kGPIO_NoIntmode              = 0U, /*!< Set current pin general IO functionality.*/
    kGPIO_IntLowLevel            = 1U, /*!< Set current pin interrupt is low-level sensitive.*/
    kGPIO_IntHighLevel           = 2U, /*!< Set current pin interrupt is high-level sensitive.*/
    kGPIO_IntRisingEdge          = 3U, /*!< Set current pin interrupt is rising-edge sensitive.*/
    kGPIO_IntFallingEdge         = 4U, /*!< Set current pin interrupt is falling-edge sensitive.*/
    kGPIO_IntRisingOrFallingEdge = 5U, /*!< Enable the edge select bit to override the ICR register's configuration.*/
} gpio_interrupt_mode_t;
  1. GPIO_PinWrite 函数 (fsl_gpio.h)

    设置指定的 GPIO 的输出电平

void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output);

base:要设置的GPIO的组

pin:组内编号

output:输出电平,1为高电平,0为低电平

  1. GPIO_PinRead 函数

此函数用于读取一个指定 IO 的电平

static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t pin)

base:要设置的 GPIO 组

pin:组内编号

返回值:读到的指定 IO 的电平值,1 为高电平,0 为低电平

代码编写

配置为输出模式时,输入部分的参数配置自动失效;

配置为输入模式时,输出部分的参数配置自动失效

详见SW_PAD_CTL_PAD——IO属性配置寄存器

应该主要看的是DSE

输出模式

void LED_Init(void)
{
    gpio_pin_config_t led_config;

    //设置 B3 的复用功能选择寄存器,设置B3为普通GPIO模式
    IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_03_GPIO1_IO03,0);

    //配置 B3 的功能
    //0 0001 0000 1011 0000
    //关闭 Hyst,下拉 100K Ohm,选择Keeper,使能pull/keeper,关闭开漏,100MHz_SPEED1,驱动能力R0/6,低转换速度
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_03_GPIO1_IO03,0x10B0);

    led_config.direction=kGPIO_DigitalOutput;
    led_config.interruptMode=kGPIO_NoIntmode;
    led_config.outputLogic=1;
    GPIO_PinInit(GPIO1,3,&led_config);//此函数中自动打开时钟
}

输入模式

void KEY_Init(void)
{
    gpio_pin_config_t key_config;

    //设置 B3 的复用功能选择寄存器,设置B3为普通GPIO模式
    IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_03_GPIO1_IO03,0);

    //配置 B3 的功能
    //0 1111 0000 1000 0000
    //关闭 Hyst,上拉 22K Ohm,选择Pull,使能pull/keeper,关闭开漏,100MHz_SPEED2,关闭输出驱动,低转换速度
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_03_GPIO1_IO03,0xF080);

    led_config.direction=kGPIO_DigitalInput;    //输入
    led_config.interruptMode=kGPIO_NoIntmode;	//无中断
    led_config.outputLogic=1;		//此值设置为输出时才有效
    GPIO_PinInit(GPIO1,3,&led_config);//此函数中自动打开时钟
}

本文参照正点原子RT1052 开发指南。

你可能感兴趣的:(学习,单片机,arm,mcu,c语言)