国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

單片機模塊化多輸出值C函數(shù)的編程實現(xiàn)

2016-06-24 02:38:58李加明
關鍵詞:模塊化

李加明

(南京航空航天大學 2015級工科研究試驗班,南京 211106)

李加明

(南京航空航天大學 2015級工科研究試驗班,南京 211106)

摘要:單片機C標準編程不能實現(xiàn)函數(shù)的多個輸出值,目前常用的全局變量法雖可變通實現(xiàn),但破壞了函數(shù)的模塊化原則。本文突破一些常規(guī)思維,探索出兩種類型的多種模塊化多輸出值C函數(shù)的編程方法,并提出了新式的C函數(shù)語法規(guī)則,實現(xiàn)了較為規(guī)范通用的模塊化多輸出值C函數(shù)的編程。本方法編程思路新穎,具有較高的技術實用價值。

關鍵詞:C函數(shù);多輸出值;模塊化;MCU

引言

函數(shù)是單片機與嵌入式系統(tǒng)C語言程序的核心,標準C函數(shù)定義遵循y=f(x1,x2,…,xn)的數(shù)學形式,其中x1,x2,…,xn為代表函數(shù)各輸入值的形式參數(shù),y為函數(shù)唯一的輸出值。函數(shù)調(diào)用以輸入值實際參數(shù)代替形式參數(shù),經(jīng)運算后由return語句返回一個輸出值。

但在實際應用中,往往希望函數(shù)能有多個輸出值,例如用于工業(yè)控制的西門子S7-300/400可編程控制器程序中,其具有函數(shù)功能的FC、FB、SFC、SFB塊均可直接實現(xiàn)多輸出值。相比之下,標準C函數(shù)不能直接實現(xiàn)多輸出值,其功能存在明顯的不足。

當需要C函數(shù)有多輸出值時,可將一個函數(shù)分為幾個函數(shù)實現(xiàn),但從算法和效率考慮顯然極不合理。目前通常采用全局變量法變通實現(xiàn):由return語句正常返回一個輸出值,其余輸出值均由另設的全局變量獲得,但函數(shù)的模塊化原則遭到了極大破壞。

實現(xiàn)模塊化原則的任意多輸出值的C函數(shù)有很大的技術需求價值,值得探索。筆者在C語言編程學習中,摸索并試驗成功了兩大類多種模塊化多輸出值C函數(shù)的編程方法。各例程分別在軟件Keil C51V9.00與8位機STC90C516RD+、軟件CCS5.2.1.00018與16位機MSP430F6638、軟件Keil MDK5.14.0.0與32位機STM32F103RBT6平臺編譯下載并運行通過。其中,16位機MSP430F6638和32位機STM32F103RBT6芯片均具備直接的硬件在線運行調(diào)試功能,文中選取了對應的CCS5.2.1.00018和Keil MDK5.14.0.0軟件觀察硬件運行結果畫面。

51核8位機STC90C516RD+芯片自身不具備硬件在線運行調(diào)試功能,故在Keil C51V9.00軟件仿真運行成功基礎上添加代碼,通過其串行口向PC機發(fā)送硬件運行結果,由PC機側串行口軟件觀察硬件運行結果。對于大多數(shù)不具備硬件在線運行調(diào)試功能的8位單片機芯片,這樣的硬件運行調(diào)試方法是非常實用且必要的。文中給出了添加串行口功能的程序和PC機側串行口軟件XCOM觀察的硬件運行結果畫面。

1標準C函數(shù)的定義與調(diào)用

標準C函數(shù)返回一個輸出值的程序如下:

int func(int a,int b){/*函數(shù)定義*/

int y; y=a+b; return(y); }/*返回一個輸出值*/

int main(void){

int n1,n2;/*輸入*/

int sum;/*輸出*/

while(1){

n1=-132;n2=-12; sum=func(n1,n2);}

}/*函數(shù)調(diào)用*/

此例是標準C函數(shù)的定義與調(diào)用:函數(shù)形式參數(shù)表僅包括各輸入量,唯一輸出量由函數(shù)體return語句返回。函數(shù)采取“輸出量=函數(shù)名(輸入量表)”的格式定義與調(diào)用。

全局變量法實現(xiàn)標準C函數(shù)的多個輸出值如下:

int sum; /*全局變量sum:函數(shù)的另一輸出值*/

int func(int a,int b){/*函數(shù)定義*/

int subs;

subs=a-b;/*一個輸出值為局部變量subs*/

sum=a+b;/*另一輸出值為全局變量sum*/

return(subs);

}/*正常返回一個輸出值subs*/

