2013-04-22 95 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()函數。