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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 如何寫出高效的單片機(jī)C語言程序代碼

          如何寫出高效的單片機(jī)C語言程序代碼

          作者: 時間:2016-11-27 來源:網(wǎng)絡(luò) 收藏

          結(jié)果:數(shù)組a存儲的內(nèi)容是1、2、3、4、5。
          例子4:在大端模式下(8051系列單片機(jī)是大端模式)將含有位域的結(jié)構(gòu)體賦給無符號字節(jié)整型值
          方法1:逐位賦值。
          typedefstruct__BYTE2BITS
          {
          UINT8_bit7:1;
          UINT8_bit6:1;
          UINT8_bit5:1;
          UINT8_bit4:1;
          UINT8_bit3:1;
          UINT8_bit2:1;
          UINT8_bit1:1;
          UINT8_bit0:1;
          }BYTE2BITS;
          BYTE2BITSByte2Bits;
          Byte2Bits._bit7=0;
          Byte2Bits._bit6=0;
          Byte2Bits._bit5=1;
          Byte2Bits._bit4=1;
          Byte2Bits._bit3=1;
          Byte2Bits._bit2=1;
          Byte2Bits._bit1=0;
          Byte2Bits._bit0=0;
          UINT8a=0;
          a|=Byte2Bits._bit7<<7;
          a|=Byte2Bits._bit6<<6;
          a|=Byte2Bits._bit5<<5;
          a|=Byte2Bits._bit4<<4;
          a|=Byte2Bits._bit3<<3;
          a|=Byte2Bits._bit2<<2;
          a|=Byte2Bits._bit1<<1;
          a|=Byte2Bits._bit0<<0;
          結(jié)果:a=0x3C
          方法2:強(qiáng)制轉(zhuǎn)換。
          typedefstruct__BYTE2BITS
          {
          UINT8_bit7:1;
          UINT8_bit6:1;
          UINT8_bit5:1;
          UINT8_bit4:1;
          UINT8_bit3:1;
          UINT8_bit2:1;
          UINT8_bit1:1;
          UINT8_bit0:1;
          }BYTE2BITS;
          BYTE2BITSByte2Bits;
          Byte2Bits._bit7=0;
          Byte2Bits._bit6=0;
          Byte2Bits._bit5=1;
          Byte2Bits._bit4=1;
          Byte2Bits._bit3=1;
          Byte2Bits._bit2=1;
          Byte2Bits._bit1=0;
          Byte2Bits._bit0=0;
          UINT8a=0;
          a=*(UINT8*)&Byte2Bits
          結(jié)果:a=0x3C
          例子5:在大端模式下(8051系列單片機(jī)是大端模式)將無符號字節(jié)整型值賦給含有位域的結(jié)構(gòu)體。
          方法1:逐位賦值。
          typedefstruct__BYTE2BITS
          {
          UINT8_bit7:1;
          UINT8_bit6:1;
          UINT8_bit5:1;
          UINT8_bit4:1;
          UINT8_bit3:1;
          UINT8_bit2:1;
          UINT8_bit1:1;
          UINT8_bit0:1;
          }BYTE2BITS;
          BYTE2BITSByte2Bits;
          UINT8a=0x3C;
          Byte2Bits._bit7=a&0x80;
          Byte2Bits._bit6=a&0x40;
          Byte2Bits._bit5=a&0x20;
          Byte2Bits._bit4=a&0x10;
          Byte2Bits._bit3=a&0x08;
          Byte2Bits._bit2=a&0x04;
          Byte2Bits._bit1=a&0x02;
          Byte2Bits._bit0=a&0x01;
          方法2:強(qiáng)制轉(zhuǎn)換。
          typedefstruct__BYTE2BITS
          {
          UINT8_bit7:1;
          UINT8_bit6:1;
          UINT8_bit5:1;
          UINT8_bit4:1;
          UINT8_bit3:1;
          UINT8_bit2:1;
          UINT8_bit1:1;
          UINT8_bit0:1;
          }BYTE2BITS;
          BYTE2BITSByte2Bits;
          UINT8a=0x3C;
          Byte2Bits=*(BYTE2BITS*)&a;

          12.減少函數(shù)調(diào)用參數(shù)
          使用全局變量比函數(shù)傳遞參數(shù)更加有效率。這樣做去除了函數(shù)調(diào)用參數(shù)入棧和函數(shù)完成后參數(shù)出棧所
          需要的時間。然而決定使用全局變量會影響程序的模塊化和重入,故要慎重使用。

          13.switch語句中根據(jù)發(fā)生頻率來進(jìn)行case排序
          switch語句是一個普通的編程技術(shù),編譯器會產(chǎn)生if-else-if的嵌套代碼,并按照順序進(jìn)行比較,
          發(fā)現(xiàn)匹配時,就跳轉(zhuǎn)到滿足條件的語句執(zhí)行。使用時需要注意。每一個由機(jī)器語言實現(xiàn)的測試和跳轉(zhuǎn)僅僅
          是為了決定下一步要做什么,就把寶貴的處理器時間耗盡。為了提高速度,沒法把具體的情況按照它們發(fā)
          生的相對頻率排序。換句話說,把最可能發(fā)生的情況放在第一位,最不可能的情況放在最后。

          14.將大的switch語句轉(zhuǎn)為嵌套switch語句
          當(dāng)switch語句中的case標(biāo)號很多時,為了減少比較的次數(shù),明智的做法是把大switch語句轉(zhuǎn)為嵌
          套switch語句。把發(fā)生頻率高的case標(biāo)號放在一個switch語句中,并且是嵌套switch語句的最外
          層,發(fā)生相對頻率相對低的case標(biāo)號放在另一個switch語句中。比如,下面的程序段把相對發(fā)生頻率
          低的情況放在缺省的case標(biāo)號內(nèi)。
          UINT8ucCurTask=1;
          voidTask1(void);
          voidTask2(void);
          voidTask3(void);
          voidTask4(void);
          ……………
          voidTask16(void);
          switch(ucCurTask)
          {
          case1:Task1();break;
          case2:Task2();break;
          case3:Task3();break;
          case4:Task4();break;
          ………………………
          case16:Task16();break;
          default:break;
          }
          可以改為
          UINT8ucCurTask=1;
          voidTask1(void);
          voidTask2(void);
          voidTask3(void);
          voidTask4(void);
          ……………
          voidTask16(void);
          switch(ucCurTask)
          {
          case1:Task1();break;
          case2:Task2();break;
          default:
          switch(ucCurTask)
          {
          case3:Task3();break;
          case4:Task4();break;
          ………………………
          case16:Task16();break;
          default:break;
          }
          Break;
          }
          由于switch語句等同于if-else-if的嵌套代碼,如果大的if語句同樣要轉(zhuǎn)換為嵌套的if語句。
          UINT8ucCurTask=1;
          voidTask1(void);
          voidTask2(void);
          voidTask3(void);
          voidTask4(void);
          ……………
          voidTask16(void);
          if(ucCurTask==1)Task1();
          elseif(ucCurTask==2)Task2();
          else
          {
          if(ucCurTask==3)Task3();
          elseif(ucCurTask==4)Task4();
          ………………
          elseTask16();
          }

          15.函數(shù)指針妙用
          當(dāng)switch語句中的case標(biāo)號很多時,或者if語句的比較次數(shù)過多時,為了提高程序執(zhí)行速度,
          可以運用函數(shù)指針來取代switch或if語句的用法,這些用法可以參考電子菜單實驗代碼、USB實驗代碼
          和網(wǎng)絡(luò)實驗代碼。
          UINT8ucCurTask=1;
          voidTask1(void);
          voidTask2(void);
          voidTask3(void);
          voidTask4(void);
          ……………
          voidTask16(void);
          switch(ucCurTask)
          {
          case1:Task1();break;
          case2:Task2();break;
          case3:Task3();break;
          case4:Task4();break;
          ………………………
          case16:Task16();break;
          default:break;
          }
          可以改為
          UINT8ucCurTask=1;
          voidTask1(void);
          voidTask2(void);
          voidTask3(void);
          voidTask4(void);
          ……………
          voidTask16(void);
          void(*szTaskTbl)[16])(void)={Task1,Task2,Task3,Task4,…,Task16};
          調(diào)用方法1:(*szTaskTbl[ucCurTask])();
          調(diào)用方法2:szTaskTbl[ucCurTask]();

          16.循環(huán)嵌套
          循環(huán)在編程中經(jīng)常用到的,往往會出現(xiàn)循環(huán)嵌套。現(xiàn)在就已for循環(huán)為例。
          UINT8i,j;
          for(i=0;i<255;i++)
          {
          for(j=0;j<25;j++)
          {
          ………………
          }
          }
          較大的循環(huán)嵌套較小的循環(huán)編譯器會浪費更加多的時間,推薦的做法就是較小的循環(huán)嵌套較大的循環(huán)。
          UINT8i,j;
          for(j=0;j<25;j++)
          {
          for(i=0;i<255;i++)
          {
          ………………
          }
          }

          17.內(nèi)聯(lián)函數(shù)
          在C++中,關(guān)鍵字inline可以被加入到任何函數(shù)的聲明中。這個關(guān)鍵字請求編譯器用函數(shù)內(nèi)部的代
          碼替換所有對于指出的函數(shù)的調(diào)用。這樣做在兩個方面快于函數(shù)調(diào)用。這樣做在兩個方面快于函數(shù)調(diào)用:
          第一,省去了調(diào)用指令需要的執(zhí)行時間;第二,省去了傳遞變元和傳遞過程需要的時間。但是使用這種方
          法在優(yōu)化程序速度的同時,程序長度變大了,因此需要更多的ROM。使用這種優(yōu)化在inline函數(shù)頻繁調(diào)
          用并且只包含幾行代碼的時候是最有效的。
          如果編譯器允許在C語言編程中能夠支持inline關(guān)鍵字,注意不是C++語言編程,而且單片機(jī)的ROM
          足夠大,就可以考慮加上inline關(guān)鍵字。支持inline關(guān)鍵字的編譯器如ADS1.2,RealViewMDK等。

          18.從編譯器著手
          很多編譯器都具有偏向于代碼執(zhí)行速度上的優(yōu)化、代碼占用空閑太小的優(yōu)化。例如Keil開發(fā)環(huán)境編
          譯時可以選擇偏向于代碼執(zhí)行速度上的優(yōu)化(FavorSpeed)還是代碼占用空間太小的優(yōu)化(Favor
          Size)。還有其他基于GCC的開發(fā)環(huán)境一般都會提供-O0、-O1、-O2、—O3、-Os的優(yōu)化選項,而使用
          -O2的優(yōu)化代碼執(zhí)行速度上最理想,使用-Os優(yōu)化代碼占用空間大小最小。

          19.嵌入?yún)R編---殺手锏
          匯編語言是效率最高的計算機(jī)語言,在一般項目開發(fā)當(dāng)中一般都采用C語言來開發(fā)的,因為嵌入?yún)R編
          之后會影響平臺的移植性和可讀性,不同平臺的匯編指令是不兼容的。但是對于一些執(zhí)著的程序員要求程
          序獲得極致的運行的效率,他們都在C語言中嵌入?yún)R編,即“混合編程”。
          注意:如果想嵌入?yún)R編,一定要對匯編有深刻的了解。不到萬不得已的情況,不要使用嵌入?yún)R編。

          上一頁 1 2 下一頁

          關(guān)鍵詞: 單片機(jī)C語言程序代

          評論


          技術(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); })();