機(jī)電之家資源網(wǎng)
單片機(jī)首頁(yè)|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開(kāi)發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開(kāi)發(fā)
培訓(xùn)信息
贊助商
用PIC寫(xiě)高效的位移操作
用PIC寫(xiě)高效的位移操作
 更新時(shí)間:2008-7-26 17:09:18  點(diǎn)擊數(shù):4
【字體: 字體顏色

用PIC寫(xiě)高效的位移操作  
  
  在許多模擬串行通信中需要用位移操作。

以1-W總線的讀字節(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<<i;
  // reads byte in, one byte at a time and then
  // shifts it left
  delay(10); // wait for rest of timeslot
 }
 return(value);
}

雖然可以用,但編譯后執(zhí)行效率并不高效,這也是很多朋友認(rèn)為C一定不能和匯編相比的認(rèn)識(shí)提供了說(shuō)法。

其實(shí)完全可以深入了解C和匯編之間的關(guān)系,寫(xiě)出非常高效的C代碼,既有C的便利,又有匯編的效率。

首先對(duì) for (i = 0; i < 8; i++)做手術(shù),改成遞減的形式:

for(i=8;i!=0;i--),因?yàn)镃PU判斷一個(gè)數(shù)是否是0(只需要一個(gè)指令),比判斷一個(gè)數(shù)是多大來(lái)的快(需要3個(gè)指令)。

再對(duì)value| = 0 x 01<<i;做手術(shù)。

value| = 0 x 01<<i;其實(shí)是一個(gè)低水平的代碼,效率低,DALLAS的工程師都是NO1,奇怪為什么會(huì)如此疏忽。

仔細(xì)研究C語(yǔ)言的位移操作,可以發(fā)現(xiàn)C總是先把標(biāo)志位清0,然后再把此位移入字節(jié)中,也就是說(shuō),當(dāng)前移動(dòng)進(jìn)字節(jié)的位一定是0。

那么,既然已經(jīng)是0了,我們就只剩下一個(gè)步驟:判斷總線狀態(tài)是否是高來(lái)決定是否改寫(xiě)此位,而不需要判斷總線是低的情況。

于是改寫(xiě)如下代碼:

for(i=8;i!=0;i--){
  value>>=1;                       //先右移一位,value最高位一定是0
  if(read_bit())   value|=0x80;                       //判斷總線狀態(tài),如果是高,就把value的最高位置1
 }

這樣一來(lái),整個(gè)代碼變得極其高效,編譯后根本就是匯編級(jí)的代碼。

 

再舉一個(gè)例子:

在采集信號(hào)方面,經(jīng)常是連續(xù)采集N次,最后求其平均值。

一般的,無(wú)論是用匯編或C,在采集次數(shù)上都推薦用8,16,32、64、128、256等次數(shù),因?yàn)檫@些數(shù)都比較特殊,對(duì)于MCU計(jì)算有很大好處。

我們以128次采樣為例:注:sampling()為外部采樣函數(shù)。

unsigned int total;

unsigned char i,val;

for(i=0;i<128;i++){

total+=sampling();

}

val=total/128;

以上代碼是很多場(chǎng)合都可以看見(jiàn)的,但是效率并不怎么樣,狂浪費(fèi)資源。

結(jié)合C和匯編的關(guān)系,再加上一些技巧,就可以寫(xiě)出天壤之別的匯編級(jí)的C代碼出來(lái)

首先分析128這個(gè)數(shù)是0B10000000,發(fā)現(xiàn)其第7位是1,其他低位全是0,那么就可以判斷第7位的狀態(tài)來(lái)判斷是否到了128次采樣次數(shù)。

在分析除以128的運(yùn)算,上面的代碼用了除法運(yùn)算,浪費(fèi)了N多資源,完全可以用右移的方法來(lái)代替之,

val=total/128等同于val=(unsigned char)(total>>7);

再觀察下去:total>>7還可以變通成(total<<1)>>8,先左移動(dòng)一位,再右移動(dòng)8位,不就成了右移7位了么?

可知道位移1,4,8的操作只需要一個(gè)指令哦。

有上面的概驗(yàn)了,就可以寫(xiě)出如下的代碼:

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)算

 

哈哈,發(fā)現(xiàn)什么?代碼量竟然可以減少一大半,運(yùn)算速度可以提高幾倍。

再回頭,就可以理解為什么采樣次數(shù)要用推薦的一些特殊值了。


  • 上一篇: MPASM的偽指令
  • 下一篇: PIC單片機(jī)開(kāi)發(fā)的若干問(wèn)題
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁(yè)  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國(guó)行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營(yíng)許可證:浙B2-20080178-1