音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

登錄 免費注冊 首頁 | 行業(yè)黑名單 | 幫助
維庫電子市場網(wǎng)
技術交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng)
驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe

在C51中關于位段使用的土辦法~~

作者:一無所知 欄目:單片機
在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
128個bit位還不夠嗎?
要一起操作用bdata定義字節(jié),再用sbit定義位即可


3樓: >>參與討論
一無所知
這樣是可以,也基本上夠了~~
~~但是有時我需要用幾個位,比如說三位或者說是2位來表示一組狀態(tài),這樣的話,就需要用連續(xù)的2或者3位,而不是分別獨立的幾位了~你覺得呢?

4樓: >>參與討論
農(nóng)民講習所
可以用宏,更好。
"比如我要讓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樓: >>參與討論
一無所知
剛剛下決心進壇,就碰到了所長~~多謝高手指點
 
參與討論
昵稱:
討論內(nèi)容:
 
 
相關帖子
有人能談談OLED嗎,尤其是價格!
那位兄臺用過usbd12smart板,最好在北京留個聯(lián)絡方式
招人!
我用深圳金得通51仿真器
請教一個關于單片機定時器公式的問題!
免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入


Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號