微控制器高階裸機程式設計(一)-- 資料驅動程式
阿新 • • 發佈:2018-12-13
我理解的所謂資料驅動程式的方法,簡單而言:將資料與程式分析,將程式碼邏輯的組織轉換成數字規律的統計。即將資料作為一個要處理的指令碼(當做資料庫),然後程式作為直譯器,將指令碼的內容用程式碼邏輯解釋出來,實現程式設計功能。
這就要求我們將程式碼邏輯分解出其內在資料關係,這樣我們就可以寫出與資料無關的函式,這樣的函式通用性很大,利於複用,耦合性也比較低,利於修改,且修改後不易出錯。
這樣的方法也有壞處,就是可讀性變差,解決的辦法就是多寫點關於邏輯的註釋。
下面舉個例子:(來自書籍--微控制器程式設計魔法師之高階裸程式設計思想,挺好的一本書,可以看看,可以去下載下載連結處,待有緣人! )
(1)要實現如下波形:
(2)我們 一般的實現方法:將上面分成16段(依據是波形存在不一樣的時候作為分界點),每段單獨分析。程式碼如下(使用51微控制器實現)。
#include <reg51.h> sbit P10=P1^0; sbit P11=P1^1; sbit P12=P1^2; sbit P13=P1^3; void delay(unsigned char d, unsigned int t) { unsigned int i; P1 = P1 & 0xF0 | d; for(i=0; i<t; i++); } main(void) { while(1) { delay(0x00, 749); // 階段1 delay(0x01, 251); // 階段2 delay(0x00, 749); // 階段3 delay(0x03, 251); // 階段4 delay(0x00, 749); // 階段5 delay(0x01, 251); // 階段6 delay(0x00, 749); // 階段7 delay(0x07, 251); // 階段8 delay(0x00, 749); // 階段9 delay(0x01, 251); // 階段10 delay(0x00, 749); // 論僇11 delay(0x03, 251); // 論僇12 delay(0x00, 749); // 階段13 delay(0x01, 251); // 階段14 delay(0x00, 749); // 階段15 delay(0x0F, 251); // 階段16 } }
(3)而採用資料驅動程式的方法:將每個階段分離出資料,然後用一個函式統一處理。本例中使用陣列來儲存代表各個階段的邏輯的資料,接著用一段程式碼就可解決,來程式碼如下:
#include <reg51.h> sbit P10=P1^0; sbit P11=P1^1; sbit P12=P1^2; sbit P13=P1^3; #define STAGES 16 unsigned char code P1_1234[] = {0, 1, 0, 3, 0, 1, 0, 7, 0, 1, 0, 3, 0, 1, 0, 15}; unsigned int code Dts[] = {749, 251, 749, 251, 749, 251, 749, 251, 749, 251, 749, 251, 749, 251, 749, 251}; void delay(unsigned char d, unsigned int t) { unsigned int i; P1 = P1 & 0xF0 | d; for(i=0; i<t; i++); } main(void) { int i; while(1) { for(i=0; i<STAGES; i++) delay(P1_1234[i], Dts[i]); } }
(4)好處:似乎沒有看出了,犧牲了易讀性,有得必有失,我們會的得到什麼?
再舉幾個例子:實現以下波形。對於這個波形,如果我們不採用資料驅動程式的方法,那麼相當於重寫(重新分階段,不難但是繁瑣),而使用這種高階的方法後,直譯器程式碼一個字母都不用改變。
資料驅動程式的程式碼如下:
#include <reg51.h>
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
#define STAGES 8
unsigned char code P1_1234[] = {0, 1, 3, 7, 15, 7, 3, 1};
void delay(unsigned char d, unsigned int t)
{
unsigned int i;
P1 = P1 & 0xF0 | d;
for(i=0; i<t; i++);
}
main(void)
{
int i;
while(1)
{
for(i=0; i<STAGES; i++)
delay(P1_1234[i], 500);
}
}
(5)總結:
雖然資料驅動程式碼這種高階的方法不是萬能,但是對於相似的程式設計要求,則給我們提供了一種可複用的方法,避免一些簡單卻繁瑣的工作任務。
還有, 用這種方法記得寫註釋,不然不僅別人看不懂, 就連幾天後的你再次回顧時,都不知道是怎麼寫出來的。