單片機里面有很多中斷資源,例如外部中斷、定時器中斷、串口中斷等,這些中斷資源應當用于處理相應的緊急事件,而不是順序執行的常規事件,所以在編寫中斷子程序的時候應當十分注意。 具體的事務處理語句不應放在中斷函數里面,中斷子程序中的語句應當簡潔明了,不應當有太多的語句。假如你在編寫中斷子程序的時候像在main函數中那樣寫一大串處理具體事務的指令的話,會在此中斷中占用太多的時間,假如當有其他低優先級的中斷信號來臨的時候也可能導致中斷丟失,發生程序的邏輯錯誤。所以,在中斷子程序中的指令語句應當做到最短。 中斷子程序中的語句不應當使用延時函數,不使用while、do-while、do-until等有等待延時功能的指令。在中斷子程序中使用while、do-while、do-until等指令也會導致單片機在執行過程中在該位置延時或者等待太長的時間,當其他中斷信號來臨的時候同樣也可能導致中斷丟失。 那么應該怎么做呢? 在編寫中斷子程序的時候,應當巧用全局狀態變量,在中斷子程序中只改變狀態變量值,在main函數中while(1)程序段內部判斷該狀態變量的值,根據狀態變量的值再分別執行對應的事務處理語句。這就像你接到一個電話要你辦某事,你也不能在一直接著電話把這件事做完吧,你需要把事情記下來,掛了電話再安排時間處理。 舉個例子,一個串口觸摸屏需要根據觸屏中按鍵來執行對應的操作,需要使用到串口中斷。假設觸屏在觸摸按鍵1時會發送數據A,觸摸到按鍵2時會發送數據B,那么我們可以定義一個全局狀態變量command: unsigned char command; 在串口中斷子程序中,根據接收到的不同串口數據改變command的值: void 串口1中斷函數() { switch (收到的串口數據) {case A: //假如收到按鍵1的動作,command賦值x1 {command=x1; break; } case B: //假如收到按鍵2的動作,command賦值x2 {command=x2; break; } … default: break; } } 在上面這個串口1的中斷子程序中,switch是一個條件選擇指令,當串口收到數據A,那么給command賦值x1, 當串口收到數據B,那么給command賦值x2。當然,上面的程序段只是一個說明的示意,不能直接復制編譯到單片機中運行,在實際工程中需要根據不同單片機程序的編寫規則進行開發。 接著在main函數中根據command的值執行不同的事務處理語句: main函數() { … while(1) { Switch(command) {case x1: //假如收到按鍵1的動作,執行事務處理1的程序 {事務處理1; break; } case x2: //假如收到按鍵2的動作,執行事務處理2的程序 {事務處理2; break; } default: break; } } } 按照這樣的程序,單片機在接收到觸屏發出的代表不同按鍵的串口數據時,在串口中斷子程序中改變全局狀態變量的值command,這個語句很少,執行時間也短。再到main函數中根據command的不同值分別執行非常耗時間的具體事務處理程序。這樣的程序分配,將使單片機運行高效而且合理。
捕獲.PNG (56.76 KB, 下載次數: 52)
下載附件
2019-9-13 11:39 上傳
中秋快樂! 沙鷗 樂山 2019.9.13
|