2013-04-22 100 views
0

我使用Hi-Tech-PICC v9.65PL1编程C编程PIC16F876。将结构传递给ISR

对于中断我使用的结构:

void interrupt isr() { 
    if (T0IF) { 
       //Do STUFF 
    T0IF = 0; 
    } 
} 

我试图找出如何传递对象到ISR。我知道我可以简单地将对象变成全局变量,但这不是重点。我已经看到它用另一种架构在C中完成。由于我使用C,当我说一个对象,我指的是一个typedef结构,如:

typedef struct { 
    volatile char state; 
    rtc_t rtc; 
    shiftReg_t shiftReg; 
} clock_t; 

我的目标是让ISR的用clock_t结构中更改“状态”。

有人可以解释一下这样做有什么关系吗?

+0

你在提及的那个不同的体系结构上做了什么? – 2013-04-22 18:12:00

+0

http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/prog/inthandler.html,在标题为“更新公共数据结构”的标题下,大约在页面的中间。 – 2013-04-22 18:13:45

回答

1

从我可以看到,鉴于体系结构没有那么不同,您需要执行原子操作来更改clock_t结构中的状态。

那么说,void interrupt isr()可以带参数吗?如果是的话,那么你可以使用本地clock_t结构,否则最好的选择是去与全局变量。

如果ISR不接受参数,可以按去:

int main() 
{ 
    clock_t noteState; 
    .... 
    isr(&noteState); 
    .... 
} 

和ISR定义::

void interrupt isr(clock_t *tmp) 
{ 
    interruptDisable(); // I am guessing that T0IF is a global value, yes? 
    /* Perform operation */ 
    tmp->state = newState /*(whatever you choose to set)*/ 
    interruptEnable(); 
} 

然后,您可以在未来:)

0
重用noteState

在某些情况下,如果变量可以在一个指令中更新,如增量,递减,只读,只写,IRQ中的变量更新为“原子”。因此,您不需要禁用并在IRQ Handler上为裸c代码启用中断。有些OS编码器为这些情况提供了函数,以确保该变量是用单条指令更新的。 OS函数示例:http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/a/atomic_add.html

对于其他一些情况,读取/修改/写入操作在大多数cpus上不是原子的(尽管它们在某些CISC cpus上是/ atomic),并且在访问多个变量时不能保证原子性。对于这些情况,在变量更新之前使用enter_critical_section()和变量更新之后使用exit_critical_section()函数。对于bare-c(非操作系统)的情况,这些函数简化为interruptEnable()和interruptDisable()函数。