<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)程序之高效的位移操

          單片機(jī)程序之高效的位移操

          作者: 時(shí)間:2016-11-30 來(lái)源:網(wǎng)絡(luò) 收藏
          近來(lái),在制作一些家用的小電器,又在收集、學(xué)習(xí)智能家居物聯(lián)網(wǎng)方面的知識(shí)。緊接著網(wǎng)站又搬了一個(gè)新家,將近一個(gè)月沒(méi)有碼字了。這些好像都跟阿浩的做事效率有關(guān),而這篇文章也是說(shuō)效率的,但并不是說(shuō)阿浩的效率如何的低,而是怎樣讓單片機(jī)執(zhí)行更高效的代碼。

          說(shuō)到這里,有人或許會(huì)反駁我:用匯編不就行了嘛?答案是肯定的。用匯編寫程序,產(chǎn)生的代碼精短,執(zhí)行效率高,無(wú)可置疑。但是當(dāng)你要寫一個(gè)大型的程序,而對(duì)執(zhí)行效率要求要高的話,選擇C語(yǔ)言來(lái)寫,具有優(yōu)勢(shì)。這種優(yōu)勢(shì),就不在這大費(fèi)口舌了。而下面介紹的幾個(gè)方法,對(duì)你寫出高效的C程序有一些幫助。

          本文引用地址:http://www.ex-cimer.com/article/201611/323747.htm


          首先,必須知道的,一個(gè)C語(yǔ)言程序,最終是要編譯成機(jī)器碼給單片機(jī)執(zhí)行的。也就是說(shuō),C語(yǔ)言將被編譯器,“翻譯”成匯編代碼,然后編譯成單片機(jī)最終的代碼。以上理解了就好辦,我們只需要讓C語(yǔ)言寫的代碼,“翻譯”成匯編代碼會(huì),代碼行減少了,就說(shuō)這種寫法更高效。

          一.高效的位移操

          我們?cè)谠S多模擬串行通信中需要用到移位操作。
          例如,IIC、SPI,1-Wire總線等等

          這里以1-Wire總線讀一個(gè)字節(jié)為例
          unsigned char read_byte(void)
          {
          unsigned char i;
          unsigned char value = 0;
          for (i = 0; i < 8; i++)
          {
          if(read_bit())
          value| = 0 x 01< delay(10); //等待總線時(shí)隙
          }
          return(value);
          }[c]

          這段代碼是正確的,但編譯后執(zhí)行效率并不高。
          而其實(shí)只要深入了解C和匯編之間的關(guān)系,寫出高效的C代碼,既有C的便利,又有匯編的效率。

          下面對(duì)代碼進(jìn)行修改剖析:
          1.for(i=0;i 解釋一下:因?yàn)镃PU判斷一個(gè)數(shù)是否為0,只需要一條指令。比判斷一個(gè)數(shù)多大要執(zhí)行得快(需要3個(gè)指令)。

          2.value|=0x01<>=1; //先右移一位,value最高位一定是0

          if(read_bit()){
          value|=0x80; //判斷總線狀態(tài),如果是高,就把value的最高位置1
          }[c]

          這樣寫出來(lái)的代碼變得極其高效,編譯后基本就是匯編級(jí)的代碼了。

          二.位移操作,讓計(jì)算更高效

          使用單片機(jī)AD采集信號(hào)方面,通常做法是連續(xù)采集N次,然后求平均值。
          一般為了MCU計(jì)算更為“方便”,采集次數(shù)推薦用8,16,32,64,128,256等次數(shù),你懂的,這些數(shù)比較特殊。
          這里以采樣128次,然后求平均值為例。注:sampling()為外部采樣函數(shù)。

          unsigned int total;
          unsigned char i,val;
          for(i=0;i<128;i++)
          {
          total+=sampling();
          }
          val=total/128;[c]

          以上代碼是通常的寫法,但是效率并不高,浪費(fèi)資源。

          改造進(jìn)行
          1.首先分析128這個(gè)數(shù)是0B10000000,發(fā)現(xiàn)其實(shí)第7位是1,其他位都為0,所以我們就可以判斷第7位的狀態(tài)來(lái)判斷128次采樣是否到了。
          2.val=total/128 運(yùn)用了除法運(yùn)算,浪費(fèi)資源,完全可以用右移的方法來(lái)代替(雖然有些編譯器會(huì)將此類運(yùn)算轉(zhuǎn)換為位移運(yùn)算,但寫成移位的鐵定沒(méi)錯(cuò))。
          val=total/128等同于 val=(unsigned char)(total>>7);
          但這并不完全高效,還再優(yōu)化一下:
          total>>7 還可以變通成(total<<1)>>8,先左移動(dòng)一位,再右移動(dòng)8位,不就成了右移 7 位了么? 因?yàn)槲灰?,4,8位的操作只需要一個(gè)指令。

          unsigned int total;
          unsigned char i=0
          unsigned char val;
          while(!(i&0x80)){ //判斷 i 第7位,只需要一個(gè)指令。
          total+=sampling();
          i++;
          }
          val=(unsigned char)((total<<1)>>8); //幾個(gè)指令就代替了幾十個(gè)指令的除法運(yùn)算[c]

          編譯后的代碼量居然可以減少一半,而運(yùn)算速度可以提高幾倍,再回頭,就可以理解為什么采用次數(shù)要用推薦的一些特殊值了。



          關(guān)鍵詞: 單片機(jī)位移

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();