COLDFIRE系列处理器的中断使用和其他单片机(如9S12)并不相同,可以说功能更加强大,但是使用起来要复杂些。在FREESCALE论坛上,问的最多的问题也就是“进不了中断的问题”,这也是COLDFIRE入门学习最棘手的问题之一。
在COLDFIRE上使用中断的流程基本是这样的: 写SR开全局中断--->设置某中断LEVEL和PRIO,写屏蔽码--->编写中断服务程序,写中断向量表--->初始化并运行程序 以下代码均以使用PIT0产生每100ms一个中断为例。 1、写SR开全局中断: 这个功能其实完全可以通过一句话来完成,在这里,必须写SR的16/17/18三位为0,才可以打开全局中断。这是初学者容易忽略和犯错误的问题。有些朋友已经设置好中断优先级和等级,打开屏蔽,初始化好并且做好向量表,发现还是无法进入中断,问题就是出在了这里。 大家需要注意的是,COLDFIRE单片机开始运行时,SR中16/17/18三位的值都是1,这样是关闭了所有中断的,所以要使用中断,必须把这三位都设置为0,这就相当于一个总闸,如果你总闸不开,你怎么设置中断都是不能够运行的。 用这句话来实现: asm{ move.w #0x2000,SR }; 有了这句话写在MAIN函数的首位,全局中断就打开了。 2、设置中断LEVEL和PRIO: COLDFIRE可以管理中断的LEVEL和PRIO,必须设置它才可以使中断工作。这点的具体内容可以在DS的中断控制器那章找到。在这里就不再具体讲了,以PIT0为例,代码如下: MCF_INTC0_ICR55 = MCF_INTC_ICR_IL(0x3) | MCF_INTC_ICR_IP(0x3); 这里设置的中断LEVEL为3,中断PRIO为3,这个都是用户可以指定的。设置好LEVEL和PRIO,还必须打开中断屏蔽码,否则中断也无法工作了。以PIT0为例,代码如下: MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_INT_MASK55; //Open the local mask MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASKALL; // Open the maskall 这样这部分工作就完成了。 3、编写中断服务程序,写中断向量表: 中断服务程序中一般要清除中断标志,这点人人皆知了,但是在CW IDE 6.3/4中,声明中断服务程序有一个格式,以PIT0为例,必须写成: __declspec(interrupt:0) void PIT0_isr(void) { …… } 函数名可以自己起。跟9S12使用interrupt关键字有所不同。 另外需要写中断向量表,一般在“xxxx_vector.s”文件中,到对应位置,把定义的中断服务程序名写入。这里要注意的是,函数名前必须加下划线“_”,这个是指对应的汇编程序,代码如下: vector117: .long asm_exception_handler vector118: .long asm_exception_handler vector119: .long _PIT0_isr vector120: .long asm_exception_handler vector121: .long asm_exception_handler 在本文件中这样写还是会提示错误,因为中断服务程序是在其他文件中编写的,必须声明它为外部函数,这样在此文件的前一部分加入: .extern _PIT0_isr 就可以了。 4、初始化并运行程序: PIT0的初始化和ISR的编写,在本系列学习文章的第五篇都有了。有兴趣的可以翻阅一下以前的文章。 好,这就是使用COLDFIRE中断的流程,不仅仅是PIT0,使用其他中断也都是大同小异,希望能够大家带来帮助。 到此,COLDFIRE学习系列的入门级文章就结束了,其他模块其实也没什么好写的。下一个系列将推出比较高级一点的文章,主要重点会放在嵌入式操作系统和以太网上。谢谢关注。 |
|
来自: WUCANADA > 《embedded》