Freescale家芯片的Keyboard Interrupt的配置

操作环境:CodeWarrior V10.5

使用芯片:MKE02Z32VLC(后简称KE02)、S08QB8CWL(后简称S08QB8)

1.1 选择KBI模块或Init_KBI模块

KE02和S08QB8等芯片都有KBI外设。但是由于PE的设计的原因,某些芯片,例如KE02,无法添加KBI模块,只能添加Init_KBI模块;而另外一些芯片,例如S08QB8,可以添加KBI模块也能添加KBI_Init模块。

由于KBI模块的Component Level为Low Level Component,而Init_KBI的为Peripheral Initilization。而Low Level Component的Methods里有Init()函数(初始化函数)以外的其他函数,所以我们更倾向于使用KBI模块,而不是Low Level Component模块(简而言之就是有KBI就用KBI,没有再用Init_KBI,两个一起会冲突!)

1.2 配置KBI模块

如果在1.1中选择了KBI模块,则继续往下看(以S08QB8举例)。

  • Pins右侧可以加减使用的管脚数。
  • 各个管脚的中断触发方式通过选择“Generate interrupt on”和各个管脚的“Invert interrupt trigger condition”来选择。先选择“Generate interrupt on”,此为各个管脚公用。再对个别管脚选择“Invert interrupt trigger condition”。(“Invert interrupt trigger condition”选项仅有HCS08,ColdFireV1,RS08系列芯片和部分HC08衍生芯片支持。)
  • S08QB8还为KBI模块提供了一个中断:Vkeyboard。当任何一个按键触发了条件,就会进入该中断对应的ISR。即KBI_OnInterrupt()。
  • 读取各个按键的状态时,可以使用GetVal()函数,将其复给一个char变量即可。

    上文中所对应的配置后的GetVal函数如下。可以看出,该函数会返回一个字节。字节从低位到高位分别为pin0~pinN的输入值。其进行一系列位操作之后,输出该字节。

byte KB1_GetVal(void)
{
  byte value = 0x00U;
  value |= PTAD & 0x01U;
  value |= ((PTAD & 0x04U) >> 1);
  value |= (byte)((PTBD & 0x01U) << 2);
  value |= (byte)((PTBD & 0x04U) << 1);
  return value;
}

但是如果不是用如上中的配置,例如将pin0~pin3设置成PTA0~PTA3,则PE会非常智能的只在KBI.h文件中生成一个宏命令。如下所示。实际结果也是将pin0~pinN从低到高排成一个字节。

#define KB1_GetVal() ((byte)(PTAD & 0x0FU))

1.3 配置Init_KBI模块

如果在1.1中选择了Init_KBI模块,则继续往下看(以KE02举例)。

  • Init_KBI模块和KBI模块不同之处在于Init_KBI的管脚号对应的Init_KBI的pin号是固定的。PTB1只能是Input pin5,不能是其他的Input pin。想使用别的Input pin需要对其使能。
  • 如果将鼠标移动到“ISR name”上并悬停就会出现提示。
  • 提示说明想要用KBI,中断就要自己写了!自己写中断的过程大致如下。

1.在KBI.h中声明中断,比如像这样声明。

PE_ISR(KB1_Interrupt);

2.在KBI.c中实现中断,比如如下。

PE_ISR(KB1_Interrupt)
{
  IRQ_PDD_ClearInterrupt(IRQ_BASE_PTR);		//clear the interrupt flag
  //do whatever u want here XD
}

3.修改Vector.c中的中断向量表,比如进行如下修改。

(tIsrFunc)&Cpu_Interrupt,/*0x28  0x000000A0-ivINT_KBI0 unused by PE */

修改为

(tIsrFunc)&KB1_Interrupt,/*0x28  0x000000A0-ivINT_KBI0 unused by PE */

4.All done!

后记:实际上也没啥难得...就是后面自定义中断的时候如果没写过可能不太好写,如果有点经验的人基本上自定义中断都不会碰见什么问题...