<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 代碼的移植性問(wèn)題

代碼的移植性問(wèn)題

作者: 時(shí)間:2016-11-17 來(lái)源:網(wǎng)絡(luò ) 收藏
代碼移植性是對編程人員的一大考驗,這個(gè)問(wèn)題應該時(shí)刻考慮。甚至從你策劃項目的一瞬間開(kāi)始,就應該考慮到代碼可能會(huì )被多次修改,或者功能模塊的刪減等。項目的外圍硬件很多時(shí)候都會(huì )根據需求改變,到底怎么樣的編寫(xiě)技巧能使修改量降至最小,而又能很好的完成項目呢?這就是今天研究的話(huà)題。這里先說(shuō)一些小的例子,以及實(shí)際怎樣運用。

(1)用宏定義代替直接IO操作

本文引用地址:http://dyxdggzs.com/article/201611/315480.htm

我覺(jué)得最典型的例子就是蜂鳴器,4KHZ驅動(dòng)的交流蜂鳴器,如果蜂鳴器接在 P50 口,那么驅動(dòng)的代碼就應該是:

mov a,@0x01

xor 0x05,a

代碼很簡(jiǎn)單,0x01 和 P5口異或出來(lái)的結果,就是 P50 口取反,不斷的取反那么得到的是 P50 口輸出方波,用C語(yǔ)言來(lái)描述就是:

PORT5 ^= 0x01

好了,這個(gè)代碼的移植性超級差,如果我的蜂鳴器現在需要修改到 P62口,那么代碼也必須相應的修改為:

mov a,@0x04

xor 0x06,a

當然了,我們這里只需要一處,還不見(jiàn)得麻煩,如果你的代碼中有50處,乃至100處需要修改,我想你肯定要抓狂。所以這種不可移植的代碼必須扔掉。

修改版1:

通過(guò)定義蜂鳴器的IO口來(lái)處理

buz_port EQU 0x05

mov a,@0x01

xor buz_port,a

這里用 buz_port 這個(gè)名字代替了蜂鳴器的輸出端口,那么現在移植性有了提高,如果修改了端口的話(huà),我們只需要重新定義 buz_port 這個(gè)宏,就完成了對代碼的所有的修改。

按照上面的描述,能解決了端口的問(wèn)題,但是我們發(fā)現,問(wèn)題還沒(méi)有完全解決,mov a,@0x01 我們還得手工計算蜂鳴器在哪個(gè)引腳上面,而且還得在一個(gè)一個(gè)的修改,所以還需要改進(jìn)。

修改版2:

buz_port EQU 0x05

buz_pin EQU 0

mov a,@1<

xor buz_port,a

這個(gè)代碼就真正實(shí)現了所謂的移植性。用C語(yǔ)言來(lái)解釋一下

buz_port ^= 1<

如果C語(yǔ)言過(guò)關(guān)的同學(xué)應該對這個(gè)表達式很熟悉了。1<

例如

1<<0 得到的結果是 1 (00000001b)

1<<3 得到的結果是 8 (00001000b)

道理是這樣,但是使用起來(lái)一點(diǎn)也不負責,可以說(shuō)是很好用??梢灾苯雍虸O的名字對應起來(lái),例如前面說(shuō)的 P62 的話(huà),那么定義就應該為:

buz_port EQU 0x06

buz_pin EQU 2

只需要修改一下定義,程序當中所有使用了這個(gè)IO口的部分都不需要修改,這樣移植性就非常好了。這個(gè)技巧雖然簡(jiǎn)單,但是是必須學(xué)會(huì )的。

(2)動(dòng)態(tài)綁定IO口

思考一種情況,我們使用 3個(gè)IO口分別發(fā)不同占空比的PWM,驅動(dòng)3個(gè)不同顏色的LED發(fā)光,形成彩燈效果。要求就是3個(gè)IO口獨立控制,那么很自然的想法就是,3段程序,每一段程序都生成PWM,也就是說(shuō)將1路的情況擴展到3路,分別控制。但是寄存器的消耗和ROM的消耗也相對應的變成了3倍,這是很好理解的。但是3段程序驚人的類(lèi)似,很可能只是IO口輸出部分修改了一下,我們思考,時(shí)候可以合在一起寫(xiě)呢?也就是說(shuō),用1個(gè)PWM程序生成PWM,分別輸出到3個(gè)不同的IO口,我建議,在看下去之前先自己思考一下,敲一下程序,就能很深刻的理解到這個(gè)問(wèn)題的難點(diǎn)。

