99精品久久久久久久免费看蜜月/欧美激情做真爱牲交视频/日本不卡不码高清免费观看/三浦惠理子jux240久久 - 他在车里撞了我八次主角是谁

購物車0種商品
IC郵購網-IC電子元件采購商城
SPI總線單字節讀寫函數
(2011/10/13 9:09:00)
最近在調試我設計的MP3,用到SPI讀寫SD卡和向VS1003B發送數據,因為MP3對數據流速度相當敏感,遂對軟件SPI進行了優化,目前已能流暢播放了。
我的SPI總線單字節讀寫函數如下,自認為速度最快了,已至極致,縱然匯編實現,也只能打個平手,51高手請指正。

#include"..incincludes.h"




sbitc_SPI_SI=P1^5;
sbitc_SPI_SO=P1^6;
sbitc_SPI_CLK=P1^7;

#defineMacro_Set_SI_High()c_SPI_SI=1
#defineMacro_Set_SI_Low()c_SPI_SI=0
#defineMacro_Set_CLK_High()c_SPI_CLK=1
#defineMacro_Set_CLK_Low()c_SPI_CLK=0

/*
//----------------標準C語言版-----------------------------------------
//可移植性好,易讀,易移植
uint8SD_SPI_ReadByte(void)
{
ucharucReadData;
ucharucCount;

ucReadData=0;
Macro_Set_SI_High();

for(ucCount=0;ucCount<8;ucCount++)
{
ucReadData<<=1;
Macro_Set_CLK_Low();

Macro_Set_CLK_High();

if(c_SPI_SO)
{
ucReadData|=0x01;
}
}

return(ucReadData);
}

voidSD_SPI_WriteByte(uint8ucSendData)
{
ucharucCount;
ucharucMaskCode;

ucMaskCode=0x80;
for(ucCount=0;ucCount<8;ucCount++)
{
Macro_Set_CLK_Low();

if(ucMaskCode&ucSendData)
{
Macro_Set_SI_High();
}
else
{
Macro_Set_SI_Low();
}
Macro_Set_CLK_High();
ucMaskCode>>=1;
}
}

*/
//-------------------------標準優化版SPI讀寫函數---------
ucharbdataucReadData;
sbitReadData_Bit0=ucReadData^0;
sbitReadData_Bit1=ucReadData^1;
sbitReadData_Bit2=ucReadData^2;
sbitReadData_Bit3=ucReadData^3;
sbitReadData_Bit4=ucReadData^4;
sbitReadData_Bit5=ucReadData^5;
sbitReadData_Bit6=ucReadData^6;
sbitReadData_Bit7=ucReadData^7;

ucharbdataucWriteData;
sbitWriteData_Bit0=ucWriteData^0;
sbitWriteData_Bit1=ucWriteData^1;
sbitWriteData_Bit2=ucWriteData^2;
sbitWriteData_Bit3=ucWriteData^3;
sbitWriteData_Bit4=ucWriteData^4;
sbitWriteData_Bit5=ucWriteData^5;
sbitWriteData_Bit6=ucWriteData^6;
sbitWriteData_Bit7=ucWriteData^7;

uint8SD_SPI_ReadByte(void)
{
//初始化SI引腳狀態
Macro_Set_SI_High();

//Bit7ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit7=c_SPI_SO;

//Bit6ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit6=c_SPI_SO;

//Bit5ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit5=c_SPI_SO;

//Bit4ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit4=c_SPI_SO;

//Bit3ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit3=c_SPI_SO;

//Bit2ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit2=c_SPI_SO;

//Bit1ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit1=c_SPI_SO;

//Bit0ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit0=c_SPI_SO;

return(ucReadData);
}

voidSD_SPI_WriteByte(uint8ucSendData)
{
ucWriteData=ucSendData;

//Bit7ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit7;
Macro_Set_CLK_High();

//Bit6ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit6;
Macro_Set_CLK_High();
//Bit5ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit5;
Macro_Set_CLK_High();
//Bit4ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit4;
Macro_Set_CLK_High();
//Bit3ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit3;
Macro_Set_CLK_High();
//Bit2ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit2;
Macro_Set_CLK_High();
//Bit1ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit1;
Macro_Set_CLK_High();
//Bit0ShiftOutToSDCard
Macro_Set_CLK_Low();
c_SPI_SI=WriteData_Bit0;
Macro_Set_CLK_High();
}




網友評論:奉上驅動與測試的UV2工程,便于大家自行測試。
相關鏈接:/upfiles/img/20083/200833134035403.rar

網友評論:太快了還要加NOP指令

網友評論:首先聲明俺對51不熟,所以不敢說下面的辦法是否有效,但想給各位提個醒,也許還有很大優化空間。

不知各位注意到了嗎?在SD的標準文檔中有這樣一段話:Bothhostcommandandcardresponseareclockedoutwiththerisingedgeofthehostclock;這就是說數據線(SPI_SI或SPI_SO)的變化可以與時鐘線的上升同時進行。

利用這一點,可以在輸出數據位時同時拉高時鐘線(SPI_CLK),把這兩個操作用一條指令完成;也許按照這個思路做,可以省掉一條操作指令,我曾在其它單片機上這樣做過,但不知道在51上是否也有效。

網友評論:把核心函數用匯編寫,還有什么問題不?

網友評論:hotpower發表于2005-6-180:21:43侃單片機←返回版面

2049:unsignedcharI2CReadWrite(unsignedcharval)
2050:{
2051:unsignedchari;
2052:ACC=val;//取寫入數據
C:0x18D3EFMOVA,R7
2053:for(i=8;i>0;i--){//收發8位數據
C:0x18D47F08MOVR7,#0x08
2054:SCL=0;//拉低I2C時鐘
C:0x18D6C286CLRSCL(0x80.6)
2055:_rlca_();//左移1位數據(取出1位寫入數據)
C:0x18D833RLCA
2056:SDA=CY;//寫入1位I2C數據
C:0x18D99287MOVSDA(0x80.7),C
2057:_rrca_();//右移1位還原數據
2058://_nop_();_nop_();_nop_();_nop_();_nop_();//延時4.7uS
2059://如果不追求高速,可在此加入一些總線沖突裁決程序
2060://即SDA=1時,讀回若為0則為總線沖突
C:0x18DB13RRCA
2061:SCL=1;//拉高I2C時鐘
C:0x18DCD286SETBSCL(0x80.6)
2062:CY=SDA;//讀回1位I2C數據
C:0x18DEA287MOVC,SDA(0x80.7)
2063:_rlca_();//左移最后1位數據
C:0x18E033RLCA
2064:}
C:0x18E1DFF3DJNZR7,C:18D6
2065:SCL=0;//拉低I2C時鐘
C:0x18E3C286CLRSCL(0x80.6)
2066:returnACC;//返回讀回數據
C:0x18E5FFMOVR7,A
2067:}
C:0x18E622RET



相關鏈接:/club/bbs/showEssence.asp?id=6493&page=1

網友評論:我的代碼確實節約了一個機器周期啊!
我最高位是直接讀P1讀進來的(只要倆周期,你原來的代碼要仨周期),雖然其他位B6~B0也一起從P1口上讀了(當然是沒有意義的),但后面一位一位地換成SPI的數據了。
我換三根線的定義,是為了讓變量的最高位與P1口的定義的SI一致。

你原始代碼的做法是:B7~B0都用相同的方式輸入,各需要6個機器周期

我的辦法是:B7節約了一個機器周期,其他位不變。

好比百米比賽,按照你劃定的“跑道”,我確實節約了一個周期,怎么就不算了呢???

至于其他的辦法,與你的辦法差異太大了,不是一個“跑道”,不評價。

當然了,我的代碼僅僅在讀入時節約了一個周期。

網友評論:你用匯編也不能再節約一個周期了

網友評論:您提到的讀P1節省周期,無法理解,因為原創作品,讀。樱校尚酒臄祿敵觯挥昧艘粋周期,是將位數據移入位變量時花費了2個機器周期,最后生成CLK占用2個周期,不服還可舉證。XWJ改寫的SPI讀函數代碼是通過縮減串轉并的周期,故而速度領先。

