第講-c語言介紹-DSP芯片應(yīng)用課件_第1頁
第講-c語言介紹-DSP芯片應(yīng)用課件_第2頁
第講-c語言介紹-DSP芯片應(yīng)用課件_第3頁
第講-c語言介紹-DSP芯片應(yīng)用課件_第4頁
第講-c語言介紹-DSP芯片應(yīng)用課件_第5頁
已閱讀5頁,還剩177頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第講c語言介紹DSP芯片應(yīng)用第講c語言介紹DSP芯片應(yīng)用第講c語言介紹DSP芯片應(yīng)用DSP芯片C語言開發(fā)簡介TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型表1列出了TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型的大小、表示形式和表示范圍,這些數(shù)據(jù)類型在float.h和limits.h中定義。在C語言開發(fā)的過程中,采用合適的數(shù)據(jù)類型對于系統(tǒng)的正確運行有著極為重要的意義。第講c語言介紹DSP芯片應(yīng)用第講c語言介紹DSP1DSP芯片C語言開發(fā)簡介TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型表1列出了TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型的大小、表示形式和表示范圍,這些數(shù)據(jù)類型在float.h和limits.h中定義。在C語言開發(fā)的過程中,采用合適的數(shù)據(jù)類型對于系統(tǒng)的正確運行有著極為重要的意義。DSP芯片C語言開發(fā)簡介TMS320C54xC/C++編表1TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型類型bit表示形式最小值最大值signedchar16ASCII?3276832767charunsignedchar16ASCII065535short,signedshort162sComplement?3276832767unsignedshort16Binary065535int,signedint162sComplement?3276832767表1TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型類型大小/bit表示形式最小值最大值unsignedint16Binary065535long,signedlong322sComplement?21474836482147483647unsignedlong32Binary04294967295enum162sComplement?3276832767float32IEEE32-bit1.175494e?383.40282346e+38double32IEEE32-bit1.175494e?383.40282346e+38longdouble32IEEE32-bit1.175494e?383.40282346e+38pointers16Binary00xFFFF類型大小/bit表示形式最小值最大值unsignediC語言的數(shù)據(jù)訪問方法

1.DSP片內(nèi)寄存器的訪問

DSP片內(nèi)寄存器在C語言中一般采用指針方式來訪問,常常采用的方法是將DSP寄存器地址的列表定義在頭文件中(如reg.h)。DSP寄存器地址定義的形式為宏,如下所示:C語言的數(shù)據(jù)訪問方法#defineIMR (volatileunsignedint*)0x0000#defineIFR (volatileunsignedint*)0x0001#defineST0(volatileunsignedint*)0x0006#defineST1 (volatileunsignedint*)0x0007#defineAL (volatileunsignedint*)0x0008#defineIMR (volatileunsig#defineAH(volatileunsignedint*)0x0009#defineAG(volatileunsignedint*)0x000A#defineBL(volatileunsignedint*)0x000B#defineBH (volatileunsignedint*)0x000C#defineBG (volatileunsignedint*)0x000D第講--c語言介紹-DSP芯片應(yīng)用課件#defineT (volatileunsignedint*)0x000E#defineTRN (volatileunsignedint*)0x000F#defineAR0 (volatileunsignedint*)0x0010#defineAR1 (volatileunsignedint*)0x0011#defineAR2 (volatileunsignedint*)0x0012#defineSP (volatileunsignedint*)0x0018#defineBK (volatileunsignedint*)0x0019#defineT (volat#defineBRC (volatileunsignedint*)0x001A#defineRSA (volatileunsignedint*)0x001B#defineREA (volatileunsignedint*)0x001C#definePMST (volatileunsignedint*)0x001D#defineXPC (volatileunsignedint*)0x001E#defineBRC (volatileunsi

在主程序中,若要讀出或者寫入一個特定的寄存器,就要對相應(yīng)的指針進行操作。下例通過指針操作對SWWSR和BSCR進行初始化。

#defineSWWSR (volatileunsignedint*)0x0028#defineBSCR (volatileunsignedint*)0x0029

在主程序中,若要讀出或者寫入一個特定intfunc(){...

*SWWSR=0x2000;*BSCR=0x0000;...}intfunc()

2.DSP內(nèi)部和外部存儲器的訪問同DSP片內(nèi)寄存器的訪問相類似,對存儲器的訪問也采用指針方式來進行。下例通過指針操作對內(nèi)部存儲器單元0x3000和外部存儲器單元0x8FFF進行操作。2.DSP內(nèi)部和外部存儲器的訪問int*data1=0x3000; /*內(nèi)部存儲器單元*/int*data2=0x8FFF; /*外部存儲器單元*/intfunc(){...

*data1=2000;*data2=0;...}int*data1=0x3000; /*內(nèi)部存儲器3.DSPI/O端口的訪問

DSPI/O端口的訪問通過ioport關(guān)鍵字實現(xiàn)。定義的形式為

ioporttypeporthex_num

其中:ioport是關(guān)鍵字,表明變量是io變量;type必須是char、short、int和unsigned;port表示io地址,hex_num是十六進制地址。下例聲明了一個io變量,地址為10H,并對I/O端口做讀/寫操作。3.DSPI/O端口的訪問ioportunsignedport10; /*定義地址為10H的I/O端口變量*/intfunc(){...port10=20;/*write20toport10H*/...b=port10;/*readport10Hintob*/...}ioportunsignedport10; C語言和匯編語言的混合編程方法用C語言和匯編語言混合編程的方法主要有以下三種:

(1)獨立編寫C程序和匯編程序,分開編譯或匯編以形成各自的目標(biāo)代碼模塊,然后用鏈接器將C模塊和匯編模塊鏈接起來。例如,主程序用C語言編寫,中斷向量文件(vector.asm)用匯編語言編寫。若要從C程序中訪問匯編程序的變量,將匯編語言程序在.bss塊中定義的變量或函數(shù)名前面加一下劃線"_",將變量說明為外部變量,同時在C程序中也將變量說明為外部變量,如下例所示:C語言和匯編語言的混合編程方法