類(lèi)似的情況也不少見(jiàn),例如RC測溫,如果測1路的話(huà)很好辦,但是如果測很多路呢?你不會(huì )真的需要將每一路都一份對應的程序吧?那絕對不可能,處理的辦法類(lèi)似,也就是說(shuō),用一個(gè)程序處理多個(gè)IO的輸入數據,切換。這有點(diǎn)類(lèi)似數字電路里面的數據選擇器。

答案是:動(dòng)態(tài)綁定IO口輸入輸出,途徑是R0和R4配合的間接尋址。怎么實(shí)現?其實(shí)很簡(jiǎn)單,因為間接尋址本身能訪(fǎng)問(wèn)地址 0x05 和 0x06 ,也就是能直接訪(fǎng)問(wèn) PORT5 和 PORT6 ,這樣就很容易聯(lián)想到,例如 PORT6 口輸出狀態(tài),然后 PORT6 的輸出狀態(tài)修改為 0X0F (P60~P63高電平,P64~P67低電平)一般的做法是:

mov a,@0x0f

mov PORT6,a

如果通過(guò)間接尋址的辦法,那么就是

mov a,@0x06

mov R4,a

mov a,@0x0f

mov R0,a

首先將要訪(fǎng)問(wèn)的寄存器地址 0x06放到地址寄存器 R4,然后將數據 0x0f 送到 R0中,那么實(shí)際的效果就是將 0xf 送到 PORT6 當中,用仿真器跑一下就OK了,很簡(jiǎn)單的。

懂了這個(gè)原理之后,那么所謂的“動(dòng)態(tài)綁定”就很容易理解了,將原來(lái)用 PORT5 PORT6訪(fǎng)問(wèn)IO口的指令,變成用 R0 R4 間接尋址來(lái)訪(fǎng)問(wèn),這樣程序就可以變得很靈活。

例如有用回之前的那個(gè)蜂鳴器的例子

系統有兩個(gè)蜂鳴器,P50和P62,那么下面看看怎么通過(guò)動(dòng)態(tài)綁定將方波分別輸出到這兩個(gè)蜂鳴器當中。

分配兩個(gè)寄存器,分別保存當前需要操作的端口信息。

REG_PORT == 0x10

REG_PIN == 0x11

假如當前需要對 P50輸出

Mov a,@0x05

Mov REG_PORT,a

Mov a,@1<<0

Mov REG_PIN,a

那么蜂鳴器的驅動(dòng)函數就應該做相應的修改,前面說(shuō)了,原來(lái)是直接對PORT口操作,現在變成間接尋址

Mov a,REG_PORT

Mov R4,a

Mov a,REG_PIN

Xor R0,a

可以理解么?其實(shí)很簡(jiǎn)單,首先確定當前需要操作的端口,前面設定了REG_PORT的值為0x05,也就是說(shuō)操作 PORT5,然后將需要操作的腳 1<<0 也就是 0x01 和 R0(現在指向PORT5)異或,得出來(lái)的效果就是 P50 改變電平,多次調用就變成輸出方波了。

如果現在需要對 P62輸出,那么事情就變得很簡(jiǎn)單,只需要:

Mov a,@0x06

Mov REG_PORT,a

Mov a,@1<<2

Mov REG_PIN,a

那么中間的方波生成部分就通用了,我們需要操作哪個(gè)端口,直接送值就OK。

看到?jīng)]有?這里就是所謂的動(dòng)態(tài)綁定。如果考慮移植性,也就是說(shuō)以后可能會(huì )修改端口的話(huà),那集合第一點(diǎn)當中所說(shuō)的,定義一個(gè)宏就OK了,反正這東西需要自己靈活的運用。

結束語(yǔ):

很簡(jiǎn)單的兩個(gè)東西,我用了大篇幅來(lái)描述就是為了說(shuō)明問(wèn)題而已,如果理解的話(huà)真的很簡(jiǎn)單,甚至是不足掛齒。但是,怎么說(shuō)呢,程序就是這類(lèi)小技巧一點(diǎn)一點(diǎn)的積累起來(lái)的。希望今天說(shuō)的2個(gè)小技巧能對你有益。



關(guān)鍵詞: 代碼移

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>