转: i.MX的GPIO控制

来源:互联网 发布:淘宝v任务入口 编辑:程序博客网 时间:2024/05/28 17:05

i.MX25系列的GPIO口大多是复用口,如果我们想将某IO口设置为输入或输出,首先需通过复用配置寄存器将该IO口配置为GPIO,然后再配置GPIO的相关寄存器。

通过配置SW_MUX_CTL寄存器选择IO口的工作模式,每一个管脚都对应一个SW_MUX_CTL寄存器,具体通过如下描述:

IOMUXC_SW_MUX_CTL_PAD_<Pin_Name>

这里<Pin_Name>为管脚名。寄存器对应描述见表1

 

 

1SW_MUX_CTL寄存器描述

通过配置SW_PAD_CTL设置IO口的驱动电压,回转率,驱动强度,开漏,上拉,DDR类型等。有些管脚需要通过SW_PAD_CTL_GRP设置一组IO口。SW_PAD_CTL寄存器通过如下描述:

IOMUXC_SW_PAD_CTL_PAD_<Pin_Name>

这里<Pin_Name>为管脚名。寄存器对应描述见表2及表3

 

2SW_PAD_CTL寄存器描述()

 

3SW_PAD_CTL寄存器描述()

这里DDR相关管脚比较特殊,其寄存器描述有所不同,见表4所示:

 

4DDR对应SW_PAD_CTL寄存器描述

有些IO口需要成组设置,具体各自寄存器设置可查看i.MX25手册。

关于各IO口具体复用的功能,以及如何设置SW_MUX_CTL来决定IO口模式,可查看i.MX25手册的表4-18[IMX25RM.pdf]

例如我们需要设置某IO口为输入或输出,首先通过上面的方法设置完复用功能相关寄存器,接着要设置GPIO的相关寄存器。每个GPIO都对应有8个寄存器设置,在程序中通过结构体封装如下:

typedef struct

{

    UINT32 DR;                           // lqm:Data register

    UINT32 GDIR;             // lqm:GPIO Direction register.       0:input 1:output

    UINT32 PSR;                         // lqm:Pad sample register. read only

    UINT32 ICR1;              // lqm:interrupt control register1

    UINT32 ICR2;              // lqm:interrupt control register2

    UINT32 IMR;                         // lqm:interrupt mask register

    UINT32 ISR;                          // lqm:interrupt state register

    UINT32 EDGE_SEL;   // lqm:edge select register

} CSP_GPIO_REGS, *PCSP_GPIO_REGS;

其中DR表示数据寄存器,也就是IO口的高低电平。GDIR表示方向寄存器,0表示输入,1表示输出。PSR为只读寄存器,用户通过读取该寄存器值获取IO口的状态。ICR1ICR2为中断控制寄存器,表明了中断触发方式;IMR为中断屏蔽寄存器,ISR为中断状态寄存器,EDGE_SEL为边沿选择寄存器。

GPIO口设置为GPIO模式时,若设置为输出,则DR[n]返回该寄存器本身设置的值,若设置为输入,则DR[n]返回该脚外部输入的信号值。

GPIO设置为非GPIO模式时,若设置为输出,则DR[n]返回该寄存器本身设置的值,若设置为输入,则DR[n]固定返回0

ICR1描述了GPIO[0:15]的中断触发方式,具体见表5

 

5:中断触发方式

ICR2描述了GPIO[16:31]的中断触发方式,具体见表6

 

6:中断触发方式

IMR对应位为0时,表示屏蔽对应GPIO的中断功能,为1时表示使能对应中断功能。ISR对应位为1时,表示对应GPIO中断产生,需要通过软件清零相应位。为0时表示中断未产生。

EDGE_SEL用于设置GPIO是否使用边沿触发,若对应GPIO口设置为1,表示相应GPIO采用上下沿触发,前面的ICR1ICR2的设置将变得无效。当EDGE_SEL的对应位恢复为0时,ICR1ICR2的相应位才会变得有效。

不论GPIO设置为输入还是输出,在读取GPIO对应的电平值时,都读取PSR的值,尽量不要读取DR的值。而设置IO口的电平时通过设置DR的值来实现

原创粉丝点击