匯編程序:

.bss_var,1 ;定義變量

.global_var ;說明為外部變量

C程序:

externintvar; /*外部變量*/var=1; /*訪問變量*/

若要在匯編程序中訪問C程序變量或函數(shù),也可以采用同樣的方法。匯編程序:C程序:globalint i; /*定義i為全局變量*/globalfloat x; /*定義x為全局變量*/main(){

}C程序:匯編程序:.ref _i; ;說明_i為外部變量.ref _x; ;說明_x為外部變量LD @_i,DPSTL _x,A匯編程序:

(2)在C語言程序的相應(yīng)位置直接嵌入?yún)R編語句,這是一種C和匯編之間比較直接的接口方法。嵌入?yún)R編語句的方法比較簡單,只需在匯編語句的左、右加上一個雙引號,用小括弧將匯編語句括住,在括弧前加上asm標(biāo)識符即可,如下所示:

asm("匯編語句");如上所述,在C程序中直接嵌入?yún)R編語句的一個典型應(yīng)用是控制DSP芯片的一些硬件資源。

(2)在C語言程序的相應(yīng)位置直接嵌

對于TMS320C5409,在C程序中一般采用下列匯編語句實現(xiàn)一些硬件控制:

asm("NOP"); /*插入等待周期*/asm("ssbxINTM"); /*關(guān)中斷*/asm("rsbxINTM"); /*開中斷*/(3)對C程序進行編譯生成相應(yīng)的匯編程序,然后對匯編程序進行手工優(yōu)化和修改。

對于TMS320C5409,在C程序中中斷函數(shù)

TMS320C54xC/C++中可以通過兩種方式定義中斷函數(shù)。

(1)通過給每個中斷函數(shù)前面加關(guān)鍵字interrupt來聲明一個函數(shù)為中斷處理函數(shù)。中斷函數(shù)的返回值是void的,函數(shù)沒有任何的形參。中斷函數(shù)可以任意使用局部變量和堆棧。例如:中斷函數(shù)interruptvoidint_handler(){unsignedintflags;...}interruptvoidint_handler()

為了能夠讓相應(yīng)的中斷信號調(diào)用不同的中斷函數(shù),還需要在中斷向量文件(vector.asm)中定義中斷向量表。如下例所示:

.ref_c_int00 .ref_int_handler .sect"vectors"RS: BD_c_int00 NOP NOP為了能夠讓相應(yīng)的中斷信號調(diào)用不同的中...BRINT1:B_int_handler;McBSP1接收中斷

.ref_int_handlerNOP NOP.end...(2)C中斷程序采用特殊的函數(shù)名,其格式為c_intnn。其中,nn代表00~99之間的兩位數(shù),如c_int01就是一個有效的中斷函數(shù)名。下面是一個中斷函數(shù)的例子:

intdatain,dateout;voidc_int05(){datain=sample(dataout);}(2)C中斷程序采用特殊的函數(shù)名存儲器模式

TMS320C54x將存儲器分為程序空間和數(shù)據(jù)空間。程序空間存放的是可執(zhí)行的代碼,數(shù)據(jù)空間存放的是外部變量、靜態(tài)變量和系統(tǒng)的堆棧。由C程序產(chǎn)生的代碼和數(shù)據(jù)就被放置在存儲空間的各個段中。存儲器模式1.C編譯器生成的段

C編譯器對C語言程序編譯后生成6個可以進行重定位的代碼和數(shù)據(jù)段,這些段可以用不同的方式分配至存儲器以符合不同系統(tǒng)配置的需要。這6個段可以分為兩種類型,一是已初始化段,二是未初始化段。1.C編譯器生成的段

已初始化段主要包括數(shù)據(jù)表和可執(zhí)行代碼。C編譯器共創(chuàng)建3個已初始化段:.text、

.cinit、.const。

.text段:包含可執(zhí)行代碼和字符串。

.cinit段:包含初始化變量和常數(shù)表。

.const段:字符串和switch表。

.bss段:保留全局和靜態(tài)變量空間。

.stack段:為系統(tǒng)堆棧分配存儲器。

.sysmem段:為動態(tài)存儲器函數(shù)malloc、calloc和realloc分配存儲器空間。

已初始化段主要包括數(shù)據(jù)表和可執(zhí)行代碼

一般地,.text、.cinit和.const連同匯編語言中的.data段可鏈入到系統(tǒng)的ROM或RAM中,而.bss、.stack和.sysmem段則應(yīng)鏈入到RAM中。一般地,.text、.cinit和.2.C系統(tǒng)的堆棧

C編譯器利用TMS320C54x內(nèi)置的堆棧機制來實現(xiàn)如下功能:

(1)保護函數(shù)的返回地址;

(2)分配局部變量;

(3)傳遞函數(shù)變量;

(4)保護臨時結(jié)果。2.C系統(tǒng)的堆棧3.動態(tài)存儲器分配編譯器提供的運行支持函數(shù)中包含幾個允許在運行時為變量動態(tài)分配存儲器的函數(shù),如malloc、calloc和recalloc。動態(tài)分配并不是C語言本身的標(biāo)準(zhǔn),而是由標(biāo)準(zhǔn)運行支持函數(shù)所提供的。3.動態(tài)存儲器分配4.存儲器大小模式編譯器支持兩種存儲器模式:小存儲器模式和大存儲器模式。

(l)小存儲器模式。小存儲器模式是編譯器的缺省存儲器模式。

(2)大存儲器模式。大存儲器模式與小存儲器模式的區(qū)別在于它不限制.bss段的大小,因此對全局變量和靜態(tài)變量來說,具有無限的空間。

4.存儲器大小模式其他注意事項

下面介紹C語言編程的一些其他注意事項。

(1)c_int00函數(shù)包含在運行支持庫中,必須與其他的C目標(biāo)模塊相鏈接。

(2)采用C優(yōu)化編譯時,為了保證程序的正確性,要特別注意,如果使用asm行匯編語句,則必須對編譯后得到的匯編語言進行仔細的檢查,以確保asm語句在程序中的正確性。

其他注意事項(3)可以使用volatile關(guān)鍵字避免優(yōu)化。對于下例這樣的語句:

unsignedint*data;while(*data!=4);

由于*data是一個循環(huán)不變的表達式,因此這個循環(huán)將被優(yōu)化為一個存儲器讀指令。為了避免這樣的優(yōu)化,需要將data定義為volatile,例如:

volatileunsignedint*data;(3)可以使用volatile關(guān)鍵字

做了這樣的定義后,優(yōu)化器就不再對上述語句進行優(yōu)化了。一般在reg.h中定義的寄存器地址都定義為volatile,例如:

#defineIMR (volatileunsignedint*)0x0000#defineIFR (volatileunsignedint*)0x0001

做了這樣的定義后,優(yōu)化器就不再對上述

(4)C54xC/C++編譯器支持標(biāo)準(zhǔn)C的關(guān)鍵字const,這個關(guān)鍵字用來定義那些值不變的變量,但是,在定義時const的位置是十分重要的。例如,下面這個例子中,第一句定義了一個常量指針p,指向一個int變量,第二句定義了一個指針q,指向一個常量int變量,所以要注意const的位置。

int*constp=&x;constint*q=&x;(4)C54xC/C++編譯(5)由于在C語言的環(huán)境下,局部變量的尋址必須通過SP寄存器實現(xiàn),在混合編程的時候,為了使匯編語言不影響堆棧寄存器SP,常用的方式是在匯編環(huán)境中使用DP方式尋址,這樣可以使二者互不干擾,編程時只要注意對CPL位正確設(shè)置即可。CPL位是編譯模式控制位,它表示在相對直接尋址時采用哪種指針。當(dāng)CPL=0時,使用頁指針DP;當(dāng)CPL=1時,使用堆棧指針SP。(5)由于在C語言的環(huán)境下,局部變(6)編譯后的C程序“跑飛”一般是對不存在的存儲區(qū)訪問造成的。首先,要查.map文件與memorymap圖對比,看是否超出范圍。如果在有中斷的程序中“跑飛”,則應(yīng)重點檢查在中斷程序中是否對所用到的寄存器進行了壓棧保護;如果在中斷程序中調(diào)用了C程序,則要查匯編后的C程序中是否用到了沒有被保護的寄存器并提供保護(在C程序的編譯中是不對A、B等寄存器進行保護的)。(6)編譯后的C程序“跑飛”一般是存儲器接口設(shè)計(不講)TMS320C5409的存儲器接口

1.TMS320C5409與外部SRAM的接口除了內(nèi)部32K字RAM和16K字ROM之外,TMS320C5409還可以擴展外部存儲器。其中,數(shù)據(jù)空間總共為64K字(0000H~FFFFH),I/O空間為64K字(0000H~FFFFH),程序空間為8M。8M程序空間的尋址是通過額外的7根地址線(A16~A22)實現(xiàn)的,由XPC寄存器控制。下面介紹幾種擴展外部RAM的方法。存儲器接口設(shè)計(不講)TMS320C5409的存儲器接口(1)外接一個128K×16位的RAM,將程序區(qū)和數(shù)據(jù)區(qū)分開。圖8-7為采用128K字RAM分開程序區(qū)和數(shù)據(jù)區(qū)的接口方法,圖中采用程序選通線()接外部RAM的A16地址線實現(xiàn)。因此,程序區(qū)為RAM的前64K字(0000H~FFFFH),數(shù)據(jù)區(qū)為RAM的后64K字(10000H~1FFFFH)。對DSP而言,程序區(qū)和數(shù)據(jù)區(qū)的地址范圍均為0000H~FFFFH。(1)外接一個128K×16位的R

采用這種外部存儲器配置,需要注意以下幾點:●如果內(nèi)部RAM設(shè)置為有效,則相同地址的外部RAM自動無效。●當(dāng)外部RAM不能全速運行時,需要根據(jù)速度設(shè)置插入等待狀態(tài)(設(shè)置SWWSR寄存器)。采用這種外部存儲器配置,需要注意以下幾圖8-7分開的數(shù)據(jù)和程序空間配置圖8-7分開的數(shù)據(jù)和程序空間配置(2)混合程序區(qū)和數(shù)據(jù)區(qū)。當(dāng)OVLY=1時,內(nèi)部RAM既是數(shù)據(jù)區(qū)又是程序區(qū)。這樣設(shè)置的優(yōu)點是程序可以在內(nèi)部全速運行,缺點是由于程序和數(shù)據(jù)是共用的,因此存儲區(qū)就變小了。此外,在鏈接時必須將程序和數(shù)據(jù)分開,以避免重疊。(2)混合程序區(qū)和數(shù)據(jù)區(qū)。當(dāng)OVLY圖8-8混合的程序和數(shù)據(jù)空間配置圖8-8混合的程序和數(shù)據(jù)空間配置(3)一種優(yōu)化的混合程序和數(shù)據(jù)區(qū)外接RAM方法。圖8-9所示為一種優(yōu)化的混合程序和數(shù)據(jù)區(qū)外接RAM方法。這種配置方法省去了DSP的A15地址線,將RAM分為32K字長的塊。采用這種方法后,可充分利用外接的RAM,不會因內(nèi)部RAM和外部RAM的地址重疊而造成外部RAM的浪費。下面分析外部RAM的地址安排。(3)一種優(yōu)化的混合程序和數(shù)據(jù)區(qū)外圖8-9優(yōu)化的混合程序和數(shù)據(jù)空間配置圖8-9優(yōu)化的混合程序和數(shù)據(jù)空間配置●外部RAM的0000H~7FFFH對應(yīng)于DSP數(shù)據(jù)區(qū)的8000H~FFFFH和程序區(qū)的08000H~0FFFFH及18000H~1FFFFH?!裢獠縍AM的8000H~FFFFH對應(yīng)于DSP程序區(qū)的28000H~2FFFFH和38000H~3FFFFH?!裢獠縍AM的10000H~1FFFFH對應(yīng)于DSP程序區(qū)的48000H~4FFFFH和58000H~5FFFFH?!裢獠縍AM的18000H~1FFFFH對應(yīng)于DSP程序區(qū)的68000H~6FFFFH和78000H~7FFFFH?!裢獠縍AM的0000H~7FFF2.TMS320C5409與Flash的接口

1)器件簡介

SST39VF400A是SiliconStorage公司的新一代256K×16位CMOSFlashMemory產(chǎn)品。它的特點是擦除和編程都采用SuperFlash技術(shù)來實現(xiàn),使得它編程所需的電流比較低,并且擦除時間短,進而保證了SST39VF400A編程和擦寫所需消耗的能量比較低。同時,SuperFlash技術(shù)能夠保證編程和擦寫時間不受已編程數(shù)據(jù)塊的影響。這種特性使得在系統(tǒng)設(shè)計時不用考慮軟件或者硬件上調(diào)整系統(tǒng)的讀/寫速率。2.TMS320C5409與FlasSST39VF400A的引腳圖及引腳說明(以DIP32封裝為例)見圖8-10。

SST39VF400A還有另外兩種封裝模式:TFBGA和TSOP32。由于FlashMemory結(jié)構(gòu)與EPROM和E2PROM都有明顯的區(qū)別,因此這里僅對它的基本工作原理做一簡介。圖8-11給出它的結(jié)構(gòu)框圖。SST39VF400A的引腳圖及引圖8-10SST39VF400A的引腳圖及其說明圖8-10SST39VF400A的引腳圖及其說明圖8-11SST39VF400A的結(jié)構(gòu)框圖圖8-11SST39VF400A的結(jié)構(gòu)框圖

輸入的存儲地址通過地址緩存后,分別送入到X地址譯碼器和Y地址譯碼器中,得到相應(yīng)的主存儲器陣列的X地址和Y地址。主存儲器通過X和Y地址找出相應(yīng)的主存儲器單元,將存儲單元中的值發(fā)送到輸入/輸出緩存中,通過控制邏輯來確定芯片的輸入/輸出。表8-2給出了SST39VF400A的工作方式選擇真值表。輸入的存儲地址通過地址緩存后,分別送入表8-2SST39VF400A工作方式選擇真值表表8-2SST39VF400A工作方式選擇真值表2)SST39VF400A與TMS320C5409的接口圖8-12為TMS320C5409與Flash的一種接口方法。圖中,F(xiàn)lash采用SST39VF400A(256K×16位)作為DSP的外部數(shù)據(jù)存儲器,地址總線和數(shù)據(jù)總線接至DSP的外部總線,接至DSP的。DSP上的XF引腳用于啟動編程,當(dāng)XF為低時,F(xiàn)lash處于讀狀態(tài);當(dāng)XF為高時,F(xiàn)lash可擦或編程。為了滿足SST39VF400A的時序要求,XF與相“或”后接至,R/引腳與相或后接至。2)SST39VF400A與TM圖8-12DSP與Flash的接口圖8-12DSP與Flash的接口8.4.2Flash擦寫在實際應(yīng)用中,選擇的片外存儲器通常是片外的RAM或FlashMemory。但由于RAM中數(shù)據(jù)掉電即丟失,不適合長期保存數(shù)據(jù),因此當(dāng)需要保存到片外存儲器的是一些無需頻繁讀/寫但需要長期保存的數(shù)據(jù)時,如字模數(shù)據(jù)、端口地址等,通常選擇使用片外的Flash擴展DSP芯片的存儲器空間。使用片外Flash必須要解決對其擦寫的問題。8.4.2Flash擦寫

在實際的應(yīng)用中,對片外Flash的擦寫有兩種方式,一是使用通用編程器對Flash芯片進行擦寫;二是直接由DSP對Flash進行擦寫。對于需要反復(fù)修改或已安裝在電路板上的Flash芯片,無法使用第一種方式,只能采用第二種方式,這樣易于調(diào)試。這里介紹一種利用存儲器映射技術(shù),通過對DSP芯片編程實現(xiàn)片外Flash擦寫的方法。在實際的應(yīng)用中,對片外Flash的擦

假設(shè)要將一組二維數(shù)組形式的數(shù)據(jù)(character[180][32])存入片外數(shù)據(jù)Flash的0x8000~0xA000地址段中,先做以下準(zhǔn)備工作:

(1)利用一個GPIO端口,擴展系統(tǒng)的可尋址數(shù)據(jù)存儲器空間。

(2)編寫Flash擦寫程序,程序流程如圖8-13所示。假設(shè)要將一組二維數(shù)組形式的數(shù)據(jù)(ch#defineN100 /*由于Flash與RAM的讀寫速度不同,因此需要在每項操作后加入若干個延時以保證正確性,延時的長短可以根據(jù)具體情況做調(diào)整*/voidmain(){unsignedinti,code;unsignedint*code_addr;unsignedint*flash_addr;#defineN100 /*由于Flash*GPIO_DR=0x0002; /*映射方式設(shè)置為映射到片外數(shù)據(jù)Flash*/delay(N);GPIOD_setup(); /*GPIOD設(shè)置*/delay(N);erase_flash(); /*如果Flash上原有數(shù)據(jù)無需保留,則全部擦除;如果部分?jǐn)?shù)據(jù)需保留,也可部分擦除*/delay(N);*GPIO_DR=0x0002; *GPIO_DR=0x0000;/*映射方式設(shè)置為映射到片內(nèi)RAM*/delay(N);flash_addr=(unsignedint*)Flash_ADDR;code_addr=(unsignedint*)CODE_ADDR;/*設(shè)置RAM的存儲起始地址和數(shù)據(jù)Flash擦寫起始地址*//*循環(huán)擦寫*/*GPIO_DR=0x0000;for(i=0;i<WRITE_LENGTH;i++){*GPIO_D_DR=0x0000;delay(N);code=*(code_addr++); /*保存RAM中數(shù)據(jù)到變量code*/delay(N);*GPIO_DR=0x0002;delay(N);for(i=0;i<WRITE_LENGTH;pre_write_flash(); /*寫Flash前的預(yù)處理,向Flash內(nèi)寫入相應(yīng)命令字,根據(jù)所選用Flash的不同,預(yù)處理操作也有所不同*/delay(N);*(flash_addr++)=code; /*寫數(shù)據(jù)到Flash中*/delay(N);}}pre_write_flash();圖8-13Flash擦寫程序流程圖圖8-13Flash擦寫程序流程圖

擦寫步驟如下:

(1)將character[180][32]設(shè)置為全局變量。

(2)將程序編譯下載到DSP芯片中,打開工程目錄中output文件夾中的.map文件,找到character數(shù)組在RAM中存放的起始地址和長度。

(3)使用SaveMemory命令將RAM中對應(yīng)于character數(shù)組的地址段的數(shù)據(jù)以二進制形式保存在計算機上。擦寫步驟如下:(4)打開Flash擦寫程序,修改數(shù)據(jù)在片內(nèi)RAM中存儲的起始地址和Flash的擦寫起始地址與數(shù)據(jù)長度。

(5)再次打開Flash擦寫程序,單步執(zhí)行到映射方式置為片外Flash處停止,然后使用SaveMemory命令保存Flash中剛寫入的地址段的數(shù)據(jù)值,接著使用UltraEdit的比較文件命令比較前兩次保存的數(shù)據(jù),如完全相同就表明character字模/數(shù)組已經(jīng)正確地寫到片外Flash中。(4)打開Flash擦寫程序,修改8.4.3Bootload設(shè)計

1.自舉加載器(Bootloader)

自舉加載器的主要功能是,在上電時從外部加載并執(zhí)行用戶的程序代碼。TMS320C54x的自舉加載共有并行EPROM(Flash)、并行I/O、串行口、HPI口和熱自舉五種方式,其中前三種又分8位和16位兩種。8.4.3Bootload設(shè)計1)選擇自舉方式在硬件復(fù)位期間,如果TMS320C54x的MP/為低電平,則從片外的0FF80H開始執(zhí)行程序,選擇過程如圖8-14所示。1)選擇自舉方式圖8-14自舉加載方式的選擇過程圖8-14自舉加載方式的選擇過程

在片內(nèi)ROM的0FF80H地址上,有一條分支轉(zhuǎn)移指令,以啟動制造商在ROM的自舉加載器程序。具體加載方法如下:

(1)在自舉加載前進行初始化。初始化的內(nèi)容如下:●INTM=1,禁止所有的中斷。●OVLY=1,將片內(nèi)雙尋址RAM和單尋址RAM映像到程序/數(shù)據(jù)空間。在片內(nèi)ROM的0FF80H地址上,有一●SWWSR=7FFFH,所有程序和數(shù)據(jù)空間都插入7個等待狀態(tài)?!馚SCR=0FFFFH,設(shè)定外部存儲區(qū)分區(qū)為4K字,當(dāng)程序和數(shù)據(jù)空間切換時,插入一個等待周期。●SWWSR=7FFFH,所有程(2)檢查,決定是否從主機接口(HPI)加載。如果沒有鎖存信號,說明不是從HPI加載,否則從HPI到RAM自舉加載。

(3)使I/O選通信號()為低電平,從地址為0FFFFH的I/O口讀入自舉程序選擇字(BRS)。BRS的低8位確定了自舉加載的方式,其內(nèi)容和引導(dǎo)方式的對應(yīng)關(guān)系如表8-3所示。表8-3中,x表示無效,SRC表示并行方式的6位頁地址,ADDR表示熱自舉方式的6位頁地址。(2)檢查,決定是否從表8-3TMS320C5409引導(dǎo)方式方式0FFFFH單元低8位內(nèi)容8位串行口xxxx000016位串行口xxxx01008位并行I/Oxxxx100016位并行I/Oxxxx11008位并行EPROMSRC0116位并行EPROMSRC10熱自舉ADDR11表8-3TMS320C5409引導(dǎo)方式方式0F2)8/16位并行自舉加載的實現(xiàn)

TMS320C54x通常都采用從EPROM或Flash引導(dǎo)的方式,這里著重討論并行Boot的實現(xiàn)。Boot程序首先讀入外部數(shù)據(jù)區(qū)的FFFEH和FFFFH兩個地址的內(nèi)容,并把它們組裝成1個16位字作為代碼存放的源地址,根據(jù)這個地址,從外部數(shù)據(jù)區(qū)讀入連續(xù)的兩個8位字節(jié),并組裝成1個16位字。2)8/16位并行自舉加載的實

由于Boot已經(jīng)設(shè)定好相應(yīng)的數(shù)據(jù)存放格式,因此在Flash組織數(shù)據(jù)就成為關(guān)鍵。下面做以下假設(shè)來具體說明Flash的數(shù)據(jù)組織方法。存放在Flash中的控制代碼和用戶代碼的首地址為外部數(shù)據(jù)區(qū)的8000H,等待狀態(tài)數(shù)為7個,Bank長度為64K字,程序執(zhí)行的入口點地址為2000H,程序代碼的長度為400H,用戶代碼存放在片內(nèi)程序區(qū)的首地址為2000H,則Flash中的數(shù)據(jù)組織如表8-4所示。表內(nèi)括號中的H表示高8位,L表示低8位。由于Boot已經(jīng)設(shè)定好相應(yīng)的數(shù)據(jù)存放表8-4Flash的數(shù)據(jù)組織數(shù)據(jù)區(qū)地址(Hex)內(nèi)容(Hex)含義8000H08H8位Boot標(biāo)識(H)8001HAAH8位Boot標(biāo)識(L)8002H7FHSWWSR(H)8003HFFHSWWSR(L)8004HF8HBSCR(H)8005H00HBSCR(L)8006H00H程序入口XPC(H)8007H00H程序入口XPC(L)8008H20H程序入口地址(H)8009H00H程序入口地址(L)800AH04H程序塊長度(H)表8-4Flash的數(shù)據(jù)組織數(shù)據(jù)區(qū)地址(Hex)內(nèi)容(800BH00H程序塊長度(L)800CH00H存放目標(biāo)XPC(H)800DH00H存放目標(biāo)XPC(L)800EH20H存放目標(biāo)地址(H)800FH00H存放目標(biāo)地址(L)8010HxxH程序代碼1(H)8011HxxH程序代碼1(L)………880EHxxH程序代碼N(H)880FHxxH程序代碼N(L)8810H00H塊結(jié)束標(biāo)志(H)8811H00H塊結(jié)束標(biāo)志(L)………FFFEH80H代碼存放首地址(H)FFFFH00H代碼存放首地址(L)800BH00H程序塊長度(L)800CH00H存放目標(biāo)XP3)熱自舉熱自舉方式是在RESET信號臨近釋放時,按照用戶定義的地址,改變TMS320C54x的程序執(zhí)行方向。熱自舉方式并不傳送自舉表,而是指示TMS320C54x按照自舉加載器程序讀入的BRS中所規(guī)定的地址起執(zhí)行,如圖8-15所示。3)熱自舉圖8-15熱自舉圖8-15熱自舉4)從HPI口自舉加載