網友評論:回NE5532,你要是能用匯編寫出更快的功能函數,I服了You
回“平常人”,您的思路很不錯,將兩步合作一步走,是個好主意,能否貼出參考代碼,便于大家依葫蘆畫瓢,如果P1口全部用作輸出,您的辦法也許真能每位節。睓C器周期。

網友評論:/*
//----------------標準C語言版-----------------------------------------
//可移植性好,易讀,易移植
uint8SD_SPI_ReadByte(void)
{
ucharucReadData;
ucharucCount;

ucReadData=0;
Macro_Set_SI_High();

ucCount=8;
do{
ucReadData<<=1;
Macro_Set_CLK_Low();

Macro_Set_CLK_High();

if(c_SPI_SO)
{
ucReadData++;
}
}while(--ucCount);

return(ucReadData);
}

voidSD_SPI_WriteByte(uint8ucSendData)
{
ucharucCount;
ucharucMaskCode;

ucCount=8;
do{
Macro_Set_CLK_Low();

Macro_Set_SI_Low();
if(ucSendData&0x01)
{
Macro_Set_SI_High();
}
Macro_Set_CLK_High();
ucSendData>>=1;
}while(--ucCount);
}

網友評論:抄也不是這樣抄的吧???

網友評論:主要是基本方法,過程并不重要...
其實是這個上網電腦沒有裝UE32軟件,用的寫字板,修改不方便...

網友評論:回37樓
以下是你的原始代碼:請看我加的注釋
//Bit7ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();
ReadData_Bit7=c_SPI_SO;//這個編譯以后成了對應于MOVC,c_SPI_SO以及MOVReadData_Bit7,C兩條匯編指令的機器碼吧?需要1+2=3個周期

以下是改過的
//Bit7ShiftOut
Macro_Set_CLK_Low();
Macro_Set_CLK_High();//已經將P1^5和P1^7的定義對調,到此,最高位出現在P1^7上
ucReadData=P1;//這個編譯以后成了對應于MOVucReadData,P1一條匯編指令的機器碼吧?只需要2個周期。注意:我把P1的整個一個byte讀進來了,當然P1^7也讀進來了,而且就讀到了ucReadData的最高位上也就是讀到了ReadData_Bit7里(讀進來的其它位當然沒有意義,后面還是要一位一位補上的)!
怎么沒有道理呢?


網友評論:看了樓上這些大蝦的一番番激論﹐心里真是賊佩服﹗﹗
同時心有感慨﹐什么時候自己才能夠參與這樣的話題。。。。N年以后﹗﹗
我剛開始學匯編﹐用的是義隆E8-ICE。。。想讓大蝦們給點建議…..
學義隆用沒有發展﹖前景好嗎﹖﹖


網友評論:都是學生時代玩的東西

網友評論:看看你的所謂的“精華”貼,那才真正的是學生做的程序

如果你的產品只能做到這種水平的話,估計是沒幾個人敢買的...

相關鏈接:/club/bbs/showEssence.asp?id=2636

網友評論:您將P1口的數據讀到ucReadData,這是能節省一個周期,但ucReadData還不是最終的結果,即使將最高位移位到D6位,為下一次讀做準備,況且下一次讀又會改變ucReadData的內容,所以局部節省不代表整個函數節省。


網友評論:貌似很多高手和考官愛那他的好算法來貶低人.

賣出去的產品人家不會看你怎么寫的程序~~~~~~~~~~

網友評論:說軟件模擬SPI沒有意義,此言差矣。SPI的擴展芯片極為常見,以其高速通訊和連線簡化,大有取代傳統并行總線接口器件之勢。
很多單片機沒有硬件SPI接口,軟件摸擬提高速度是有好處的。比如傳統字庫用并行Flash29C020,改用AT45DB161后,讀取字庫不優化,效果很不理想。
又比如LCD屏幕,很多小屏采用了SPi接口,如果驅動函數不做優化,整屏更新數據會明顯的停頓感,更不要說做繪圖設計了。

網友評論:但是這種方法在51上是最快的方法了,也是KeilC預留的一個經典方法,相關的頭文件如下
#define_setc_()CY=1
#define_clrc_()CY=0
#define_setb_(RBIT)RBIT=1
#define_clrb_(RBIT)RBIT=0
#define_clra_()ACC=0
#define_movcb_(RBIT)CY=RBIT
#define_movbc_(RBIT)RBIT=CY
#define_movra_(RX)RX=ACC
#define_movar_(RX)ACC=RX
#define_movb0_(RBIT,RX)RBIT=RX&0x01//用于取RX的最低位
#define_movb7_(RBIT,RX)RBIT=RX&0x80//用于取RX的最高位
#define_rrca_()CY=ACC&0x01//產生RRCA指令
#define_rlca_()CY=ACC&0x80//產生RLCA指令
#define_rrcar_(RX)CY=RX&0x01
#define_rlcar_(RX)CY=RX&0x80
#define_xorr_(RX)RX^=RX//用于取奇偶位P,且RX=0
#define_andr_(RX)RX&=RX//用于取奇偶位P,且RX=不變
#define_orr_(RX)RX|=RX//用于取奇偶位P,且RX=不變
#define_notr_(RX)RX=~RX


網友評論:因為位操作可以用MOVE指令,要是PIC可以把你急死。菜農的C語言精簡到差不多了,要更快,何必用軟口了呢?

網友評論:回50樓
咋就局部節省不等于整體節省了呢?我改過以后,別的地方并沒有動,也就沒有在別的地方多用機器周期。我改過的函數你調用一次就是比原來的少用了一個機器周期的,難道不是嗎?那你說說,改了以后,用多少個機器周期?
我的局部難道影響整體了嗎?

我只是在取D7位的時候節省了一個周期,其它的位還是原始代碼,原始代碼效率確實是很高了,我沒指望節省多的機器周期,一個,就一個,也是省了。


網友評論:再更正一下50樓的說法
是最高位D7,不是D6,注意我把P1.5和P1.7的定義對調了,就是為了取D7的時候少用一個機器周期。

網友評論:即使有SPI...因為它的地基不好~~~鋪金也白搭~~~

網友評論:現在8塊以內的Arm有嗎?象一些簡單應用,還是用51比較好,簡單易用,很多底層代碼可以網絡上下載。
另外,除非你是個剛開門的公司,否則如果原來的產品是51做的,那么你的產品必然有一定的繼承性,或者叫兼容性,并不是說Arm好用,就可以把一個公司里面所有的東西重新開發一遍,你想,所有的硬件驅動代碼要重新寫工作量就很可怕,就算能夠重新開發,售后服務怎么做。你的客戶會怎么想,硬件只是一個平臺,能表達你的設計思想,夠用就可以了。難道你出門上班,有部夏利的士過來,你就是不坐,非帕薩特的士不可嗎?
呵呵。。別介意。。不是對你的攻擊,對你的觀點的一種不同意的表達

網友評論:您還不服氣,您可以將您的思想改個完整代碼試試,您就會發現錯誤的,好多東西光憑想象是不可靠的。
Hotpower的觀點是完美主義,Winds代表實用主義,俺的觀點是逐步追求完美。
先實現功能,再做優化。

網友評論:再精簡代碼,也只是局限于用軟件一位一位的模擬發送和接收,思想已經局限于這個框架了。我現在操作SPI接口器件是用CPLD來實現的,單片機用并口向CPLD寫一個字節數據后,CPLD依靠晶振給提供的脈沖極快的就把數據發送給接口器件,單片機只需要等待2個NOP就可以寫下一個字節數據了,比單片機提供的真正的SPI接口還要快,完全是兩種檔次的思想,這個問題沒什么討論的價值。

網友評論:串口的UART0方式有我做的方式快么

網友評論:PDF介紹,該芯片在6時鐘模式下,最大外頻為16M,俺整了個18.432M的晶體,小超一把,嘿嘿,用得蠻好的。俺相信再用上它的硬件SPI,估計能將256KbpS的Mp3播放出來。

網友評論:如果不是程序容量不是很大,可以試試看,成本也不高,聽說才6塊多

網友評論:其實,在做技術的過程中,總是有很多的這樣的小問題,總是在困擾著我們!
看了一下這個題目,我自己沒有想到更好的辦法出來!
從對于這些問題的理解,就可以看到人的水平是不同的!

網友評論:我沒有不服氣,是你不服氣吧?(因為你的NO.1???)
我當然做了測試,還是不相信的話,你可以要求我發編譯過程中形成的反匯編碼子。


網友評論:最好附上您修改好的uV2工程,讓大家給您分析分析。我已上傳采用XWJ代碼建立的uV2工程,修改和測試很方便,見前述發貼。


網友評論:我也在做SD卡,但不是MP3,現在也差不多了。我的設計對速度要求不是很高,所以可以讀寫就行了!
今天在這里向各位學習了!

網友評論:回71樓,我只看你的代碼!
我就那點能耐,就省了一個機器周期,呵呵
我的UV工程和你的UV工程就差那一句,以及P1.5,P1.7定義對調。



網友評論:XWJ讀函數好!
不過同理,可以節約一個機器周期。XWJ已經在代碼里給出注釋了。

網友評論:直接操作一個完整字節,才是軟件模擬最快的方法=======單刀直入。






網友評論:ucharMMC_SPI(dataucharcmd)
{
datauchari,j=0;
//ACC=0;
for(i=8;i>0;i--)
{
j<<=1;
MMC_SCK=0;
j|=MMC_DO;
MMC_DI=(cmd&0x80)==0x80;
//MMC_DI=cmd>>7;
MMC_SCK=1;
cmd<<=1;
}
//MMC_SCK=1;
return(j);
}

ucharMMC_SPI(dataucharcmd)
;15.{
MMC_SPI:
;16.datauchari,j=0;
;17.//ACC=0;
;18.for(i=8;i>0;i--)
MOV$LOCBDMMC_SPI+1,#0
MOV$LOCBDMMC_SPI,#8
MOV$LOCBDMMC_SPI+2,R4
?0001:
MOVA,$LOCBDMMC_SPI
JZ?0000
?0002:
;19.{
;20.j<<=1;
MOVA,$LOCBDMMC_SPI+1
ADDA,ACC
MOV$LOCBDMMC_SPI+1,A
;21.MMC_SCK=0;
CLR232.1
;22.j|=MMC_DO;
CLRA
MOVC,232.0
MOVACC.0,C
ORL$LOCBDMMC_SPI+1,A
;23.MMC_DI=(cmd&0x80)==0x80;
MOVA,$LOCBDMMC_SPI+2
ANLA,#128
XRLA,#128
JZ?0031
MOVA,#255
?0031:
INCA
MOVC,ACC.0
MOV232.2,C
;24.//MMC_DI=cmd>>7;
;25.MMC_SCK=1;
SETB232.1
;26.cmd<<=1;
MOVA,$LOCBDMMC_SPI+2
ADDA,ACC
MOV$LOCBDMMC_SPI+2,A
DEC$LOCBDMMC_SPI
SJMP?0001
?0000:
;27.}
;28.//MMC_SCK=1;
;29.return(j);
MOVR4,$LOCBDMMC_SPI+1
;30.}

網友評論:最接近硬件SPI的特性,只是俺的應用是分開的,讀數據時,不管寫入什么東西,寫數據時,不管返回的數據。

網友評論:因為其生成的DJNZ匯編指令循環模式是很不錯的。

網友評論:IAR的編譯器喜歡預分配一個堆,局部變量一般都在堆里分配,較少用到寄存器。不過IAR文件越大優化效果越明顯,而且不出錯,KEILC51在編譯超過20多K后8~9級優化便容易出一些問題。表現形式是液晶上顯示的字符亂碼(同樣的代碼低優化級別正常)

網友評論:看了也不記得,能全在一樓上下看最好

網友評論:難道cpu一直在這模擬?
cpu忙其他事的時候,速度立馬變成0,或者除非外部有緩沖,
硬件并且帶fifo才有意義。不然也只有死等

瀏覽:(3037)| 評論( 0 )
博文評論

  • 昵 稱:
  • 內 容:10~250個字符
  • 驗證碼: 驗證碼看不清楚?請點擊刷新驗證碼
  •                      
  • 博文分類

    熱點博文

    最新博文

    最新評論

    IC電子元件查詢
    IC郵購網電子元件品質保障