int main(void){

int n1, n2;/*輸入*/

int sub;/*輸出*/

while(1){

n1=-132;n2=-12; sub=func(n1,n2);}

}/*由函數(shù)調(diào)用獲得一個輸出值sub,另一輸出值由全局變量sum獲得*/

此例為目前實現(xiàn)標準C函數(shù)多輸出值常用的全局變量法:函數(shù)func由return返回一個輸出值sub,另一輸出值sum也需由函數(shù)func計算,但函數(shù)只能返回一個輸出值,故只得將sum定義為在函數(shù)func與調(diào)用func的main程序中均有效的全局變量,變通實現(xiàn)函數(shù)func的兩個輸出值。

全局變量法可變通實現(xiàn)函數(shù)的多輸出值,因而應用廣泛。但此方法的函數(shù)體內(nèi)包括了作為輸出量的全局變量,破壞了函數(shù)“模塊自身內(nèi)聚,模塊間不耦合”的模塊化原則,致使函數(shù)無法獨立、難以移植共用,且極大降低了編程的可靠性與清晰性。

2維持標準C函數(shù)語法規(guī)則的改進編程

標準C函數(shù)只能由return直接返回一個輸出值,可對這個輸出值進行思路拓展:C語言有一種構造數(shù)據(jù)類型“結構”,能包含多個不同類型的數(shù)據(jù)成員,但對外卻可以作為一個數(shù)據(jù)單位出現(xiàn)。若運用return直接返回一個結構變量,也符合標準C函數(shù)的語法規(guī)則。函數(shù)定義時可將所需的多個輸出量匯集到一個專用結構變量中,調(diào)用后逐個拆分讀取返回的結構變量的數(shù)據(jù)成員,則可間接獲得函數(shù)的多個輸出值。

如下面的例程中,函數(shù)定義將各輸出量匯集定義到結構中,仍采用標準C函數(shù)的格式調(diào)用:OUT=calc(n1,n2),多個輸出值可由結構OUT的成員OUT.sum、OUT.sub、OUT.mul、OUT.div間接獲得。CCS5.21.00018與Keil MDK5.14.0.0觀察的硬件在線調(diào)試運行結果略——編者注。

typedef struct{

int sum; int sub;

unsigned int mul; unsigned char div;

}result;

/*定義專用結構result,匯集4個輸出量*/

result calc(int a,int b){/*函數(shù)定義*/

result c;

c.sum=a+b; c.sub=a-b; c.mul=a*b; c.div=a/b;

return(c); }/*返回一個結構變量*/

int main(void){

int n1,n2;/*輸入*/

volatile result OUT;

/*輸出,默認條件,CCS和KeilMDK編譯時此處需添加volatile,而KeilC51編譯時此處無需volatile,詳細見后文敘述*/

while(1){

n1=-132;n2=-12;

OUT=calc(n1,n2);}/*函數(shù)調(diào)用*/

}

對于51核8位機STC90C516RD+,由于芯片自身不支持硬件在線運行調(diào)試功能,故在Keil C51V9.00軟件仿真運行成功基礎上添加代碼,通過其串行口及printf()函數(shù)向PC機發(fā)送硬件運行結果,程序略——編者注。

由PC機側串口軟件XCOM觀察的硬件運行結果略——編者注。

本方法是維持標準C函數(shù)語法規(guī)則的改進方法,通過結構間接實現(xiàn)函數(shù)的多輸出值,結果正確、實用。標準C函數(shù)return不能直接返回多個輸出值,所以函數(shù)定義時需另行定義一個專用結構變量并將期望的多個輸出量以成員方式匯集定義到其中,函數(shù)調(diào)用后還需對返回的唯一結構變量進行成員拆分讀取才可獲得期望的多輸出值,編程與數(shù)據(jù)操作均顯復雜繁瑣。

3重新設計新式C函數(shù)語法規(guī)則的編程

標準C函數(shù)的形式參數(shù)表僅包括輸入量,輸出量只能依靠return返回,這正是其不能直接實現(xiàn)多輸出值的根源。為了從根本上解決問題,突破常規(guī)思維,放棄標準C函數(shù)的語法規(guī)則,重新設計可直接實現(xiàn)多輸出值的新式的函數(shù)定義與調(diào)用語法規(guī)則:①函數(shù)體中完全取消return語句,再不用return返回輸出值;②將函數(shù)期望的多個輸出量與輸入量共同納入形式參數(shù)表。