HPI是一個將主處理器與TMS320C54x連接在一起的8位并行口,主處理器和TMS320C54x通過共享的片內(nèi)存儲器交換信息。從HPI口自舉加載的示意圖如圖8-16所示。4)從HPI口自舉加載圖8-16從HPI口自舉加載圖8-16從HPI口自舉加載5)從I/O自舉加載

I/O自舉方式就是從I/O的0H口異步傳送程序代碼到內(nèi)部/外部程序存儲器,其自舉加載方框圖如圖8-17所示。5)從I/O自舉加載圖8-17從I/O自舉加載圖8-17從I/O自舉加載6)從串行口自舉加載從串行口自舉加載就是TMS320C54x從串行口傳送程序代碼至程序存儲器,并執(zhí)行程序,如圖8-18所示。6)從串行口自舉加載圖8-18從串行口自舉加載圖8-18從串行口自舉加載2.Bootload與片外SRAM沖突的解決由于Bootload的尋址區(qū)是在數(shù)據(jù)區(qū),即Flash只能接在數(shù)據(jù)空間,即用片選,因此如果設(shè)計的DSP系統(tǒng)需要外接SRAM作為外部數(shù)據(jù)存儲空間,就會和Flash產(chǎn)生地址沖突。另一方面,當(dāng)程序全部從FlashBoot到所指定的目的地址以后,用于存放程序的Flash在系統(tǒng)的運行過程中就不再起任何作用。2.Bootload與片外SRAM沖5.軟件調(diào)試

(1)利用開發(fā)系統(tǒng)進行在線調(diào)試,如單步、斷點等。

(2)分塊調(diào)試。檢驗各程序模塊正確性的方法需要根據(jù)各模塊的實際情況而定。

(3)模塊間通信調(diào)試。

(4)系統(tǒng)軟件聯(lián)調(diào),在測試各項指標(biāo)參數(shù)時,注意進行參數(shù)補償。5.軟件調(diào)試6.調(diào)試技巧

(1)如果不慎將DSP燒壞,就要從板子上面把DSP拿下來??梢杂眉氥~絲穿過DSP的一排引腳,將銅絲的一端固定,一邊用烙鐵燙DSP的引腳一邊用銅絲切割DSP的引腳。這樣可以完好無損地將DSP拿下,保護了焊盤。

(2)焊DSP、SRAM一類的多引腳貼片封裝的芯片時,先將芯片與焊盤對齊,用烙鐵點芯片的四個腳將芯片固定在板子上,然后用烙鐵將焊錫均勻的涂在芯片的一側(cè)管腳上,用吸錫線將管腳旁邊的錫吸掉。其他幾面用同樣的方法即可。6.調(diào)試技巧(3)有關(guān)C編程的技巧參見8.2節(jié)。軟硬件調(diào)試成功后就可以脫離仿真器。首先通過CCSIDE將整個系統(tǒng)的軟件按照8.4.2介紹的Flash擦寫方法寫入Flash,其中寫入Flash的數(shù)據(jù)組織形式參見8.4.3節(jié)Bootload設(shè)計,這樣系統(tǒng)就可以成為獨立運行的DSP系統(tǒng)。(3)有關(guān)C編程的技巧參見8.2謝謝觀賞!2020/11/591謝謝觀賞!2020/11/591第講c語言介紹DSP芯片應(yīng)用第講c語言介紹DSP芯片應(yīng)用第講c語言介紹DSP芯片應(yīng)用DSP芯片C語言開發(fā)簡介TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型表1列出了TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型的大小、表示形式和表示范圍,這些數(shù)據(jù)類型在float.h和limits.h中定義。在C語言開發(fā)的過程中,采用合適的數(shù)據(jù)類型對于系統(tǒng)的正確運行有著極為重要的意義。第講c語言介紹DSP芯片應(yīng)用第講c語言介紹DSP92DSP芯片C語言開發(fā)簡介TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型表1列出了TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型的大小、表示形式和表示范圍,這些數(shù)據(jù)類型在float.h和limits.h中定義。在C語言開發(fā)的過程中,采用合適的數(shù)據(jù)類型對于系統(tǒng)的正確運行有著極為重要的意義。DSP芯片C語言開發(fā)簡介TMS320C54xC/C++編表1TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型類型bit表示形式最小值最大值signedchar16ASCII?3276832767charunsignedchar16ASCII065535short,signedshort162sComplement?3276832767unsignedshort16Binary065535int,signedint162sComplement?3276832767表1TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型類型大小/bit表示形式最小值最大值unsignedint16Binary065535long,signedlong322sComplement?21474836482147483647unsignedlong32Binary04294967295enum162sComplement?3276832767float32IEEE32-bit1.175494e?383.40282346e+38double32IEEE32-bit1.175494e?383.40282346e+38longdouble32IEEE32-bit1.175494e?383.40282346e+38pointers16Binary00xFFFF類型大小/bit表示形式最小值最大值unsignediC語言的數(shù)據(jù)訪問方法

