不知道有木有人有这种感脚,即如果你把技术当作一种专业的爱好,而不是养家糊口的工具(咳咳,有点站着说话不嫌腰疼了,呵呵,毕竟我还没到养家糊口的那个时候),你往往会沉迷其中,往往会因为一点小收获、一点小成就、一点小发现而感到欣喜,对这一类人来说,收获知识所带来的自身素质的提高是最大的满足,他们把技术当作爱好,从中收获知识、优越感、自信等等,哈哈,不知道看到本篇的又中枪的没。好了,不扯这些了,进入正题吧:
中断的使用方法我在从零系列第九篇里说的差不多了,今天本篇就算是补充一种另类的使用方法,小技巧而已,不过相信一些人会喜欢,哈哈。在以前我介绍过Kinetis的启动代码部分,在里面我曾经介绍过,Kinetis为了提高中断执行的速率,在启动代码部分把中断向量表copy了一份放到RAM里面,然后把向量中断寄存器重定位到该部分向量表,这样一定程度上缩短了Kinetis执行中断的时间,这部分的功能代码如下所示(在启动代码里可以找得到):
/* Copy the vector table to RAM */
if (__VECTOR_RAM != __VECTOR_TABLE)
{
for (n = 0; n < 0x410; n++)
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
}
/* Point the VTOR to the new copy of the vector table */
write_vtor((uint32)__VECTOR_RAM);
既然Kinetis的中断执行机制是这样的,那么我们可以这样想,既然Kinetis执行中断服务的时候是根据发生中断的中断向量号查找到其在中断向量表的位置(即根据n找到_VECTOR_RAM[n]的内容)然后读出目标中断服务程序(即ISR)的地址然后跳到该地址执行目标中断服务函数,以PORTB口中断为例,那么我们在加载中断服务函数地址到向量表的时候完全可以不采用以前我说的那种方法(以前是#define VECTOR_104 PortB_ISR),而是采用如下这种方式,即我们直接更改RAM中向量表的内容(即把default_isr替代为我们自己定义的中断服务函数的地址,这样可以达到同样的目的):
extern uint32 __VECTOR_RAM[]; //Get vector table that was copied to RAM
__VECTOR_RAM[104]=(uint32)PortB_ISR; //replace ISR
呵呵,其实通篇说了这么多话,上面这两行代码才是本篇的目的所在,即核心技巧就在这里了,我想表达意思也很明白,就是不要小看这两行代码,虽然很简单,但它表达的是一种思想,即如果我们把内在的机制领悟透彻了,你就会明白,有些东西并不是一成不变的,在保证功能的时候,随心所欲的改变才说明你完全懂它了...