結構化MCU程式

1.目的

在小型專案中,通常MCU程式不會太過於龐大,但有時程式動輒也是上千行,再重新瀏覽過往所寫的專案程式時,發現一個很重要的結構化條件,即是多入口單一出口的概念。

在程式設計課程中,提到結構化程式設計時,均會提到一個單一入口,單一出口的概念,也就是程式只會從一個入口進入,固定從一個出口返回。這使用C語言時如果不使用goto的話基本上應該就不會破壞程式結構。

而這邊所要討論的是,對於資源的結構化設計,以常見MCU資源來說莫過於I/O腳位。

2.以I/O腳為例

假設今天使用某MCU進行專案設計,如果有一個Digital Output腳位用於指示燈顯示,可能會有類似這樣的一行程式:

LED_OUT = 1; //將LED腳位點亮

而這個LED控制權可能會交由多個程式進行控制,所以我們可能會有類似這樣下面的用法:

void foo(void)
	{
	...
	..
	..
	LED_OUT = 1;
	}
	
void yoo(void)
	{
	LED_OUT = 0;
	...
	..
	..
	}
	
void main(void)
	{
	
	while (1)
		{
		foo();
		yoo();
		}
	}

上述的用法看起來很正常,的確也是一個正確無誤的用法,但是此用法卻造成了LED_OUT這個Digital Output資源變成了一個種多入口多出口的情況。

20150917-1

這可能會造成什麼現象?假定今天專案持續擴增,使LED_OUT這隻腳的控制越來越複雜(可能有多個副程式需要使用),而在除錯時,就必須針對所有有用到LED_OUT的位置做檢查,這會增加除錯時的難度。

而假使今天LED_OUT在觸發前,可能需要增加一些固定的功能(例如被控制時閃爍兩下之類的功能),則就必須針對所有使用到LED_OUT的程式碼處新增功能,此時已經產生了重複程式碼的資源浪費。

所以我們可以為LED_OUT這個資源建立一個專屬的入口,而在這個入口處我們就可以有效的管理及追蹤使用情況,例如:

void ledCtrl(uint8 stu)
	{
	//擴充程式;新增動作
	LED_OUT = stu;
	}

void foo(void)
	{
	...
	..
	..
	ledCtrl(1);
	}
	
void yoo(void)
	{
	ledCtrl(0);
	...
	..
	..
	}
	
void main(void)
	{
	
	while (1)
		{
		foo();
		yoo();
		}
	}

此時,原有的LED_OUT已不再直接受各副程式控制,而各副程式如欲使用LED_OUT資源時,則都必須透過ledCtrl呼叫才可使用,而在除錯時,我們就可以將目標只注意到ledCtrl上,也可以有效的控管LED_OUT的使用情況。

20150917-2

3.其他

其實在MCU程式設計是很底層的硬體程式設計,如果可以將資源透過結構式的想法來操作,也可以大大的增加程式設計時的效率,以及日後維護的難度也會相對減低許多。因為早期我在寫的程式沒有投入這個概念時,則現在維護起來相對的比較吃力(無限Ctrl+F),在修改除錯時真的還是挺傷腦筋的。

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料