新式C函數(shù)的定義與調(diào)用形如:f(x1,x2,…,xn,y1,y2,…,yn),即“函數(shù)名(輸入量表,輸出量表)”格式,函數(shù)體內(nèi)完全取消return語句。采用新式函數(shù)語法規(guī)則,沒有原標準語法規(guī)則的不足限制,可靈活自由地實現(xiàn)多種通用規(guī)范的結構化多輸出值C函數(shù)的編程方法。

3.1數(shù)組法

下面的例程中,函數(shù)的多個輸出量用數(shù)組result[]定義,函數(shù)以calc(n1,n2,res)格式調(diào)用,輸出的res數(shù)組的元素res[0]、res[1]、res[2]、res[3]即為函數(shù)的多個輸出值。CCS5.21.00018與Keil MDK5.14.0.0觀察的硬件在線調(diào)試運行結果略——編者注。

void calc(int a,int b,int result[]){

/*新語法規(guī)則函數(shù)定義:輸入輸出量均納入形式參數(shù)表,取消return語句*/

result[0]=a+b; result[1]=a-b;

result[2]=a*b; result[3]=a/b;}

int main(void){

int n1,n2; /*輸入*/

int res[4]; /*輸出*/

while(1)

{ n1=-132;n2=-12; calc(n1,n2,res);}

} /*新語法規(guī)則函數(shù)調(diào)用*/

對于51核8位機STC90C516RD+,由于芯片自身不支持硬件在線運行調(diào)試功能,故在Keil C51V9.00軟件仿真運行成功基礎上添加代碼,通過其串行口及printf()函數(shù)向PC機發(fā)送硬件運行結果,程序略——編者注。

由PC機側串口軟件XCOM觀察的硬件運行結果略——編者注。

函數(shù)多個輸出值的數(shù)據(jù)類型相同時,只需定義一個數(shù)組;如多個輸出值的數(shù)據(jù)類型不相同,只需依據(jù)其數(shù)據(jù)類型歸類定義多個數(shù)組即可,數(shù)組的個數(shù)不受限制。

3.2“宏函數(shù)”法

本方法以帶參數(shù)的宏來定義類似函數(shù)功能的“宏函數(shù)”,宏的參數(shù)表包括全部輸入與輸出量。例程中,宏以CALC(n1,n2,sum,sub,mul,div)格式調(diào)用后即可直接獲得所需的多個輸出值sum、sub、mul、div。CCS5.21.00018與Keil MDK5.14.0.0觀察的硬件在線調(diào)試運行結果略——編者注。

#define CALC(a,b,summ,subs,mult,divi){

(summ)=(a)+(b); (subs)=(a)-(b);

(mult)=(a)*(b); (divi)=(a)/(b);}

/*新語法規(guī)則“宏函數(shù)”定義:輸入輸出量均納入形式參數(shù)表,取消return語句*/

int main(void){

int n1,n2;/*輸入*/

volatile int sum, sub, mul;

volatile unsigned char div;/*輸出,默認條件,CCS和KeilMDK編譯時此處需添加volatile,而Keil C51編譯時此處無需volatile,詳細見后文敘述*/

while(1){

n1=-132; n2=-11;

CALC(n1,n2,sum,sub,mul,div);}

} /*新語法規(guī)則“宏函數(shù)”調(diào)用*/

對于51核8位機STC90C516RD+,由于芯片自身不支持硬件在線運行調(diào)試功能,故在Keil C51V9.00軟件仿真運行成功基礎上添加代碼,通過其串行口及printf()函數(shù)向PC機發(fā)送硬件運行結果,程序略——編者注。

由PC機側串口軟件XCOM觀察的硬件運行結果略——編者注。

用宏代替函數(shù)有如下優(yōu)點:①函數(shù)的形式參數(shù)類型在定義時即已固定,實際參數(shù)類型必須由編程定義與之保持一致,不能自動匹配,編程不便;而宏的參數(shù)類型完全由調(diào)用時的實際參數(shù)確定,數(shù)據(jù)類型自然自動匹配,編程簡便。②函數(shù)調(diào)用要付出為形式參數(shù)分配臨時單元及現(xiàn)場保護恢復等額外代碼的時間開銷;而宏調(diào)用的實質是在編譯階段就已完成的代碼中展開,運行時完全不存在函數(shù)上述的額外時間開銷,故運算速度明顯快于函數(shù)。

宏的不足是:宏多次調(diào)用時,每次均會展開一套大部分相互重復的代碼,最終的程序代碼比函數(shù)調(diào)用方式的大。但目前單片機的程序存儲器足夠大,速度更為重要,所以,“宏函數(shù)”在運算速度及參數(shù)類型自動匹配方面具備獨特應用價值。

3.3指針法

研究C語言的指針,總結并成功驗證本方法:函數(shù)定義時,各輸出量形式參數(shù)均冠以符號*,以指針方式定義;函數(shù)調(diào)用時,各輸出量實際參數(shù)前均冠以地址符&。例程中,函數(shù)各輸出量形式參數(shù)為summ、subs、mult、divi,故定義格式為:

void calc(int a,int b,int *summ,int *subs,unsigned int *mult,unsigned char *divi)

函數(shù)各輸出量實際參數(shù)為sum、sub、mul、div,故調(diào)用格式為:

calc(n1,n2,&sum,&sub,&mul,&div)

CCS5.21.00018與Keil MDK5.14.0.0觀察的硬件在線調(diào)試運行結果略——編者注。

void calc(int a,int b,int *summ,int *subs,unsigned int *mult,unsigned char *divi){

*summ=a+b; *subs=a-b; *mult=a*b; *divi=a/b;}

/*新語法規(guī)則:輸入輸出量均納入形式參數(shù)表,取消return語句。函數(shù)各輸出量形式參數(shù)均以其指針定義;函數(shù)體內(nèi)采用對指針形式參數(shù)指向的值賦值的方式實現(xiàn)對各輸出量的賦值*/

int main(void) {

int n1,n2;/*輸入*/

int sum,sub;

unsigned int mul;

unsigned char div;/*輸出*/

while(1){

n1=-132; n2=-12;

calc(n1,n2,&sum,&sub,&mul,&div);}

}/*函數(shù)調(diào)用:各輸出值的實際參數(shù)sum,sub,mul,div前均冠以地址符& */

對于51核8位機STC90C516RD+,由于芯片自身不支持硬件在線運行調(diào)試功能,故在Keil C51V9.00軟件仿真運行成功基礎上添加代碼,通過其串行口及printf()函數(shù)向PC機發(fā)送硬件運行結果,程序略——編者注。

由PC機側串口軟件XCOM觀察的硬件運行結果略——編者注。

本方法概括為,當函數(shù)輸入為x1,x2,…,xn、輸出為y1,y2,…,yn、函數(shù)名為f 時,函數(shù)定義格式為:

f(x1,x2…xn,*y1,*y2…*yn)

調(diào)用格式為:

f(x1,x2…xn,&y1,&y2…&yn)

與數(shù)組法比較,不同數(shù)據(jù)類型的多個輸出量不需歸類定義;與“宏函數(shù)”法比較,是完全規(guī)范的函數(shù)定義與調(diào)用。相比前述的模塊化多輸出值C函數(shù)的編程方法,在函數(shù)定義與調(diào)用方面,本方法的編程風格最為規(guī)范化。

4兩類結構化多輸出值函數(shù)編程的比較

4.1維持標準C函數(shù)語法規(guī)則的改進編程

此方法的函數(shù)參數(shù)表仍僅包括輸入量,仍保留函數(shù)體return返回輸出量,故受到標準C函數(shù)語法不足的限制,編程與數(shù)據(jù)操作均顯復雜繁瑣,不是函數(shù)多輸出值編程的最好方法。

4.2重新設計新式C函數(shù)語法規(guī)則的編程

此類方法打破標準C函數(shù)語法的思路限制,取消了函數(shù)體return語句,將輸入與輸出參數(shù)全部納入?yún)?shù)表,依此方法重新設計的新式函數(shù)語法規(guī)則回避了原標準C函數(shù)的固有不足。

雖然無法推翻C語言的基本語法,但源自于C語言基本語法的標準C函數(shù)的語法規(guī)則并不是不可取代的,此類方法放棄了標準C函數(shù)的語法規(guī)則,可靈活自由地實現(xiàn)通用規(guī)范的模塊化多輸出值的C函數(shù)編程,是解決函數(shù)多輸出值編程困擾的最好方法。

5輸出變量定義增加volatile的試驗及體會

結構法和宏函數(shù)法列舉的16位及32位機程序,試驗中發(fā)現(xiàn)輸出變量需要添加volatile進行定義。在8位機Keil C51V9.00軟件編譯時,不添加volatile完全沒有任何問題,但在16位機CCS5.2.1.00018及32位機Keil MDK5.14.0.0軟件編譯時,如果不添加volatile,編譯時會產(chǎn)生報警,輸出變量會被意外地優(yōu)化省略掉。

