微控制器程式設計和pc端程式設計有所不同,筆者根據已有的粗淺的程式設計經驗,列寫幾個認為比較重要的點。
首先對文中的名詞作適當的約定。文章的「事件」可理解為「中斷」,每乙個「中斷」發生時,isr將傳送對應於該「事件」的「訊息」;「事件」通常理解為「非同步事件」,為了方便,即使是固定週期的定時中斷,亦稱為「非同步事件」。
中斷服務程式(isr)內不處理事務(或資料),將程式流程轉移到主程式
isr僅負責傳送事件標誌,以通知主程式(不稱其為「應用程式」的原因是,文章的總結基於不使用rtos的假定)發生了非同步事件。但這並非絕對,在一些需要極精準的定時控制的或者資料必須在事件發生時馬上被採集或處理的場合中,我們仍難以避免在isr中作資料採集、處理或者執行控制任務,或者兼有之,但通常我們應保證在這種情況下isr的執行時間仍然非常短。
如何通知主程式非同步事件發生了呢?這裡列出三種方案。
利用一組標誌變數(或者為了節省儲存空間,使用標誌位),通過對標誌變數的置位、復位來實現事件的通知和撤銷(表明事件已被處理)。該方案偽**如下
int main()
... }
return 0; }
void isr()
這一方案的偽**僅表示了單個事件的情況,事實上事件(數量)可以任意定義。
方案二是上一方案的改進,考慮事件連續發生導致微控制器來不及處理之的情況,我們利用佇列來暫存未被處理的事件資訊(若沒有儲存未被處理的事件的緩衝區,那麼微控制器將丟失這些事件的資訊,從而導致有些事件不被處理)。在這一方案中,我們依然在isr中傳送時間通知,但此時不再是置位某一標誌,而是往事件佇列新增事件資訊。在主函式的死迴圈中,則不斷地檢查事件佇列是否為空,一旦非空,取出其中的事件資訊,交由事件判斷和事件處理函式處理。這個方案保證了即使在極短的時間內連續發生兩次或者數次同樣的事件,依然不會丟失資訊。
在嵌入式裸機程式中,佇列通常用迴圈陣列實現,而非鍊錶。
這一方案的靈感源於我學習mfc的時候了解的「訊息(佇列)」機制。
方案二的偽**如下
intmain()
} return0; }
voidisr0()
voidisr1()
...
方案三是使用實時作業系統(rtos)。對於rtos的講述,三言兩語難以清楚明白,省略之。
除非使用了低速外設(如低端字元液晶),拒絕一切阻塞性延時
當你是新手,阻塞性延時意指微控制器在執行延遲程式時,不再處理任何事務,直到延時完成。相應地,非阻塞性延時則是指在該種延時操作進行時,cpu並非原地踏步等待時間到,而是將程式流程切換至其它位置。非阻塞性延時有賴於任務切換,通常需要rtos的支援,在裸機程式難以實現。
用巨集定義和條件編譯實現易修改、配置和移植效能
敏銳察覺程式中任何可能需要修改的引數/變數,用巨集定義代替立即數。在具規模的程式中,易修改效能尤為重要,因此對此不可等閒視之。利用巨集定義和條件編譯結合實現便捷地裁剪和配置程式/功能。
合理地將程式結構設計成模組化、層次化的架構,對未來實現**重用和移植大有裨益。
注意計算方式對執行效率的影響
舉個例子,如果我們要用乙個無符號整形對2整除,請使用移位操作而非"/"操作符,即使編譯器也會優化。
isr中不傳送資料塊、不延時
利用串列埠傳送資料是常用的除錯/監控方式,但是請勿在isr中傳送大量資料,以低波特率更加不可取。
統一介面
當我們熟悉數個型號的微控制器時,我們經常會考慮在不同的微控制器之間移植同乙個程式框架,從而提高開發效率。如果統一底層驅動的介面、串列埠除錯用的通訊協議等等,將更加得心應手。
實不相瞞,第一次寫部落格,文筆與邏輯實在不怎麼樣,讓您見笑了。
微控制器選用注意事項
在實際的工作中,經常出現因為rd人員的設計 疏忽 導致試產失敗。這個疏忽要加上引號,是因為這並不是真正的粗心造成的,而是對生產工藝的不熟悉而導致的。為了避免各位做rd的朋友出現同樣的錯誤,或為了更好的完成試產我對一些常見的問題點做一些總結,希望能對大家有所幫助。1 ic封裝的選擇。現在電子產品都在向...
8051核心微控制器程式設計注意事項
1 巨集定義。例如 define debug log printf define degug log printf 2 51核心的堆疊空間只在pdata區。程式設計中,對於函式巢狀較多層,容易引起堆疊溢位的情況 程式執行至0xffff位址 因而需要減少函式的巢狀。3 51核心程式設計注意區域性變數和...
微控制器嵌入式程式設計的五個注意事項
在微控制器程式設計的過程中,如果一名設計者能夠同時掌握多門程式語言,那麼這名設計者肯定是一位非常優秀的人才。但是想要同時精通彙編 c語言 c 這三門語言實在是太難了,很多初學者在其中一門的學習中就已經到處碰壁,苦不堪言。本文特意為大家整理了擁有嵌入式程式設計領域多年工作經驗的工程師意見,彙總成了一篇...