hi大家好~这期我们来学习按键控制LED灯的例程,本质上是检测GPIO输入。
我们按照第一期导入官方例程的方法导入这个例程,并将其设置为Active,再关闭掉所有已经打开的其他工程的代码。
可以看一下,GPIO_LED_Button.c中的代码,在这里我把注释都去掉了方便大家阅读:
#include "IfxPort.h"
#define LED &MODULE_P00,5 /* Port pin for the LED */
#define BUTTON &MODULE_P00,7 /* Port pin for the button */
void init_GPIOs(void)
{
IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinMode(BUTTON, IfxPort_Mode_inputPullUp);
}
void control_LED(void)
{
if(IfxPort_getPinState(BUTTON) == 0)
{
IfxPort_setPinState(LED, IfxPort_State_low);
}
else
{
IfxPort_setPinState(LED, IfxPort_State_high);
}
}
可以看到,分别对LED和按键所在的Pin脚进行初始化,LED和上期一样是推挽输出,而按键设置为了上拉输入。
我们来看下按键部分的原理图:
首先在实物图上可以看到按键对应的就是P07没有问题:
在原理图中也可以看到,P07是上拉输入,当按键按下闭合时会接地变为低电平。同时大家可以看到,P07本身就是外部上拉了,不需要我们内部再设置为上拉,但是例程为了通用性还是设置为了内部上拉:
那配置GPIO的源码和寄存器在第一期都已经讲过了,就不再赘述,我们继续往下看:

void control_LED(void)
{
if(IfxPort_getPinState(BUTTON) == 0)
{
IfxPort_setPinState(LED, IfxPort_State_low);
}
else
{
IfxPort_setPinState(LED, IfxPort_State_high);
}
}
可以看到逻辑非常简单,检测到按键按下就亮灯,否则就熄灭。上一期我们知道LED是低电平驱动的,所以这里亮灯给low。
设置引脚高低电平的寄存器我们在上一期也带大家看过了,那实际上只有下面这个读取的操作是上一期没有提到的:
IfxPort_getPinState(BUTTON) == 0
我们进入这个函数内部来看:
IFX_INLINE boolean IfxPort_getPinState(Ifx_P *port, uint8 pinIndex)
{
return (__getbit(&port->IN.U, pinIndex) != 0) ? TRUE : FALSE;
}
可以看到有一个getbit方法,读取的结果如果是1的话就返回true,否则返回false,而这个方法的第一个参数我们需要留意,它提取了P00的IN寄存器,我们跳转来看看这是什么寄存器:
Ifx_P_IN IN; /**< \brief 24, Port Input Register */
我们在手册的13-68页可以很容易找到这个寄存器:
在13-52页也可以看到这个寄存器的详细内容,可以看到每一位就是对应各个端口输入的高低电平了,同时可以看到手册里说明这是一个只读寄存器,并且不论这个引脚被配置成了输入还是输出都会取到当前的电平值。
这里我再带大家看看寄存器的地址,在代码里可以看到P00的基地址是0xF003A000:
#define MODULE_P00 /*lint --e(923)*/ (*(Ifx_P*)0xF003A000u)
在P00的结构体中, 可以看到IN寄存器的偏移量是0x24:
那么两者相加,就是0xF003A024,跟手册里正好对上:
我们最后回顾一下CPU0的main函数:
init_GPIOs(); /* Initialize port pin for push button and LED */
while(1)
{
control_LED(); /* Check the push button and set the LED accordingly */
}
就是简简单单的初始化,然后在主循环里一直检测按键,大家可以编译然后下载到板子里试试,记得要先设置Debugger!