各類單片機C軟件平臺對程序編譯時均會對代碼進行自認為最合理的優(yōu)化,但有時會優(yōu)化過度,導致結果意外錯誤。前例程序中遇到的報警就是優(yōu)化過度,經(jīng)試驗,對會被意外優(yōu)化省略掉的輸出變量增加volatile定義,問題即可解決。

volatile的功能簡單地說,就是防止編譯器對代碼進行優(yōu)化。在作為變量定義的修飾關鍵字時其功能為:①確保本變量不會被編譯器優(yōu)化而省略;②確保變量存儲在內(nèi)存,在生成的代碼中,每次的變量訪問均要重新從內(nèi)存直接讀值,而不是去訪問寄存器里的變量備份。使用volatile能徹底回避代碼過度優(yōu)化導致的意外錯誤,確保編譯結果的正確性。

同樣默認設置對相同C程序編譯,16位與32位機編譯系統(tǒng)比8位機編譯系統(tǒng)的編譯優(yōu)化力度要強得多,更易出現(xiàn)過度優(yōu)化問題。觀察MSP430、STM32單片機的各類例程,變量添加volatile定義的現(xiàn)象確實比51核單片機的多,也佐證了這個印象。試驗還發(fā)現(xiàn),變量添加volatile定義會微量增加存儲空間占用,雖然目前單片機存儲空間一般都足夠且對于存儲空間更多的16位與32位機影響更小,但一般還是希望volatile定義的變量越少越好。當編程難以判斷變量是否需要volatile定義時,可以設想先對這些變量均添加volatile定義,再逐步取消各自的volatile進行調(diào)試驗證,直至在確保結果正確前提下留下最少的volatile定義的變量為止。

結語

本文探索的編程方法具備良好通用的技術實用價值,其中,新式函數(shù)語法規(guī)則的編程較為規(guī)范,是模塊化多輸出值C函數(shù)編程的較好方法。

參考文獻

[1] 劉同法.單片機C語言編程基礎與實踐[M].北京:北京航空航天大學出版社,2009.

[2] 何欽銘.C語言程序設計[M].3版.北京:科學出版社,2010.

[3] 廖常初.S7-300/400 PLC應用技術[M].3版.北京:機械工業(yè)出版社,2011.

[4] 西門子.西門子S7-300/400編程手冊[EB/OL].[2016-01].http://www.gongkong.com/download/200709/63764.html.

李加明(本科),機電與控制方向。

(責任編輯:薛士然收修改稿日期:2016-01-05)

Li Jiaming

(2015 Engineering Research Experimental Class,Nanjing Aeronautics Astronautics University,Nanjing 211106,China)

Abstract:MCU C standard programming can not achieve multiple output value function.Although it can be solved by the global variate at present,but the function modular principle is destroyed.In the paper,two kinds of modular multiple output C function programming method are explored,and a new type of C function syntax rules is proposed.Then the more standardized and versatile programming for modular multiple output C function is achieved.The method has novel programming idea and excellent practical technic value.

Key words:C function;multiple output value;modularity;MCU

中圖分類號:TP368.1

文獻標識碼:A

猜你喜歡
模塊化
模塊化自主水下機器人開發(fā)與應用
基于模塊化控制系統(tǒng)在一體化教學中的應用
模塊化住宅
馬勒推出新型模塊化混動系統(tǒng)
考慮模塊化和退貨率的供應鏈大規(guī)模定制模型
ACP100模塊化小型堆研發(fā)進展
中國核電(2017年2期)2017-08-11 08:00:56
從模塊化中得到的二氧化碳
模塊化VS大型工廠
非模塊化設計四合一爐對流室的模塊化吊裝
機械制造技術模塊化教學改革研究
谷城县| 怀远县| 陵川县| 准格尔旗| 临城县| 江安县| 百色市| 扎赉特旗| 都江堰市| 济宁市| 马公市| 望都县| 长海县| 宿松县| 永修县| 竹溪县| 仁寿县| 东安县| 衡东县| 镇坪县| 太白县| 墨竹工卡县| 融水| 宜昌市| 左云县| 元谋县| 安福县| 西盟| 栖霞市| 乌兰察布市| 达尔| 砀山县| 当雄县| 英超| 麻城市| 尼玛县| 怀来县| 肇东市| 德化县| 北票市| 本溪市|