03 IMX6ULL裸机开发:普适的GPIO引脚操作方法概述

创建时间:2021/12/28 9:19
更新时间:2022/2/17 18:21
作者:gi51wa2j
标签:100ask_IMX6ULL_v11, bingo, 正文

一、概念介绍

GPIO: General-purpose input/output,通用的输入输出口。

1.1 GPIO模块一般结构

  • 有多组GPIO,每组有多个GPIO

  • 使能:电源/时钟

  • 模式(Mode):引脚可用于GPIO或其他功能

  • 方向:引脚Mode设置为GPIO时,可以继续设置它是输出引脚,还是输入引脚

  • 数值:对于输出引脚,可以设置寄存器让它输出高、低电平

  对于输入引脚,可以读取寄存器得到引脚的当前电平

1.2 GPIO寄存器操作

  • 芯片手册一般有相关章节,用来介绍:power/clock,可以设置对应寄存器使能某个GPIO模块(Module),有些芯片的的GPIO是没有使能开关的,即它总是使能的

  • 一个引脚可以用于GPIO、串口、USB或其他功能,有对应的寄存器来选择引脚的功能

  • 对于已经设置为GPIO功能的引脚,有方向寄存器用来设置它的方向:输出、输入

  • 对于已经设置为GPIO功能的引脚,有数据寄存器用来写、读引脚电平状态

1.3 GPIO不同单板操作流程图


1.4 GPIO寄存器的2种操作方法:

本节后文3.1.2重复提及,不过此处更为详细,方便理解

原则:不能影响到其他位

1.4.1 直接读写:读出、修改对应位、写入

要设置bit n:

val = data_reg; val = val | (1<<n); data_reg = val

要清除bit n:

val = data_reg; val = val & ~(1<<n) data_reg = val;

 

1.4.2 set-and-clear protocol:(高效)

set_reg, clr_reg, data_reg 三个寄存器对应的是同一个物理寄存器,

要设置bit n:set_reg = (1<<n);

要清除bit n:clr_reg = (1<<n);

(视频笔记)

二、IMX6ULL的GPIO操作方法

2.1 GPIO的其他功能:防抖动、中断、唤醒

后续章节再介绍

2.2 IMX6ULL的GPIO操作方法

CCM: Clock Controller Module (时钟控制模块)
IOMUXC : IOMUX Controller,IO复用控制器
GPIO: General-purpose input/output,通用的输入输出口

就根据这些常用的寄存器,拿到芯片手册可以直接查找相应的寄存器来设置所需要的GPIO

2.3 IMX6ULL的GPIO模块结构

参考资料:网盘开发板配套资料“06_Datasheet(数据手册)/Core_board/CPU/IMX6ULLRM.pdf”中《Chapter 28: General Purpose Input/Output (GPIO)》。
有5组GPIO(GPIO1~GPIO5),每组引脚最多有32个,但是可能实际上并没有那么多。
GPIO1有32个引脚:GPIO1_IO0~GPIO1_IO31;
GPIO2有22个引脚:GPIO2_IO0~GPIO2_IO21;
GPIO3有29个引脚:GPIO3_IO0~GPIO3_IO28;
GPIO4有29个引脚:GPIO4_IO0~GPIO4_IO28;
GPIO5有12个引脚:GPIO5_IO0~GPIO5_IO11;

GPIO的控制涉及4大模块:CCM、IOMUXC、GPIO模块、本身,框图如下:
关于上图的使用及相关寄存器的使用,可以看链接:https://blog.csdn.net/u010168781/article/details/77855666

2.3.1 CCM用于设置是否向GPIO模块提供时钟

参考资料:网盘开发板配套资料“06_Datasheet(数据手册)/Core_board/CPU/IMX6ULLRM.pdf”芯片手册《Chapter 18: Clock Controller Module (CCM)》。
在原理图中找到引脚号后,在CCM的寄存器中寻找相应寄存器对其GPIO组进行是时钟使能
GPIOx要用CCM_CCGRy寄存器中的2位来决定该组GPIO是否使能。哪组GPIO用哪个CCM_CCGR寄存器来设置,请看下表。
GPIO组
所对应的CCM_CCGR寄存器
GPIO1
CCM_CCGR1
GPIO2
CCM_CCGR0
GPIO3
CCM_CCGR2
GPIO4
CCM_CCGR
GPIO5
CCM_CCGR1
CCM_CCGR寄存器中某2位的取值含义如下:
① 00:该GPIO模块全程被关闭
② 01:该GPIO模块在CPU run mode情况下是使能的;在WAIT或STOP模式下,关闭
③ 10:保留
④ 11:该GPIO模块全程使能
GPIO2时钟控制:

GPIO1、GPIO5时钟控制:
GPIO3时钟控制:
GPIO4时钟控制:

2.3.2 IOMUXC:引脚的模式(Mode、功能)

参考资料:芯片手册《Chapter 32: IOMUX Controller (IOMUXC)》。
对于某个/某组引脚,IOMUXC中有2个寄存器用来设置它:
① 选择功能:
 IOMUXC_SW_MUX_CTL_PAD_<PADNAME> :Mux pad xxx,选择某个pad的功能
 IOMUXC_SW_MUX_CTL_GRP_<GROUP NAME>Mux grp xxx,选择某组引脚的功能
某个引脚,或是某组预设的引脚,都有8个可选的模式(alternate (ALT) MUX_MODE)
比如:
注意:IMX6ULL中存Daisy chain的问题,多个引脚可以同时驱动一个模块,所以还需要再进行一次复用选择。
② 设置上下拉电阻等参数:
IOMUXC_SW_PAD_CTL_PAD_<PAD_NAME>:pad pad xxx,设置某个pad的参数
IOMUXC_SW_PAD_CTL_GRP_<GROUP NAME>:pad grp xxx,设置某组引脚的参数

比如:

2.3 GPIO模块内部

框图如下:


我们暂时只需要关心3个寄存器:

2.3.1 GDIR

① GPIOx_GDIR:设置引脚方向,每位对应一个引脚,1-output,0-input

2.3.2 DR

GPIOx_DR:设置输出引脚的电平,每位对应一个引脚,1-高电平,0-低电平

2.3.3 PSR

GPIOx_PSR:读取引脚的电平,每位对应一个引脚,1-高电平,0-低电平

三、怎么编程GPIO

3.1 读GPIO

翻译一下:
① 设置CCM_CCGRx寄存器中某位使能对应的GPIO模块 // 默认是使能的,上图省略了
② 设置IOMUX来选择引脚用于GPIO
③ 设置GPIOx_GDIR中某位为0,把该引脚设置为输入功能
④ 读GPIOx_DR或GPIOx_PSR得到某位的值(读GPIOx_DR返回的是GPIOx_PSR的值)

3.2 写GPIO

翻译一下:
① 设置CCM_CCGRx寄存器中某位使能对应的GPIO模块 // 默认是使能的,上图省略了
② 设置IOMUX来选择引脚用于GPIO
③ 设置GPIOx_GDIR中某位为1,把该引脚设置为输出功能
④ 写GPIOx_DR某位的值

     需要注意的是,你可以设置该引脚的loopback功能,这样就可以从GPIOx_PSR中读到引脚的有实电平;你从GPIOx_DR中读回的只是上次设置的值,它并不能反应引脚的真实电平,比如可能因为硬件故障导致该引脚跟地短路了,你通过设置GPIOx_DR让它输出高电平并不会起效果。