前言
前面介绍了GPIO的内部结构、相关寄存器、引脚复用情况以及使用注意情况,那么接下来需要做的就用GPIO控制相应的外设进行工作。
本文是在学习普中DSPF28335的基础上总结出来的,首先给出了控制LED点亮所用GPIO初始化出现的问题,之后指出具体的原因并给出GPIO正确的初始化方法。最后通过用GPIO驱动继电器再次验证自己的结论。
1. GPIO正确的初始化方法
1.1 LED初始化出现的问题
普中DSPF28335开发板上LED的硬件连接情况如图1所示。
以D1对应的GPIO的初始化为例进行探讨,D1的阴极连接到GPIO68,GPIO68在上电复位后默认配置为输入上拉,普中提供的初始化程序为:
EALLOW;
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO68 = 0;
GpioCtrlRegs.GPCDIR.bit.GPIO68 = 1;
EDIS;
GpioDataRegs.GPCSET.bit.GPIO68 = 1;
在未进行初始化之前,由于GPIO68被上拉,因此D1是不会亮的。初始化的过程中,在执行 “GpioCtrlRegs.GPCDIR.bit.GPIO68 = 1;” 语句后D1点亮,也就是说GPIO68在配置为输出后输出了一个低电平。在执行 “GpioDataRegs.GPCSET.bit.GPIO68 = 1;” 语句后GPIO68输出一个高电平,D1熄灭。
正常情况下,我们希望在初始化GPIO68的过程中其引脚的电平应一直保持为高电平,即一直保持D1熄灭,而现在出现的现象是:在初始化的过程中D1由熄灭→点亮→熄灭(注意:该现象是在调试的时候发现的,由于程序运行较快,因此正常运行的情况下,人眼捕捉不到D1点亮的那一瞬间),为什么会这样呢?
1.2 原因分析
GPIO68的内部结构图如图2所示。
在配置GPIO68为输出之前,其端口被上拉电阻拉高,因此D1不会被点亮;当GPIO68配置为输出后,GPCDAT寄存器中GPIO68对应位的被锁存的数据将会传输到引脚上,而上电复位后GPIO68对应位的被锁存的数据为0,因此导致GPIO68在配置为输出后,D1被点亮。
在执行 “GpioDataRegs.GPCSET.bit.GPIO68 = 1;” 语句后GPIO68输出一个高电平,D1再次被熄灭。
1.3 正确的初始化方法
通过上述的分析可以知道,导致GPIO68初始化过程中D1点亮的原因就是GPCDAT寄存器中GPIO68对应位的被锁存的数据为0导致的,因此有必要在配置GPIO68为输出之前配置GPCDAT寄存器中GPIO68对应位的被锁存的数据为1,故正确的初始化方法为:
EALLOW;
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO68 = 0;
GpioDataRegs.GPCSET.bit.GPIO68 = 1;
GpioCtrlRegs.GPCDIR.bit.GPIO68 = 1;
EDIS;
或者:
EALLOW;
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO68 = 0;
GpioDataRegs.GPCDAT.bit.GPIO68 = 1;
GpioCtrlRegs.GPCDIR.bit.GPIO68 = 1;
EDIS;
1.4 总结
对于LED的驱动控制而言,当初始化GPIO时,用普中的初始化程序和用正确的初始化程序本质上没有太大的区别,只是用普中的初始化程序会使LED提前点亮一次。然而,当外设是一个严格控制运行次数以及启停时间的器件时,用正确的初始化程序是极其有必要的!!
2. 继电器的初始化
普中DSPF28335开发板上继电器的硬件连接情况如图3所示。
可以看到,RELAY连接到GPIO15,开发板上电复位后,GPIO15为输入上拉,即引脚为高电平,高电平经ULN2003反向放大后输出低电平,这就使得继电器动作,这也就是为什么开发板一上电后,大家会听到啪的一声。
同样,普中继电器初始化程序为:
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0;
GpioCtrlRegs.GPAPUD.bit.GPIO15 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO15 = 1;
EDIS;
GpioDataRegs.GPACLEAR.bit.GPIO15 = 1;
前面说过,开发板在上电的一瞬间继电器就动作了,那么在执行 “GpioCtrlRegs.GPADIR.bit.GPIO15 = 1;” 语句后,GPIO15将输出一个低电平,该低电平经ULN2003反向放大后输出高电平,继电器恢复到初始状态。执行 “GpioDataRegs.GPACLEAR.bit.GPIO15 = 1;” 语句后,GPIO15将持续输出一个低电平,此时继电器将一直保持初始状态。
可以看到,开发板在继电器的硬件设计上本就存在问题,初始化的目的是使继电器恢复到初始状态。
总结
当GPIO作为通用输入输出口时,为了保证GPIO在初始化的过程中其驱动控制的外设不提前误动作,则需要在GPIO由输入改为输出之前配置GPxDAT寄存器或者GPxSET、GPxSET、GPxSET(x=A,B,C)寄存器。