|
|||||||||||
| 技術交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
在C51中關于位段使用的土辦法~~ |
| 作者:一無所知 欄目:單片機 |
很長時間以來,在使用C51的時候,常常為了一個問題煩惱。在對MCU的操作中我們常常習慣對某個Bit或者是某幾個連續(xù)的bit進行操作. 比如說用三位表示一個器件或者某種設備的邏輯狀態(tài)。比如說象MCU的SFR一樣,在一個控制寄存器(以ADUC845為的ADCOCON1為例)其中的三位表示它的AD轉(zhuǎn)換的量程。這種方法簡單有效并且易于理解。但是在MCU中,只有對在可位尋址區(qū)(BDATA)才能單獨的對某一位進行寫1或0的操作。那么怎么樣能夠在C51下,單獨的對這三位進行寫或者讀操作,而不影響該地址下其他位的狀態(tài)呢? 先舉例: 現(xiàn)有一個PWM輸出程序的自定義8 bit控制字CFG, 對CFG的規(guī)劃如下: ZeroBit 1位表示零位校正功能 GainBit 1位表示增益校正功能 FollowBit 1位表示跟隨輸出功能 FixBit 1位表示定值輸出功能 ResolutionBit 3位表示PWM輸出的分辨率,0~7分別為10bit-16bit DefaultBit 1位保留 一開始,我試圖將這個CFG定義在BATA區(qū),這樣就可以分別對8位中的每一位進行操作了。但是這樣也有缺點。就是對于ResolutionBit,它被定義成一個三位的量,一共有7種可能出現(xiàn)的值。如果我分別對每一位進行操作的話,在代碼中并不能夠清晰的反映出相應的邏輯,要輔以注釋說明才行。并且如果在開發(fā)的過程中,如果有比較大量的類似于CFG的數(shù)據(jù)的話,似乎有限的BDATA區(qū)好像有點緊張(雖然從0x20~0x2f有16 bytes可用)最主要的還是對于象ResolutionBit這類多位的數(shù)據(jù),這種方法表示起來不直觀,可讀性不好(除了我沒人明白)。 為了節(jié)省BDATA空間,干脆就把CFG當作一個unsigned CHAR 來定義,直接對它進行| 或者是&的操作,來實現(xiàn)對某一位或者是某一位的操作,而不影響其他位的狀態(tài)。 比如我要讓ResolutionBit為7的話,可以這樣操作 CFG |= 0x70; 但是問題又來了,這樣的代碼似乎可讀性較差,也必須和說明放在一起,才知道CFG |= 0x70;實際上是ResolutionBit = 7的意思 那么怎么辦呢? 再進一步,我想到了struct中的位段。我把這個東東定義成一個位段: struct stPwmCFG { unsigned CHAR ZeroBit: 1; unsigned CHAR GainBit: 1; unsigned CHAR FollowBit: 1; unsigned CHAR FixBit: 1; unsigned CHAR ResolutionBit: 3; unsigned CHAR DefaultBit: 1; }CFG; 這樣似乎問題都解決了,我可以單獨對CFG中的某一位或者是某幾位進行操作了,向前面的ResolutionBit = 7就可以變成: CFG.ResolutionBit = 7 這樣一來代碼閱讀起來輕松多了,好像沒問題了?墒窃僖幌雴栴}還是有的。 現(xiàn)在我對CFG中定義的各個位段都可以輕松的實現(xiàn)獨立的讀寫操作了?墒侨绻袝r我還想一次對這個8個位進行讀寫操作怎么辦呢?比如說,我想一次令CFG = 0x76(就是跟隨輸出,16位分辨率)怎么辦呢?好像只能分別的對每一個位段進行操作。這樣不是變得更麻煩了么?有點象脫褲子放屁。 于是嘗試著用諸如強制類型轉(zhuǎn)換之類的土方法和怪招來把本來是一個 struct 的CFG變成 unsigned CHAR 來實現(xiàn)對CFG整體的讀寫操作,可惜失敗了。(本來人家就是包子,你非得把它當拉面處理,那不失敗才怪)。 仔細的想了想,這個問題的本質(zhì)似乎是這樣的。在一個固定地址的數(shù)據(jù)(CFG)我要用兩種不同的數(shù)據(jù)類型來實現(xiàn)對它的操作(unsigned CHAR 和struct) 那么,那么~~沒轍啦? 不對,不是還有union沒用嘛,哈哈,想到這兒當時我就笑了 在前面工作的基礎上我再改改: struct stPwmCFG { unsigned CHAR ZeroBit: 1; unsigned CHAR GainBit: 1; unsigned CHAR FollowBit: 1; unsigned CHAR FixBit: 1; unsigned CHAR ResolutionBit: 3; unsigned CHAR DefaultBit: 1; }; union uniPWM { struct stPwmCFG PwmCFG; unsigned CHAR PWMCFG; }uniCFG; 這樣夢想實現(xiàn)了。PwmCFG 和 PWMCFG一個是位段,一個是unsigned CHAR,這兩中不同類型的數(shù)據(jù)重疊在同一個地址上。 那么當我們想單獨的對ResolutionBit進行操作時,是這么實現(xiàn)的: 如果目的是ResolutionBit = 7;那么實現(xiàn)方法是: uniCFG.PwmCFG.ResolutionBit = 7; 那如果希望CFG = 0x76呢(ResolutionBit = 7; FollowBit = 1;) 這么實現(xiàn): uniCFG.PWMCFG = 0x76 這樣就行了,目的完成。 打完收工~~~(是不是真的很有用還有待檢驗) PS:看了一下生成的匯編代碼,似乎效率還是可以的 |
| 2樓: | >>參與討論 |
| 作者: xwj 于 2006/7/17 9:26:00 發(fā)布:
128個bit位還不夠嗎? 要一起操作用bdata定義字節(jié),再用sbit定義位即可 |
|
| 3樓: | >>參與討論 |
| 作者: 一無所知 于 2006/7/17 9:32:00 發(fā)布:
這樣是可以,也基本上夠了~~ ~~但是有時我需要用幾個位,比如說三位或者說是2位來表示一組狀態(tài),這樣的話,就需要用連續(xù)的2或者3位,而不是分別獨立的幾位了~你覺得呢? |
|
| 4樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/7/17 9:45:00 發(fā)布:
可以用宏,更好。 "比如我要讓ResolutionBit為7的話,可以這樣操作 CFG |= 0x70; 但是問題又來了,這樣的代碼似乎可讀性較差,也必須和說明放在一起,才知道CFG |= 0x70;實際上是ResolutionBit = 7的意思 那么怎么辦呢? " #define SetResolution(x) do{ CFG |= x<<4; }while(0) #define ClrResolution(x) do{ CFG &= ~(x<<4); }while(0) SetResolution( 0x3 ); ClrResolution( 0x3 ); |
|
| 5樓: | >>參與討論 |
| 作者: 一無所知 于 2006/7/17 9:49:00 發(fā)布:
剛剛下決心進壇,就碰到了所長~~多謝高手指點 |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |