本帖最后由 KEVIN1973 于 2014-12-9 09:13 编辑
问题三:中断处理
在本项目中需要用到多个中断,其中就包括定时器中断。之前在STVD环境下开发时,只要新建一个工程,系统就会自动为你添加main.c和stm8_interrupt_vector.c这两个函数,而且stm8_interrupt_vector.c函数中,已写好了很多代码,实际使用时,只需要写下自己的中断处理函数,然后将函数名复制到中断号相对应的结构体中即可被调用,部分代码如下:
@far @interrupt void Timer2 (void)
{
//------ 清除中断标志
TIM2_SR1=TIM2_SR1 & 0xfe;
//------ 遥控信号计数
if(Remote1 || Remote2 || Remote3)
{
Count_Remote++;
if(Count_Remote>30)
Count_Remote=30;
}
else Count_Remote=0;
}
以上是我自己编写的中断处理函数,用以实现我想要的功能。
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap */
{0x82, NonHandledInterrupt}, /* irq0 */
{0x82, NonHandledInterrupt}, /* irq1 */
{0x82, NonHandledInterrupt}, /* irq2 */
{0x82, NonHandledInterrupt}, /* irq3 */
{0x82, NonHandledInterrupt}, /* irq4 */
{0x82, NonHandledInterrupt}, /* irq5 */
{0x82, NonHandledInterrupt}, /* irq6 */
{0x82, NonHandledInterrupt}, /* irq7 */
{0x82, NonHandledInterrupt}, /* irq8 */
{0x82, NonHandledInterrupt}, /* irq9 */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, NonHandledInterrupt}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, Timer2}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
上面这些,大部分是系统自带的代码,我只做了一个很小的改动:
把我的名为“Timer2”的中断处理函数放在了/*irq13*/的位置,
也许有人会问为什么是放在这个位置?
答案很简单:因为芯片STM8的资料中,中断向量表指出:TIM2的中断号为13。
好了,以上是STVD环境下的中断函数的编写,程序也通过了编译,可以正常工作。
然后,我把这个名为“stm8_interrupt_vector.c“的函数直接添加到IAR中使用时,编译无法通过,报错了,因为,@far是STVD编译器独有的寻址方式,表示在更大的范围内寻址,具体的寻址范围我记不清了,有兴趣的朋友可以查阅相关的芯片资料。
通过查找想关资料,我把程序做了如下改动:
#pragma vector = 15 //改动1,改动2
__interrupt void Timer2 (void) //改动3
{
//------ 清除中断标志
TIM2_SR1=TIM2_SR1 & 0xfe;
//------
//此处省略其它代码
}
以上共有3处改动,
改动1:用关键字#pragma vector=指出本中断处理函数指向的中断号
改动2:从原来的中断号13,改为15.这是因为IAR和STVD对中断号的定义方法不一样,简单地理解就是:把资料中提供的中断号+2,就是IAR中的中断号。
改动3:用关键字__interrupt 作为函数void Timer2 (void)的前缀,表示这是中断处理函数。此函数定义之后,他处无需再做声明,否则会报错。
注意:关键字__interrupt 前面是两个下划杠。
经过以上的处理,定时器Timer2的中断已经可以被响应了。 |