1 首先打开源代码userkey.cpp
static inline void GetKeyValues(BYTE values[])
{
values[0] = !(g_pGPIOReg->GPNDAT & 0x01U);
values[1] = !(g_pGPIOReg->GPNDAT & 0x02U);
values[2] = !(g_pGPIOReg->GPNDAT & 0x04U);
values[3] = !(g_pGPIOReg->GPNDAT & 0x08U);
values[4] = !(g_pGPIOReg->GPNDAT & 0x10U);
values[5] = !(g_pGPIOReg->GPNDAT & 0x20U);
values[6] = !(g_pGPIOReg->GPLDAT & (1U<<11));
values[7] = !(g_pGPIOReg->GPLDAT & (1U<<12));
}
分析g_pGPIOReg->GPNDAT & 0x01U是什么意思。
查看原理图,找到BUTTON 的位置。
可以看到KEY1...kEY8分别由IO:EINT0..EINT5,EINT19,EINT20控制。
当没有键按下的时候,上拉高电平,当有键按下时,为低电平,所以可以明白
values[0] = !(g_pGPIOReg->GPNDAT & 0x01U);中的!的作用。
现在分析KEY0,也就是EINT0
观察可见,EINT0由管脚XEINT0/KPROW0/GPN0控制,也就是该管脚应该配置为输入,那么怎么样得到管脚的状态值?
查看6410的数据手册,可以看到GPNCON,GPNDAT,GPNPUD的作用与寄存器地址。
在手册中这样解释到: GPNCON (0x00~0xff)
00 = Input 01 = Output
10 = Ext. Interrupt[0] 11 = Key pad ROW[0]
若GPN0为输入则GPNCON&=0X00;输出GPNCON&=0X01;中断GPNCON&=0X02;键盘行列:GPNCON&=0X03
当定义好了GPN0的IO功能后,那就可以从GPNDAT读出数据了
在数据手册中,GPNDAT:
GPN[15:0] [15:0] When the port is configured as input port, the corresponding bit is the pin state.
When the port is configured as output port, the pin state is the same as the
corresponding bit. When the port is configured as functional pin, the undefined
value will be read.
意思为当管脚选中为输入,那么就可以从相应位读取管脚状态值,当管脚被设为外设,那么将不确定读取值
所以我们可以通过GPNDAT&0X01来得知GPN0的状态。
由此可以明白values[0] = !(g_pGPIOReg->GPNDAT & 0x01U);的意思。
那么还有EINT19与EINT20呢,在原理图找到对应管脚XhiADDR11/IOWR_CF/EINT19/GPL11,即GPL11,同理可知其意义。
下面介绍static DWORD UserKeyProcessThread(void)