1.DSP片內(nèi)寄存器的訪問

DSP片內(nèi)寄存器在C語言中一般采用指針方式來訪問,常常采用的方法是將DSP寄存器地址的列表定義在頭文件中(如reg.h)。DSP寄存器地址定義的形式為宏,如下所示:C語言的數(shù)據(jù)訪問方法#defineIMR (volatileunsignedint*)0x0000#defineIFR (volatileunsignedint*)0x0001#defineST0(volatileunsignedint*)0x0006#defineST1 (volatileunsignedint*)0x0007#defineAL (volatileunsignedint*)0x0008#defineIMR (volatileunsig#defineAH(volatileunsignedint*)0x0009#defineAG(volatileunsignedint*)0x000A#defineBL(volatileunsignedint*)0x000B#defineBH (volatileunsignedint*)0x000C#defineBG (volatileunsignedint*)0x000D第講--c語言介紹-DSP芯片應(yīng)用課件#defineT (volatileunsignedint*)0x000E#defineTRN (volatileunsignedint*)0x000F#defineAR0 (volatileunsignedint*)0x0010#defineAR1 (volatileunsignedint*)0x0011#defineAR2 (volatileunsignedint*)0x0012#defineSP (volatileunsignedint*)0x0018#defineBK (volatileunsignedint*)0x0019#defineT (volat#defineBRC (volatileunsignedint*)0x001A#defineRSA (volatileunsignedint*)0x001B#defineREA (volatileunsignedint*)0x001C#definePMST (volatileunsignedint*)0x001D#defineXPC (volatileunsignedint*)0x001E#defineBRC (volatileunsi

在主程序中,若要讀出或者寫入一個特定的寄存器,就要對相應(yīng)的指針進行操作。下例通過指針操作對SWWSR和BSCR進行初始化。

#defineSWWSR (volatileunsignedint*)0x0028#defineBSCR (volatileunsignedint*)0x0029

在主程序中,若要讀出或者寫入一個特定intfunc(){...

*SWWSR=0x2000;*BSCR=0x0000;...}intfunc()

2.DSP內(nèi)部和外部存儲器的訪問同DSP片內(nèi)寄存器的訪問相類似,對存儲器的訪問也采用指針方式來進行。下例通過指針操作對內(nèi)部存儲器單元0x3000和外部存儲器單元0x8FFF進行操作。2.DSP內(nèi)部和外部存儲器的訪問int*data1=0x3000; /*內(nèi)部存儲器單元*/int*data2=0x8FFF; /*外部存儲器單元*/intfunc(){...

*data1=2000;*data2=0;...}int*data1=0x3000; /*內(nèi)部存儲器3.DSPI/O端口的訪問

DSPI/O端口的訪問通過ioport關(guān)鍵字實現(xiàn)。定義的形式為

ioporttypeporthex_num

其中:ioport是關(guān)鍵字,表明變量是io變量;type必須是char、short、int和unsigned;port表示io地址,hex_num是十六進制地址。下例聲明了一個io變量,地址為10H,并對I/O端口做讀/寫操作。3.DSPI/O端口的訪問ioportunsignedport10; /*定義地址為10H的I/O端口變量*/intfunc(){...port10=20;/*write20toport10H*/...b=port10;/*readport10Hintob*/...}ioportunsignedport10; C語言和匯編語言的混合編程方法用C語言和匯編語言混合編程的方法主要有以下三種:

(1)獨立編寫C程序和匯編程序,分開編譯或匯編以形成各自的目標(biāo)代碼模塊,然后用鏈接器將C模塊和匯編模塊鏈接起來。例如,主程序用C語言編寫,中斷向量文件(vector.asm)用匯編語言編寫。若要從C程序中訪問匯編程序的變量,將匯編語言程序在.bss塊中定義的變量或函數(shù)名前面加一下劃線"_",將變量說明為外部變量,同時在C程序中也將變量說明為外部變量,如下例所示:C語言和匯編語言的混合編程方法

匯編程序:

.bss_var,1 ;定義變量

.global_var ;說明為外部變量

C程序:

externintvar; /*外部變量*/var=1; /*訪問變量*/

若要在匯編程序中訪問C程序變量或函數(shù),也可以采用同樣的方法。匯編程序:C程序:globalint i; /*定義i為全局變量*/globalfloat x; /*定義x為全局變量*/main(){

}C程序:匯編程序:.ref _i; ;說明_i為外部變量.ref _x; ;說明_x為外部變量LD @_i,DPSTL _x,A匯編程序:

(2)在C語言程序的相應(yīng)位置直接嵌入?yún)R編語句,這是一種C和匯編之間比較直接的接口方法。嵌入?yún)R編語句的方法比較簡單,只需在匯編語句的左、右加上一個雙引號,用小括弧將匯編語句括住,在括弧前加上asm標(biāo)識符即可,如下所示:

asm("匯編語句");如上所述,在C程序中直接嵌入?yún)R編語句的一個典型應(yīng)用是控制DSP芯片的一些硬件資源。

(2)在C語言程序的相應(yīng)位置直接嵌

對于TMS320C5409,在C程序中一般采用下列匯編語句實現(xiàn)一些硬件控制:

asm("NOP"); /*插入等待周期*/asm("ssbxINTM"); /*關(guān)中斷*/asm("rsbxINTM"); /*開中斷*/(3)對C程序進行編譯生成相應(yīng)的匯編程序,然后對匯編程序進行手工優(yōu)化和修改。

對于TMS320C5409,在C程序中中斷函數(shù)

TMS320C54xC/C++中可以通過兩種方式定義中斷函數(shù)。

(1)通過給每個中斷函數(shù)前面加關(guān)鍵字interrupt來聲明一個函數(shù)為中斷處理函數(shù)。中斷函數(shù)的返回值是void的,函數(shù)沒有任何的形參。中斷函數(shù)可以任意使用局部變量和堆棧。例如:中斷函數(shù)interruptvoidint_handler(){unsignedintflags;...}interruptvoidint_handler()

為了能夠讓相應(yīng)的中斷信號調(diào)用不同的中斷函數(shù),還需要在中斷向量文件(vector.asm)中定義中斷向量表。如下例所示:

.ref_c_int00 .ref_int_handler .sect"vectors"RS: BD_c_int00 NOP NOP為了能夠讓相應(yīng)的中斷信號調(diào)用不同的中...BRINT1:B_int_handler;McBSP1接收中斷

.ref_int_handlerNOP NOP.end...(2)C中斷程序采用特殊的函數(shù)名,其格式為c_intnn。其中,nn代表00~99之間的兩位數(shù),如c_int01就是一個有效的中斷函數(shù)名。下面是一個中斷函數(shù)的例子:

intdatain,dateout;voidc_int05(){datain=sample(dataout);}(2)C中斷程序采用特殊的函數(shù)名存儲器模式

TMS320C54x將存儲器分為程序空間和數(shù)據(jù)空間。程序空間存放的是可執(zhí)行的代碼,數(shù)據(jù)空間存放的是外部變量、靜態(tài)變量和系統(tǒng)的堆棧。由C程序產(chǎn)生的代碼和數(shù)據(jù)就被放置在存儲空間的各個段中。存儲器模式1.C編譯器生成的段

C編譯器對C語言程序編譯后生成6個可以進行重定位的代碼和數(shù)據(jù)段,這些段可以用不同的方式分配至存儲器以符合不同系統(tǒng)配置的需要。這6個段可以分為兩種類型,一是已初始化段,二是未初始化段。1.C編譯器生成的段

已初始化段主要包括數(shù)據(jù)表和可執(zhí)行代碼。C編譯器共創(chuàng)建3個已初始化段:.text、

.cinit、.const。

.text段:包含可執(zhí)行代碼和字符串。

.cinit段:包含初始化變量和常數(shù)表。

.const段:字符串和switch表。

.bss段:保留全局和靜態(tài)變量空間。

.stack段:為系統(tǒng)堆棧分配存儲器。

.sysmem段:為動態(tài)存儲器函數(shù)malloc、calloc和realloc分配存儲器空間。

已初始化段主要包括數(shù)據(jù)表和可執(zhí)行代碼

一般地,.text、.cinit和.const連同匯編語言中的.data段可鏈入到系統(tǒng)的ROM或RAM中,而.bss、.stack和.sysmem段則應(yīng)鏈入到RAM中。一般地,.text、.cinit和.2.C系統(tǒng)的堆棧

C編譯器利用TMS320C54x內(nèi)置的堆棧機制來實現(xiàn)如下功能:

(1)保護函數(shù)的返回地址;

(2)分配局部變量;

(3)傳遞函數(shù)變量;

(4)保護臨時結(jié)果。2.C系統(tǒng)的堆棧3.動態(tài)存儲器分配編譯器提供的運行支持函數(shù)中包含幾個允許在運行時為變量動態(tài)分配存儲器的函數(shù),如malloc、calloc和recalloc。動態(tài)分配并不是C語言本身的標(biāo)準(zhǔn),而是由標(biāo)準(zhǔn)運行支持函數(shù)所提供的。3.動態(tài)存儲器分配4.存儲器大小模式編譯器支持兩種存儲器模式:小存儲器模式和大存儲器模式。

(l)小存儲器模式。小存儲器模式是編譯器的缺省存儲器模式。

(2)大存儲器模式。大存儲器模式與小存儲器模式的區(qū)別在于它不限制.bss段的大小,因此對全局變量和靜態(tài)變量來說,具有無限的空間。

4.存儲器大小模式其他注意事項

下面介紹C語言編程的一些其他注意事項。

(1)c_int00函數(shù)包含在運行支持庫中,必須與其他的C目標(biāo)模塊相鏈接。

(2)采用C優(yōu)化編譯時,為了保證程序的正確性,要特別注意,如果使用asm行匯編語句,則必須對編譯后得到的匯編語言進行仔細的檢查,以確保asm語句在程序中的正確性。

其他注意事項(3)可以使用volatile關(guān)鍵字避免優(yōu)化。對于下例這樣的語句:

unsignedint*data;while(*data!=4);

由于*data是一個循環(huán)不變的表達式,因此這個循環(huán)將被優(yōu)化為一個存儲器讀指令。為了避免這樣的優(yōu)化,需要將data定義為volatile,例如:

volatileunsignedint*data;(3)可以使用volatile關(guān)鍵字

做了這樣的定義后,優(yōu)化器就不再對上述語句進行優(yōu)化了。一般在reg.h中定義的寄存器地址都定義為volatile,例如:

#defineIMR (volatileunsignedint*)0x0000#defineIFR (volatileunsignedint*)0x0001

做了這樣的定義后,優(yōu)化器就不再對上述

(4)C54xC/C++編譯器支持標(biāo)準(zhǔn)C的關(guān)鍵字const,這個關(guān)鍵字用來定義那些值不變的變量,但是,在定義時const的位置是十分重要的。例如,下面這個例子中,第一句定義了一個常量指針p,指向一個int變量,第二句定義了一個指針q,指向一個常量int變量,所以要注意const的位置。

int*constp=&x;constint*q=&x;(4)C54xC/C++編譯(5)由于在C語言的環(huán)境下,局部變量的尋址必須通過SP寄存器實現(xiàn),在混合編程的時候,為了使匯編語言不影響堆棧寄存器SP,常用的方式是在匯編環(huán)境中使用DP方式尋址,這樣可以使二者互不干擾,編程時只要注意對CPL位正確設(shè)置即可。CPL位是編譯模式控制位,它表示在相對直接尋址時采用哪種指針。當(dāng)CPL=0時,使用頁指針DP;當(dāng)CPL=1時,使用堆棧指針SP。(5)由于在C語言的環(huán)境下,局部變(6)編譯后的C程序“跑飛”一般是對不存在的存儲區(qū)訪問造成的。首先,要查.map文件與memorymap圖對比,看是否超出范圍。如果在有中斷的程序中“跑飛”,則應(yīng)重點檢查在中斷程序中是

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論