《TMS320C54X DSP原理及應(yīng)用》課件第8章_第1頁
《TMS320C54X DSP原理及應(yīng)用》課件第8章_第2頁
《TMS320C54X DSP原理及應(yīng)用》課件第8章_第3頁
《TMS320C54X DSP原理及應(yīng)用》課件第8章_第4頁
《TMS320C54X DSP原理及應(yīng)用》課件第8章_第5頁
已閱讀5頁,還剩253頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第8章DSP芯片應(yīng)用8.1引言8.2DSP芯片C語言開發(fā)簡介8.3模/數(shù)接口設(shè)計8.4存儲器接口設(shè)計8.5G.726語音編解碼系統(tǒng)8.6語音實時變速系統(tǒng)

8.1引言

前面幾章我們介紹了DSP芯片的原理以及CCS開發(fā)工

具。TMS320C5409是目前性能價格比較高的一種定點(diǎn)DSP

芯片,已經(jīng)在很多領(lǐng)域得到了廣泛的應(yīng)用。本章以TMS320C5409為例,介紹DSP應(yīng)用系統(tǒng)的設(shè)計、調(diào)試和開

發(fā)過程。8.2DSP芯片C語言開發(fā)簡介

8.2.1TMS320C54xC/C++編譯器支持的數(shù)據(jù)類型

表8-1列出了TMS320C54xC/C++編譯器支持的數(shù)據(jù)類

型的大小、表示形式和表示范圍,這些數(shù)據(jù)類型在float.h和limits.h中定義。在C語言開發(fā)的過程中,采用合適的數(shù)據(jù)類型對于系統(tǒng)的正確運(yùn)行有著極為重要的意義。8.2.2C語言的數(shù)據(jù)訪問方法

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

DSP片內(nèi)寄存器在C語言中一般采用指針方式來訪問,常用的方法是將DSP寄存器地址的列表定義在頭文件(如reg.h)中。DSP寄存器地址定義的形式為宏,如下所示:

#defineIMR (volatileunsignedint*)0x0000

#defineIFR(volatileunsignedint*)0x0001

#defineST0 (volatileunsignedint*)0x0006

#defineST1 (volatileunsignedint*)0x0007

#defineAL (volatileunsignedint*)0x0008

#defineAH (volatileunsignedint*)0x0009

#defineAG (volatileunsignedint*)0x000A

#defineBL (volatileunsignedint*)0x000B

#defineBH (volatileunsignedint*)0x000C

#defineBG (volatileunsignedint*)0x000D

#defineT (volatileunsignedint*)0x000E

#defineTRN (volatileunsignedint*)0x000F

#defineAR0 (volatileunsignedint*)0x0010

#defineAR1 (volatileunsignedint*)0x0011

#defineAR2 (volatileunsignedint*)0x0012

#defineSP (volatileunsignedint*)0x0018

#defineBK (volatileunsignedint*)0x0019

#defineBRC (volatileunsignedint*)0x001A

#defineRSA (volatileunsignedint*)0x001B

#defineREA (volatileunsignedint*)0x001C

#definePMST (volatileunsignedint*)0x001D

#defineXPC (volatileunsignedint*)0x001E在主程序中,若要讀出或者寫入一個特定的寄存器,就

要對相應(yīng)的指針進(jìn)行操作。下例通過指針操作對SWWSR和BSCR進(jìn)行初始化。

#defineSWWSR (volatileunsignedint*)0x0028

#defineBSCR (volatileunsignedint*)0x0029

intfunc(?)

{

*SWWSR=0x2000;

*BSCR=0x0000;

}

2.DSP內(nèi)部和外部存儲器的訪問

同DSP片內(nèi)寄存器的訪問相類似,對存儲器的訪問也采用指針方式來進(jìn)行。下例通過指針操作對內(nèi)部存儲器單元0x3000和外部存儲器單元0x8FFF進(jìn)行操作。

int*data1=0x3000; /*內(nèi)部存儲器單元*/

int*data2=0x8FFF; /*外部存儲器單元*/

intfunc(?)

{

*data1=2000;

*data2=0;

}

3.DSPI/O端口的訪問

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

式為:

ioporttypeporthex_num

其中,ioport是關(guān)鍵字,表示變量是I/O變量;type必須是char、short、int和unsigned;port表示I/O地址,hex_num是十六進(jìn)制地址。下例聲明了一個I/O變量,地址為10H,并對I/O端口進(jìn)行讀/寫操作。

ioportunsignedport10;/*定義地址為10H的I/O端口變量*/

intfunc(?)

{

port10=20;/*writeatoport10H*/

...

b=port10;/*readport10Hintob*/

}8.2.3C語言和匯編語言的混合編程方法

用C語言和匯編語言混合編程的方法主要有以下三種:

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

.bss _var,1 ;定義變量

.global _var ;說明為外部變量

C程序:

externintvar; /*外部變量*/

var=1; /*訪問變量*/若要在匯編程序中訪問C程序變量或函數(shù),也可以采用同樣的方法。

C程序:

globalint i; /*定義i為全局變量*/

globalfloat x; /*定義x為全局變量*/

main(?)

{

}匯編程序:

.ref _i; ;?說明_i為外部變量

.ref _x; ;?說明_x為外部變量

LD @_i,DP

STL _x,A

(2)在C語言程序的相應(yīng)位置直接嵌入?yún)R編語句,這是一種C語言和匯編語言之間比較直接的接口方法。采用這種方法一方面可以在C語言中實現(xiàn)用C語言不好實現(xiàn)的一些硬件控制功能,如插入等待狀態(tài)、中斷使能或禁止等;另一方面,也可以用這種方法在C程序中的關(guān)鍵部分用匯編語句代替C語句以優(yōu)化這個程序。但是,采用這種方法的一個缺點(diǎn)是比較容易破壞C環(huán)境,因為C編譯器在編譯嵌入了匯編語句的C程序時并不檢查或分析所嵌入的匯編語句,在后面的注意事項中我們還會提到。嵌入?yún)R編語句的方法比較簡單,只需在匯編語句的左、右加上一個雙引號,用小括弧將匯編語句括住,在括弧前加上asm標(biāo)識符即可,如下所示:

asm(“匯編語句”);

如上所述,在C程序中直接嵌入?yún)R編語句的一個典型應(yīng)用是控制DSP芯片的一些硬件資源。對于TMS320C5409,在C程序中一般采用下列匯編語句實現(xiàn)一些硬件控制,如下所示:

asm(“NOP”); /*插入等待周期*/

asm(“ssbxINTM”); /*關(guān)中斷*/

asm(“rsbxINTM”); /*開中斷*/

除硬件控制外,匯編語句也可以嵌入在C程序中實現(xiàn)其他功能,但是TI建議不要采用這種方法改變C變量的數(shù)值,因為這容易改變C環(huán)境。

(3)對C程序進(jìn)行編譯生成相應(yīng)的匯編程序,然后對匯編程序進(jìn)行手工優(yōu)化和修改。這種方法通過查看交叉列表的匯編程序,可以對某些編譯不是很優(yōu)但卻是比較關(guān)鍵的匯編語句進(jìn)行修改。修改匯編語句時,必須嚴(yán)格遵循不破壞C環(huán)境的原則。因此,這種方法需要程序員對C編譯器及C環(huán)境有充分的理解,一般不推薦使用這種方法。8.2.4中斷函數(shù)

當(dāng)C程序被中斷時,中斷處理函數(shù)與其他函數(shù)不同,進(jìn)入函數(shù)前需要保護(hù)所有的寄存器的值,在中斷函數(shù)返回時恢復(fù)被保護(hù)的寄存器。對于擴(kuò)展精度寄存器來說,由于可能包含整數(shù)或浮點(diǎn)數(shù),而中斷程序并不能確定寄存器中數(shù)值的類型,因此,中斷程序必須保護(hù)所有的40位數(shù)據(jù)。如果中斷程序不調(diào)用其他函數(shù),則只有那些在中斷程序中用到的寄存器才予以保護(hù)。但是,如果C中斷程序調(diào)用其他函數(shù),則中斷程序?qū)⒈Wo(hù)所有的表達(dá)式寄存器。

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

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

interruptvoidint_handler(?)

{

unsignedintflags;

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

.ref_c_int00

.ref_int_handler

.sect“vectors”

RS: BD_c_int00

NOP

NOP

BRINT1: BD_int_handler?;McBSP1接收中斷

NOP

NOP

.end

其中,_int_handler就是我們上小節(jié)提到的用C語言和匯編語言混合編程時,在匯編語言中訪問C程序變量時要在變量或函數(shù)名前面加一下劃線“_”。

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

intdatain,dateout;

voidc_int05(?)

{

datain=sample(dataout);

}在所有的c_intnn函數(shù)中,最特殊的是c_int00函數(shù)。c_int00是C程序的入口點(diǎn),是為系統(tǒng)復(fù)位中斷保留的,這個特殊的中斷程序用于初始化系統(tǒng)和調(diào)用main函數(shù)。由于c_int00本身并沒有調(diào)用其他程序,因此它不需要保存任何寄存器。運(yùn)行c_int00函數(shù)有多種方法,可以跳轉(zhuǎn)到這個函數(shù),也可以調(diào)用這個函數(shù),還可以作為硬件復(fù)位后的中斷矢量的入口(如上例所示)。8.2.5存儲器模式

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

1.C編譯器生成的段

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

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

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

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

.const段:字符串和switch表。在大存儲器模式下,常數(shù)

表也包含在?.const段中。

未初始化段用于保留存儲器空間,程序利用這些空間在

運(yùn)行時創(chuàng)建和存儲變量。C編譯器創(chuàng)建三個未初始化段:

.bss、.stack和?.sysmem段。

.bss段:保留全局和靜態(tài)變量空間。在小模式中,.bss段也為常數(shù)表保留空間。在程序開始運(yùn)行時,C初始化Boot程序?qū)?shù)據(jù)從?.cinit段中拷貝至?.bss段。

.stack段:為系統(tǒng)堆棧分配存儲器。這個存儲器用于將變量傳送至函數(shù),以及分配局部變量。

.sysmem段:為動態(tài)存儲器函數(shù)malloc、calloc和realloc分配存儲器空間。當(dāng)然,若C程序沒有用到這些函數(shù),編譯器就不創(chuàng)建?.sysmem段。一般地,.text、.cinit和?.const段連同匯編語言中的?.data

段可鏈入到系統(tǒng)的ROM或RAM中,而?.bss段、.stack段和?.sysmem段則應(yīng)鏈入到RAM中。需要注意的是,如果系統(tǒng)不支持將?.data塊鏈入到數(shù)據(jù)空間,則必須將.data段鏈入到程序空間,運(yùn)行的時候再調(diào)入數(shù)據(jù)空間,它的cmd文件如下所示:

MEMORY

{

PAGE0:PROG:...

PAGE1:DATA:...

}

SECTIONS

{

.const:load=PROGPAGE1,run=DATAPAGE1

{

/*GETRUNADDRESS*/

_const_run=.;

/*MARKLOADADDRESS*/

*(.c_mark)

/*ALLOCATE.const*/

*(.const)

/*COMPUTELENGTH*/

_const_length=.–_?const_run;

}

}

2.C系統(tǒng)的堆棧

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

功能:

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

(2)分配局部變量。

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

(4)保護(hù)臨時結(jié)果。

C系統(tǒng)的堆棧是分配的一塊從高地址到低地址的連續(xù)存儲空間,C編譯器利用堆棧指針(SP)寄存器來管理堆找。

局部幀是堆棧的一個區(qū)域,用于存儲函數(shù)傳遞的變量和局部變量。每一個函數(shù)被調(diào)用時都要在堆棧項創(chuàng)建一個新的局部幀。

C環(huán)境在調(diào)用C函數(shù)時自動管理這些寄存器。當(dāng)匯編與C語言接口時,注意必須采用與C語言一樣的方式使用這些寄存器。堆棧的大小可以由鏈接器設(shè)定。鏈接器創(chuàng)建一個全局符號_stack_size,并給它分配一個與堆棧大小一樣的數(shù)值,缺省值為400H,即1?K字。更改堆棧大小的方法非常簡單,只需在鏈接器選項?_stack后面加上一個大小等于堆棧的常數(shù)即可。

系統(tǒng)初始化后,SP指向堆棧的底部,其值等于堆棧底部的地址,也就是.stack段的首地址。因此,由于堆棧的位置取決于?.stack段的分配,因而堆棧的實際位置是在鏈接階段確定的。若將堆棧分配至存儲器的最后一塊,則堆棧具有無限的增長空間。

特別需要注意的是,由于C編譯器不提供檢查堆棧溢出的任何手段,因此必須保證有足夠的空間用于堆棧,否則若發(fā)生溢出現(xiàn)象,將破壞程序的運(yùn)行環(huán)境,從而導(dǎo)致程序的癱瘓。

3.動態(tài)存儲器分配

編譯器提供的運(yùn)行支持函數(shù)中包含幾個允許在運(yùn)行時為變量動態(tài)分配存儲器的函數(shù),如malloc、calloc和recalloc。動態(tài)分配并不是C語言本身的標(biāo)準(zhǔn),而是由標(biāo)準(zhǔn)運(yùn)行支持函數(shù)所提供的。為全局變量pool或heap分配的內(nèi)存定義在.sysmem段中。

.sysmem段的大小可在鏈接時用_heap選項設(shè)定,設(shè)置方法是在該選項后面加上一個常數(shù)。同樣,鏈接器也創(chuàng)建一個全局符號_sysmem_size,并將.sysmem段的大小賦予這個符號,缺省的大小為1K字。動態(tài)分配的目標(biāo)一般用指針尋址,其存儲區(qū)在一個獨(dú)立的段中。因此,即使在小模式下,動態(tài)內(nèi)存區(qū)也可有無限的大小。如此,即使在程序中說明了大的數(shù)據(jù)目標(biāo),也可以使用效率更高的小存儲器模式。為了在?.bss段中保留空間,可用heap分配大的數(shù)據(jù),以代替將它們說明為全局或靜態(tài)。例如:

structbigtable[100];

可以用指針并調(diào)用malloc函數(shù)來實現(xiàn),如下所示:

structbig*table;

table=(structbig*)malloc(100*sizeof(structbig));

4.存儲器大小模式

(l)小存儲器模式。小存儲器模式是編譯器的缺省存儲器模式。在這種模式下,要求整個?.bss段能匹配一個獨(dú)立的64K字存儲器頁。也就是說,程序中所有的靜態(tài)和全局?jǐn)?shù)據(jù)必須小于64K字,并且?.bss段不能跨越任何的64?K字地址邊界。編譯器在運(yùn)行初始化時,將數(shù)據(jù)頁指針寄存器DP指向.bss段的開始,隨后,編譯器就可以用直接尋址(@)訪問.bss中的所有目標(biāo)(如全局變量、靜態(tài)變量、常數(shù)表等),而不用修改DP寄存器。

(2)大存儲器模式。大存儲器模式與小存儲器模式的區(qū)別在于它不限制?.bss段的大小,因此對全局變量和靜態(tài)變量來說,具有無限的空間。但是,當(dāng)編譯器訪問任意存儲在?.bss段中的全局或靜態(tài)變量時,首先必須保證DP正確地指向目標(biāo)所在的存儲器頁。為了做到這一點(diǎn),在每一次訪問全局或靜態(tài)變量時,編譯器必須用LDP指令來設(shè)置DP寄存器。8.2.6其他注意事項

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

(1)?c_int00函數(shù)包含在運(yùn)行支持庫中,必須與其他的C目標(biāo)模塊相鏈接。在鏈接時,如果用?_c或?_cr選項,并包含實時運(yùn)行支持庫rts.lib,則c_int00就自動鏈入。鏈接C程序時,

鏈接器將可執(zhí)行模塊的入口點(diǎn)設(shè)置為c_int00。

(2)采用C優(yōu)化編譯時,為了保證程序的正確性,要特別注意,如果使用asm行匯編語句,則必須對編譯后得到的匯編語言進(jìn)行仔細(xì)的檢查,以確保asm語句在程序中的正確性。一般而言,當(dāng)asm語句僅涉及諸如控制中斷寄存器等硬件操作時,使用優(yōu)化是比較安全的。

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

unsignedint*data;

while(*data!=4);

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

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

#defineIMR (volatileunsignedint*)0x0000

#defineIFR (volatileunsignedint*)0x0001

(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;

(5)由于在C語言的環(huán)境下,局部變量的尋址必須通過SP寄存器實現(xiàn),在混合編程的時候,為了使匯編語言不影響堆棧寄存器SP,常用的方式是在匯編環(huán)境中使用DP方式尋址,這樣可以使二者互不干擾,編程時只要注意對CPL位進(jìn)行正確設(shè)置即可。CPL位是編譯模式控制位,它表示在相對直接尋址時采用哪種指針。當(dāng)CPL=0時,使用頁指針DP;當(dāng)CPL=1時,使用堆棧指針SP。

(6)編譯后的C程序“跑飛”一般是對不存在的存儲區(qū)進(jìn)行訪問而造成的。首先,要查.map文件與memorymap圖對比,看是否超出范圍。如果在有中斷的程序中“跑飛”,則應(yīng)重點(diǎn)檢查在中斷程序中是否對所用到的寄存器進(jìn)行了壓棧保護(hù);如果在中斷程序中調(diào)用了C程序,則要查匯編后的C程序中是否用到了沒有被保護(hù)的寄存器并提供保護(hù)(在C程序的編譯中是不對A、B等寄存器進(jìn)行保護(hù)的)。8.3模/數(shù)接口設(shè)計

8.3.1TLC320AD50及其接口

圖8-1是TLC320AD50的引腳圖。圖8-1TLC320AD50的引腳圖

1.TLC320AD50控制寄存器功能簡介

TLC320AD50具有7個可編程的內(nèi)部寄存器,通過軟件編程能隨時控制TLC320AD50的采樣頻率、模擬輸入及輸出的增益等。

控制寄存器0(CR0):不執(zhí)行任何操作,但是CR0能夠響應(yīng)握手通信請求而不改變其他控制寄存器的值??刂萍拇嫫?(CR1):控制TLC320AD50的軟件重啟,選擇數(shù)字反饋以及數(shù)/模轉(zhuǎn)換器的模式。

控制寄存器2(CR2):選擇模擬反饋以及模/數(shù)轉(zhuǎn)換器的模式,并且包括TLC320AD50內(nèi)部FIR濾波器的溢出標(biāo)志。

控制寄存器3(CR3):包含主設(shè)備連接從器件個數(shù)的信息。(當(dāng)某個器件向其他器件發(fā)送信息時,稱為主器件,而某器件從其他器件接收信息時,稱為從器件。)控制寄存器4(CR4):選擇輸入和輸出放大器的增益,確定TLC320AD50的采樣頻率,選擇PLL模式。

控制寄存器5(CR5):工業(yè)測試使用。

控制寄存器6(CR6):工業(yè)測試使用。

2.TLC320AD50器件功能簡介

1)采樣頻率和濾波器控制

TLC320AD50的采樣頻率由控制寄存器4設(shè)定。當(dāng)選擇PLL模式時(D7=0),TLC320AD50的采樣率為?(8-1)當(dāng)不選擇PLL模式時(D7=1),TLC320AD50的采樣率為(8-2)其中,N為1~8的整數(shù)。如果要設(shè)定的采樣頻率低于7?kHz,由于PLL工作的時鐘頻率必須高于7kHz,因此這種情況下不能使用TLC320AD50的PLL模式,必須使用非PLL模式,則相應(yīng)的采樣頻率也要由式(8-2)計算。

輸出的串口時鐘(SCLK)由采樣頻率決定而不是由主時鐘決定,串口時鐘與采樣頻率之間的關(guān)系為

SCLK=256×fs

TLC320AD50內(nèi)部濾波器的截止頻率是不能通過軟件編程改變的。

2)模/數(shù)轉(zhuǎn)化模塊

輸入的模擬信號經(jīng)過前端的放大器放大后,送入到A/D轉(zhuǎn)換器的輸入端。A/D轉(zhuǎn)換器將輸入的模擬信號轉(zhuǎn)化為以二進(jìn)制補(bǔ)碼表示的數(shù)字信號。轉(zhuǎn)化后的數(shù)字信號通過TLC320AD50內(nèi)部的可編程放大器后,在串口時鐘(SCLK)的上升沿從芯片的DOUT管腳輸出,每一個串口時鐘周期輸出1bit。通過設(shè)置控制寄存器2,可以設(shè)置A/D轉(zhuǎn)換器每次將模擬量轉(zhuǎn)化為16bit還是15bit的數(shù)字量。在握手通信期間,如果想讀出TLC320AD50內(nèi)部寄存器的值,可以向芯片的DIN管腳發(fā)送序列DS。DS12~DS8是相應(yīng)的寄存器地址,DS13=1表示讀取寄存器的值。這樣DOUT輸出的就是對應(yīng)的TLC320AD50內(nèi)部寄存器的值。

3)數(shù)/模轉(zhuǎn)化模塊

DIN管腳從外部設(shè)備讀入16bit的二進(jìn)制數(shù)據(jù),以補(bǔ)碼形式表示。在串口時鐘(SCLK)的下降沿,TLC320AD50讀入這些二進(jìn)制數(shù)據(jù),每一個串口時鐘周期輸入1bit。這些二進(jìn)制數(shù)據(jù)通過由數(shù)字插值濾波器和數(shù)字調(diào)制器組成的Σ–δD/A轉(zhuǎn)換器后轉(zhuǎn)換為脈沖串。這些脈沖串再被送入到TLC320AD50內(nèi)部的低通濾波器而恢復(fù)出模擬信號。模擬信號通過可編程放大器后在OUTP和OUTM輸出。

4)數(shù)字串行接口

數(shù)字串行接口由串行時鐘(SCLK)、幀同步信號(FS)、A/D轉(zhuǎn)換器輸出(DOUT)和D/A轉(zhuǎn)換器輸入(DIN)組成.在每一個串行時鐘周期(SCLK)中,A/D轉(zhuǎn)換器從DOUT引腳輸出轉(zhuǎn)化好的二進(jìn)制數(shù)據(jù),D/A轉(zhuǎn)換器從DIN引腳輸入需要轉(zhuǎn)化的二進(jìn)制數(shù)據(jù)。

此外,TLC320AD50內(nèi)部還包括了插值濾波器、數(shù)字和模擬反饋等部分。8.3.2模/數(shù)接口的硬件電路設(shè)計

圖8-2是TLC320AD50與TMS320C5409的McBSP之間的接口連線圖。圖8-2TLC320AD50與TMS320C5409的McBSP之間的接口從圖8-2中可以看出,TLC320AD50與TMS320C5409的McBSP之間的接口連接十分簡單,兩者之間的接口不需要其他的硬件支持。MCLK由TMS320C5409的CLOCKOUT提供,也可以使用單獨(dú)的晶振提供。當(dāng)CLK的頻率比較高時,也常

采用在CLKOUT和MCLK之間加入一個串行終端電阻(Series-terminationResistor)或者連接上一個零歐姆電阻來消除自激振蕩。TMS320C5409的XF設(shè)置為輸出,作為TLC320AD50的復(fù)位信號。

TLC320AD50的復(fù)位至少需要復(fù)位信號保持6個MCLK周期,這樣,TLC320AD50的復(fù)位可由TMS320C5409用軟件控制,從而可使TMS320C5409的定時器和McBSP在AIC進(jìn)行A/D和D/A轉(zhuǎn)換前進(jìn)行初始化。是TLC320AD50的幀同步信號,由DSP的McBSP提供。M/S為低電平時,TLC320AD50工作在從設(shè)備狀態(tài)。在設(shè)計TLC320AD50的印刷板電路時注意,必須要分別設(shè)計TLC320AD50的數(shù)字地和模擬地、數(shù)字電源和模擬電源。將數(shù)字地和模擬地分開,能夠避免器件產(chǎn)生的數(shù)字噪聲影響板上的其他模擬器件,以達(dá)到理想的信噪比要求。如果在系統(tǒng)的設(shè)計過程中只有一個可用的5?V電源同時作為數(shù)字電源和模擬電源,那么最好用適當(dāng)?shù)碾娮鑼?shù)字電源和模擬電源分開,數(shù)字電源和模擬電源的設(shè)計如圖8-3所示。圖8-3數(shù)字電源和模擬電源的設(shè)計圖8-3中的兩個電容和相應(yīng)的磁珠用來去耦,濾除電源輸出的噪聲。此外,TLC320AD50的許多管腳在與相應(yīng)的電源或地相連時,需要連接相應(yīng)的去耦電容。其去耦電路如圖8-4所示。其中,REFP和REFM之間的電容是帶隙基準(zhǔn)電壓的去耦電容;連接到FILT的電容是帶隙基準(zhǔn)的濾波電容。圖8-4TLC320AD50的去耦電路8.3.3模/數(shù)接口的軟件設(shè)計

1.TMS320C5409內(nèi)部寄存器的初始化

(1)初始化TMS320C5409的SWWSR、BSCR、ST0、ST1、PMST等寄存器,設(shè)置中斷屏蔽寄存器IMR來屏蔽所有的中斷,并置IFR=0xFFFF。

(2)設(shè)置定時器寄存器TIM、PRD和TCR的值,使得CLOCKOUT的輸出滿足TLC320AD50的要求。

2.TMS320C5409緩沖串口的初始化

TMS320C5409的McBSP由SPCR、RCR、XCR、SRGR、MCR、PCR等寄存器控制。由于TMS320C54xx系列DSP是TMS320C54x系列DSP的增強(qiáng)型DSP,因此,為了與TMS320C54x

DSP的寄存器地址兼容,TMS320C540x系列DSP對McBSP的寄存器采用了兩級尋址訪問的方法,對每一個McBSP都設(shè)置了兩個寄存器SPSA和SPCD。通過對SPSA寫入不同的二級地址,可以用SPCD訪問不同的二級寄存器SPCR、RCR、XCR、SRGR、MCR、PCR等。McBSP的初始化就是通過SPSA和SPCD來設(shè)置這些寄存器的值。初始化TMS320C5409緩沖串口的步驟如下:

(1)復(fù)位McBSP并設(shè)置控制寄存器(SPCR)幀同步信號和串口時鐘信號均為External。設(shè)置接受中斷信號由幀同步信號產(chǎn)生,用中斷的方式向McBSP發(fā)送數(shù)據(jù)(也可以采用DSP輪詢或DMA的方式,ABU模式),使能串行口中斷。

(2)設(shè)置McBSP的發(fā)送(XCR)和接受(RCR)控制寄存器,使接收到的每一幀包含一個字,每個字為16bit。

(3)設(shè)置McBSP的引腳控制寄存器(PCR),使串行口的所有引腳工作在串行口方式,而不是通用I/O方式。

(4)使能全局中斷,并使緩沖串行口脫離復(fù)位狀態(tài),

和置1。

3.TLC320AD50的初始化

在對上述TMS320C5409進(jìn)行初始化之前,首先置TLC320AD50的=0,用于復(fù)位TLC320AD50,使得TLC320AD50設(shè)置為缺省配置狀態(tài),并暫停TLC320AD50的工作。在TMS320C5409的內(nèi)部寄存器和McBSP初始化完成后,將置高,使TLC320AD50脫離復(fù)位狀態(tài),并且開始以缺省配置方式工作。復(fù)位后,TLC320AD50的所有寄存器均清零,因而上

電后,整個TLC320AD50的采樣頻率為8?kHz,可見TLC320AD50主要是用來進(jìn)行語音處理的。在TLC320AD50

的Master方式下,TLC320AD50輸出的幀同步信號的頻率和

它的采樣率相同。采用同步工作方式,輸出的串口時鐘則是256FS(采樣率),所以在這種情況下每幀只傳輸一個字(16bit)。對于一般的音頻應(yīng)用,TLC320AD50復(fù)位后的各寄存器的值已經(jīng)可以滿足應(yīng)用的要求,不需要再對TLC320AD50的各個寄存器進(jìn)行設(shè)置了,但是如果應(yīng)用中需要的采樣率不是復(fù)位后的8kHz,則需要設(shè)置TLC320AD50的各個寄存器。TLC320AD50有兩種配置方式:軟件方式和硬件方式。在軟件方式下,配置一個TLC320AD50寄存器需要發(fā)送兩次數(shù)據(jù),每次16bit。

TLC320AD50第一次接收到數(shù)據(jù)的高15位(1~15)bit為采樣數(shù)據(jù),若第一次的最低位(D0)為1,則接著第二次的16bit為控制信號。在硬件方式下,配置TLC320AD50寄存器是利用TLC320AD50的FC外部引腳,若FC置高電平,則通知TLC320AD50開始配置寄存器。從圖8-2可以看出,與FC腳相連的是DSP的XF引腳,利用SSBXXF指令使XF置為1,可通

知TLC320AD50進(jìn)行命令字的傳輸。軟件方式下配置一個寄存器需要傳輸兩次,太復(fù)雜,但是這種接口方式為串行音頻數(shù)據(jù)提供了一個專用通道而不需要占用DSP外部引腳(在復(fù)雜系統(tǒng)的設(shè)計中,DSP的引腳資源是有限的)。硬件方式下配置TLC320AD50比較簡單,只需要一次傳輸,但是要占用DSP的一個引腳。設(shè)計人員在設(shè)計系統(tǒng)的過程中,可以根據(jù)不同的應(yīng)用情況決定采取哪種方式。

TLC320AD50的初始化參數(shù)可以根據(jù)實際需要,利用式

(8-1)和式(8-2)計算。

TLC320AD50和McBSP之間同步串行通信的時序如圖8-5所示。圖8-5TLC320AD50和McBSP之間同步串行通信的時序

【例1】TLC320AD50應(yīng)用程序。

TLC320AD50應(yīng)用程序的c流程圖如圖8-6所示。

圖8-6C程序的流程圖

C程序代碼如下所示:

reg.h

#defineSPSA1(volatileunsignedint*)0x0048

//McBSP1

sub_addressregister

#defineSPSD1(volatileunsignedint*)0x0049

#defineSPCR11?0x0000

#defineSPCR21?0x0001

#defineRCR110x0002

#defineRCR210x0003

#defineXCR110x0004

#defineXCR210x0005

#definePCR1?0x000E

main.c

/*本程序是TLC320AD50與TMS320C5409通過緩沖串行口*/

/*通信的實例*/

#include<stdio.h>

#include"reg.h"

/*聲明所有用到的函數(shù)原型*/

voidinlinedisable(void);

voidinlineenable(void);

voidinterruptessp_rx(void);

voidinit_core(void);

voidinit_bsp(void);

voidinit_codec(void);

/*主程序*/

main(?)

{

init_core(?);

init_codec(?);

/*使能中斷屏蔽*/

enable(?);

?

/*等待直到下一個中斷到來*/

while(1);

}

/*初始化DSP內(nèi)部寄存器*/

voidinit_core(?)

{

/*設(shè)置外部存儲器的等待周期為0,I/O的等待周期為2*/

*SWWSR=0x2000;

*BSCR=0x0000;

*ST0=0x1800;

*ST1=0x2900;

/*設(shè)置中斷向量表的首地址為0x0080*/

*PMST=0x00A0;*IMR=0x0000;

*IFR=0xFFFF;/*清除所有的中斷標(biāo)志*/

}

voidinit_bsp(?)

{

/*McBSP0接收字符為右對齊,接收中斷由幀同步信號產(chǎn)生*/

*SPSA1=SPCR11;

*SPSD1=0x0020;

/*發(fā)送中斷由幀同步信號產(chǎn)生,McBSP0Tx=FREE(軟件中斷后時鐘停止運(yùn)行)*/

*SPSA1=SPCR21;

*SPSD1=0x0201;

/*接收幀長1個字,數(shù)據(jù)長度為16bit*/

*SPSA1=RCR11;

*SPSD1=0x0040;

/*設(shè)置奇數(shù)幀和偶數(shù)幀相同,數(shù)據(jù)長度為16?bit*/

*SPSA1=RCR21;

*SPSD1=0x0000;

/*與接收寄存器的設(shè)置相同*/

*SPSA1=XCR11;

*SPSD1=0x0040;

/*與接收寄存器的設(shè)置相同*/

*SPSA1=XCR21;

*SPSD1=0x0000;

*SPSA1=PCR1;

*SPSD1=0x000C;

asm(“NOP”);

asm(“NOP”);

}

/*初始化TLC320AD50*/

voidinit_codec(?)

{

disable(?);/*關(guān)閉所有中斷*/

/*初始化McBSP0*/

init_bsp(?);

/*設(shè)置中斷為串口發(fā)出而不是DMA*/

*DMPREC=*DMPREC&0xff3f;

*DXR11=0x0;

/*使能McBSP0接收數(shù)據(jù)*/

*SPSA1=SPCR11;

*SPSD1|=0x0001;

/*使能McBSP0發(fā)送數(shù)據(jù)*/

*SPSA1=SPCR21;

*SPSD1|=0x0001;

/*用軟件方式配置AD50寄存器*/

*DXR11=0x0003;

*SPSA1=SPCR21;

while(!(*SPSD1&0x0002)); /*循環(huán)直到字傳送完畢*/

*DXR11=0x0181; /*向控制寄存器CR1寫入0x0181(D7?=?1),復(fù)位TLC320AD50*/

while(!(*SPSD1&0x0002));

for(i=0;i<4000;i++); /*等待AD50復(fù)位*/*DXR11=0x0003;

while(!(*SPSD1&0x0002));

*DXR11=0x0101; /*向控制寄存器CR1寫入0x0101(D7=0),啟動TLC320AD50*/

while(!(*SPSD1&0x0002));

*DXR11=0x0003;

while(!(*SPSD1&0x0002));*DXR11=0x0210; /*向控制寄存器CR2寫入0x0210,設(shè)置為16bitADC模式*/

while(!(*SPSD1&0x0002));

*DXR11=0x0003;

while(!(*SPSD1&0x0002));

*DXR11=0x0300; /*向控制寄存器CR3寫入0x0300,TLC320AD50沒有從屬系統(tǒng)*/

while(!(*SPSD1&0x0002));*DXR11=0x0003;

while(!(*SPSD1&0x0002));

*DXR11=0x04D0; /*向控制寄存器CR4寫入0x04D0,設(shè)置增益為0dB,PLL模式*/

while(!(*SPSD1&0x0002));

asm(“NOP”);

asm("NOP");*IMR=0x0400; /*使能McBSP1的接收中斷*/

*IFR=0x0400; /*清除相應(yīng)的中斷標(biāo)志位*/

enable(?); /*使能所有中斷*/

/*Sendadummyvaluetostartthingsoff*/

*DXR11=*DRR11;

}

/*關(guān)閉所有中斷*/

voidinlinedisable(?)

{

asm(“ssbxINTM”);

}

/*使能所有中斷*/

voidinlineenable(?)

{

asm(“rsbxINTM”);

}

/*接收中斷處理函數(shù)*/

voidinterruptessp_rx(?)

{

intsample_in;

/*讀入采樣數(shù)據(jù)*/

sample_in=*DRR11;

/*傳送回TLC320AD50*/

*DXR11=sample_in;

}

vector.asm

.ref_c_int00

.ref_essp_rx

.sect"vectors"

RS: BD_c_int00

NOP

NOP

.space4*16*25;將接下來的25個中斷向量位置0

BRINT1: BD_essp_rx;McBSP的接收中斷

NOP

NOP

.end8.4存儲器接口設(shè)計

8.4.1TMS320C5409的存儲器接口

1.TMS320C5409與外部SRAM的接口

除了內(nèi)部32K字RAM和16?K字ROM之外,TMS320C5409還可以擴(kuò)展外部存儲器。其中,數(shù)據(jù)空間總共為64?K字(0000H~FFFFH),I/O空間為64?K字(0000H~FFFFH),程

序空間為8M。8M程序空間的尋址是通過額外的7根地址線(A16~A22)實現(xiàn)的,由XPC寄存器控制。

(1)外接一個128K×16位的RAM,將程序區(qū)和數(shù)據(jù)區(qū)分

開。圖8-7為分開的程序和數(shù)據(jù)空間配置,即采用128?K字RAM分開程序區(qū)和數(shù)據(jù)區(qū)的接口方法,圖中采用程序選通線

(

)接外部RAM的A16地址線實現(xiàn)。因此,程序區(qū)為RAM

的前64?K字(0000H~FFFFH),數(shù)據(jù)區(qū)為RAM的后64?K字(10000H~1FFFFH)。對DSP而言,程序區(qū)和數(shù)據(jù)區(qū)的地址范圍均為0000H~FFFFH。采用這種外部存儲器配置,需要注意以下幾點(diǎn):

●如果內(nèi)部RAM設(shè)置為有效,則相同地址的外部RAM自動無效。

●當(dāng)外部RAM不能全速運(yùn)行時,需要根據(jù)速度設(shè)置插入等待狀態(tài)(設(shè)置SWWSR寄存器)。圖8-7分開的程序和數(shù)據(jù)空間配置

(2)混合程序區(qū)和數(shù)據(jù)區(qū)。當(dāng)OVLY=1時,內(nèi)部RAM既是程序區(qū),又是數(shù)據(jù)區(qū)。這樣設(shè)置的優(yōu)點(diǎn)是程序可以在內(nèi)部全速運(yùn)行,缺點(diǎn)是由于程序和數(shù)據(jù)是共用的,因此存儲區(qū)就變小了。此外,在鏈接時必須將程序和數(shù)據(jù)分開,以避免重疊。利用程序和數(shù)據(jù)共用存儲器可以達(dá)到上述目的。方法是將

和信號線接至一與非門,形成PDS信號,這個信號不論是有效(低電平)還是有效(低電平)都呈現(xiàn)有效(高電平)。將這個信號反向后用作片選信號,就可保證外部RAM既作為程序區(qū),又作為數(shù)據(jù)區(qū),混合的程序和數(shù)據(jù)空間配置如圖8-8所示。圖8-8混合的程序和數(shù)據(jù)空間配置圖中A15與、接至與非門,從而保證了PCS_RAM信號只有當(dāng)A15和、同時為高電平時才變?yōu)橛行У牡碗娖?,所以PCS_RAM的尋址空間是8000H~FFFFH。上述電路使得程序和數(shù)據(jù)都存儲在同一片SRAM中,不論是程序還是數(shù)據(jù)都可訪問8000H~FFFFH中的任一地址。為了保證系統(tǒng)的正確運(yùn)行,一般需將這32?K字空間劃分為程序區(qū)和數(shù)據(jù)區(qū),如程序占據(jù)8000H~BFFFH前16?K字,數(shù)據(jù)占據(jù)C000H~FFFFH后16?K字,也可以是程序占8K字,數(shù)據(jù)占24K字等,劃分完全取決于應(yīng)用程序的需要。程序員可根據(jù)實際系統(tǒng)的情況,靈活地劃分程序和數(shù)據(jù)空間,但不管如何劃分,必須保證程序和數(shù)據(jù)區(qū)的相互分離,以免發(fā)生沖突。

(3)一種優(yōu)化的混合程序和數(shù)據(jù)區(qū)外接RAM方法。圖8-9所示的是一種優(yōu)化的混合程序和數(shù)據(jù)空間配置。這種配置方法省去了DSP的A15地址線,將RAM分為32K字長的塊。采用這種方法后,可充分利用外接的RAM,不會因內(nèi)部RAM和外部RAM的地址重疊而造成外部RAM的浪費(fèi)。下面分析外部RAM的地址安排。圖8-9優(yōu)化的混合程序和數(shù)據(jù)空間配置●外部RAM的0000H~7FFFH對應(yīng)于DSP數(shù)據(jù)區(qū)的8000H~FFFFH和程序區(qū)的08000H~0FFFFH及18000H~1FFFFH。

●外部RAM的8000H~FFFFH對應(yīng)于DSP程序區(qū)的28000H~2FFFFH和38000H~3FFFFH。●外部RAM的10000H~1FFFFH對應(yīng)于DSP程序區(qū)的48000H~4FFFFH和58000H~5FFFFH。

●外部RAM的18000H~1FFFFH對應(yīng)于DSP程序區(qū)的68000H~6FFFFH和78000H~7FFFFH。由于外部擴(kuò)展的程序空間很大,因此DSP程序區(qū)另外的地址空間也能訪問到外部RAM。這種優(yōu)化的外部RAM配置方法使得在使用DSP內(nèi)部RAM的情況下,能夠充分利用外部擴(kuò)展RAM。

2.TMS320C5409與Flash的接口

1)器件簡介

SST39VF400A是SiliconStorage公司的新一代256K×16

位CMOSFlashMemory產(chǎn)品。它的特點(diǎn)是擦除和編程都采用SuperFlash技術(shù)來實現(xiàn),使得它編程所需的電流比較低,并且擦除時間短,進(jìn)而保證了SST39VF400A編程和擦寫所需消耗的能量比較低。同時,SuperFlash技術(shù)能夠保證編程和擦寫時間不受已編程數(shù)據(jù)塊的影響。這種特性使得設(shè)計系統(tǒng)時不用考慮在軟件或者硬件上調(diào)整系統(tǒng)的讀/寫速率。

SST39VF400A的引腳圖及其說明(以DIP32封裝為例)如圖8-10所示。

SST39VF400A還有另外兩種封裝模式:TFBGA和TSOP32。由于FlashMemory結(jié)構(gòu)與EPROM和E2PROM都有明顯的區(qū)別,因此這里僅對它的基本工作原理做一簡介。圖8-11給出了它的結(jié)構(gòu)框圖。圖8-10SST39VF400A的引腳圖及其說明圖8-11SST39VF400A的結(jié)構(gòu)框圖輸入的存儲地址通過地址緩存后,分別送入到X地址譯碼器和Y地址譯碼器中,得到相應(yīng)的主存儲器陣列的X地址和Y地址。主存儲器通過X和Y地址找出相應(yīng)的主存儲器單元,將存儲單元中的值發(fā)送到輸入/輸出緩存中,通過控制邏輯來確定芯片的輸入/輸出。表8-2給出了SST39VF400A的工作方式選擇真值表。

2)?TMS320C5409與SST39VF400A的接口

圖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/引腳與相或后接至。圖8-12MS320C5409與Flash的接口方式8.4.2Flash擦寫

在實際應(yīng)用中,選擇的片外存儲器通常是片外的RAM或FlashMemory。但由于RAM中的數(shù)據(jù)掉電即丟失,不適合長期保存數(shù)據(jù),因此當(dāng)需要保存到片外存儲器的是一些無需頻繁讀/寫但需要長期保存的數(shù)據(jù)時,如字模數(shù)據(jù)、端口地址等,通常選擇使用片外的Flash來擴(kuò)展DSP芯片的存儲器空間。使用片外Flash必須要解決對其進(jìn)行擦寫的問題。在實際的應(yīng)用中,對片外Flash的擦寫有兩種方式,一是使用通用編程器對Flash芯片進(jìn)行擦寫;二是直接由DSP對Flash進(jìn)行擦寫。對于需要反復(fù)修改或已安裝在電路板上的Flash芯片,無法使用第一種方式,只能采用第二種方式,這樣易于調(diào)試。這里介紹一種利用存儲器映射的技術(shù),通過對DSP芯片的編程實現(xiàn)片外Flash擦寫的方法。

CCS5000IDE是TI公司專為TI的TMS320C54x和TMS320C54xx系列設(shè)計的開發(fā)平臺,該平臺具有簡單明了

的圖形用戶界面和豐富的軟件開發(fā)工具,適合于開發(fā)基于TMS320C54x系列的應(yīng)用程序、插件程序等各種程序代碼。在CCS環(huán)境中,用戶可以通過修改?.cmd文件來配置存儲器分配方式,還可以通過修改C5409對應(yīng)的初始化程序.gel文件來控制系統(tǒng)的初始化操作,程序員只需要在c5409.gel文件

的hotmenuC5409_Init()函數(shù)中加入需要的地址映射,如“GEL_MapAdd(0x8000u,1,0x8000u,1,1);”。用戶工程編譯并鏈接后,將生成?.map文件,在文件中可以看到存儲器的詳細(xì)分配情況。在用戶將程序下載到DSP芯片中后,用戶可以使用CCS的調(diào)試器對程序進(jìn)行全面的調(diào)試,如設(shè)置斷點(diǎn)、單步執(zhí)行等;可以使用WatchMemory工具來檢查存儲器中的各地址段的值;還可以使用Save/LoadMemory指令來保存或是載入某段存儲器的值。利用GPIO端口可以生成合適的片外Flash和片內(nèi)RAM片選信號,從而實現(xiàn)片內(nèi)RAM和片外Flash訪問的切換,在電路上可以實現(xiàn)將GPIO信號與數(shù)據(jù)選擇信號或程序選擇信號的相“或”。例如,當(dāng)GPIOD0=1時,0x8000~0xFFFF映射到片外SRAM,此時對于整個0x0000~0xFFFF地址范圍的讀/寫操作就是對于片外SRAM的操作;當(dāng)GPIOD0=0時,如果0x8000~0xFFFF地址范圍映射到數(shù)據(jù)Flash,則對0x8000~0xFFFF地址范圍的讀/寫操作就是對于片外Flash的操作,而對0x0000~0x7FFF地址范圍的讀/寫仍是針對片內(nèi)RAM的操作,從而將數(shù)據(jù)存儲空間擴(kuò)展了32K字。將映射方式設(shè)置為片內(nèi),將需要寫到Flash中的數(shù)據(jù)文件載入片內(nèi)RAM,根據(jù)需要設(shè)置GPIO端口值,切換地址映射的存儲器。這樣,通過地址映射的方法,便可實現(xiàn)將RAM中的數(shù)據(jù)寫入片外Flash的操作,而對于DSP芯片來說只是進(jìn)行了其RAM尋址空間內(nèi)部的數(shù)據(jù)搬移操作。假設(shè)要將一組二維數(shù)組形式的數(shù)據(jù)(character[180][32])存入片外數(shù)據(jù)Flash的0x8000~0xA000地址段中,先做以下準(zhǔn)備工作:

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

空間。

(2)編寫Flash擦寫程序。其程序流程如圖8-13所示。

#defineN100 ?/*由于Flash與RAM的讀寫速度不同,因此需要在每項操作后加入若干個延時以保證正確性,延時的長短可以根據(jù)具體情況做調(diào)整*/

voidmain(?)

{

unsignedinti,code;

unsignedint*code_addr;

unsignedint*flash_addr;

*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=0x0000; /*映射方式設(shè)置為映射到片內(nèi)RAM*/

delay(N);

flash_addr=(unsignedint*)Flash_ADDR;

code_addr=(unsignedint*)CODE_ADDR;

/*設(shè)置RAM的存儲起始地址和數(shù)據(jù)Flash的擦寫起始地址循環(huán)擦寫*/

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

pre_write_flash(?); /*寫Flash前的預(yù)處理,向Flash內(nèi)寫入相應(yīng)命令字,根據(jù)所選用Flash的不同,預(yù)處理操作也有所不同*/

delay(N);

*(flash_addr++)=code; /*寫數(shù)據(jù)到Flash中*/

delay(N);

}

}圖8-13Flash擦寫程序流程圖擦寫步驟如下:

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

(2)將程序編譯下載到DSP芯片中,打開工程目錄中output文件夾中的?.map文件,找到character數(shù)組在RAM中存放的起始地址和長度。用戶可以使用WatchMemory工具查看該段地址的數(shù)據(jù)值。

(3)使用SaveMemory命令將RAM中對應(yīng)于character數(shù)組的地址段的數(shù)據(jù)以二進(jìn)制形式保存在計算機(jī)上。通過UltraEdit將其打開,查看數(shù)據(jù)保存是否正確。

(4)打開Flash擦寫程序,修改數(shù)據(jù)在片內(nèi)RAM中存儲的起始地址和Flash的擦寫起始地址與數(shù)據(jù)長度。編譯下載后,單步執(zhí)行,直到擦除完Flash,并將地址映射方式置為映射到片內(nèi)RAM處,使用LoadMemory指令將char數(shù)據(jù)文件載入到片內(nèi)RAM的相應(yīng)存儲地址段中,再全速運(yùn)行程序,幾十秒之后程序執(zhí)行完畢,數(shù)據(jù)便寫到片外Flash的相應(yīng)地址中。

(5)再次打開Flash擦寫程序,單步執(zhí)行到映射方式置為片外Flash處停止,然后使用SaveMemory命令保存Flash中剛寫入的地址段的數(shù)據(jù)值,接著使用UltraEdit的比較文件命令比較前兩次保存的數(shù)據(jù),如完全相同就表明character字模/數(shù)組已被正確地寫到片外Flash中。將數(shù)據(jù)擦寫入片外數(shù)據(jù)Flash后,就可以在用戶程序中對該數(shù)據(jù)加以調(diào)用。在調(diào)用時,要先將映射方式設(shè)置為映射到片外Flash,再取數(shù)據(jù)。下述程序表示取出Flash中0x6000地址上存儲的數(shù)據(jù):

#defineFLASH_ADD(unsignedint*)0x6000

*GPIO_D_DR=0x0002;/*映射方式設(shè)置為映射到片外Flash*/

data=*(FLASH_ADD);這種通過地址映射方式的方法可適用于多種場合,針對多個Flash芯片而使用多個GPIO端口進(jìn)行地址的擴(kuò)展,即可實現(xiàn)對其進(jìn)行擦寫操作;若將部分擦寫程序放置到片外Flash中并做相應(yīng)設(shè)置,即可實現(xiàn)系統(tǒng)的自舉運(yùn)行等。8.4.3Bootload設(shè)計

1.自舉加載器(Bootloader)

自舉加載器的主要功能是,在上電時從外部加載并執(zhí)行

用戶的程序代碼。TMS320C54x的自舉加載共有并行EPROM(Flash)、并行I/O、串行口、HPI口和熱自舉五種方式,其中前三種又分8位和16位兩種。

1)選擇自舉方式

在硬件復(fù)位期間,如果TMS320C54x的MP/為高電平,則從片外的0FF80H開始執(zhí)行程序,自舉加載方式的選擇過程如圖8-14所示。圖8-14自舉加載方式的選擇過程

(1)在自舉加載前進(jìn)行初始化。初始化的內(nèi)容如下:

●?INTM=1,禁止所有的中斷。

●?OVLY=1,將片內(nèi)雙尋址RAM和單尋址RAM映像到程序/數(shù)據(jù)空間。

●?SWWSR=7FFFH,所有程序和數(shù)據(jù)空間都插入7個等待狀態(tài)。

●?BSCR=0FFFFH,設(shè)定外部存儲區(qū)分區(qū)為4?K字,當(dāng)程序和數(shù)據(jù)空間切換時,插入一個等待周期。

(2)檢查,決定是否從主機(jī)接口(HPI)加載。如果沒有鎖存信號,說明不是從HPI加載,否則從HPI到RAM自舉加載。

(3)使I/O選通信號(

)為低電平,從地址為0FFFFH的I/O口讀入自舉程序選擇字(BRS)。BRS的低8位確定了自舉加載的方式,其引導(dǎo)方式和內(nèi)容的對應(yīng)關(guān)系如表8-3所示。表8-3中,x表示無效,SRC表示并行方式的6位頁地址,ADDR表示熱自舉方式的6位頁地址。

2)?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位字。如果這個16位字是08AAH,則Boot程序就知道是外部8位并行Boot方式,否則是其他Boot方式。判斷是8位Boot方式后,Boot程序就進(jìn)入相應(yīng)的子程序。由于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í)行的入口點(diǎn)地址為2000H,程序代碼的長度為400H,用戶代碼存放在片內(nèi)程序區(qū)的首地址為2000H,則Flash的數(shù)據(jù)組織如表8-4所示。表內(nèi)括號中的H表示高8位,L表示低8位。不難看出,如果采用外部并行Boot方式,由于Boot的尋

址區(qū)是在數(shù)據(jù)區(qū),因此最大的地址范圍是8000H~FFFFH,

共32K字。

自舉加載器將Flash(EPROM)中的程序代碼全部傳送到程序存儲器之后,立即分支轉(zhuǎn)移到目的地址,并開始執(zhí)行程序

代碼。

3)熱自舉

熱自舉方式是在RESET信號臨近釋放時,按照用戶定義的地址,改變TMS320C54x的程序執(zhí)行方向。熱自舉方式并不傳送自舉表,而是指示TMS320C54x按照自舉加載器程序讀入的BRS中所規(guī)定的地址起開始執(zhí)行,熱自舉的示意圖如圖8-15所示。

由圖8-15可見,熱自舉時,TMS320C54x程序計數(shù)器PC等于BRS中的7~2位加上低10位(全0)。圖8-15熱自舉

4)從HPI口自舉加載

HPI是一個將主處理器與TMS320C54x連接在一起的8位并行口,主處理器和TMS320C54x通過共享的片內(nèi)存儲器交換信息。從HPI口自舉加載的示意圖如圖8-16所示。圖8-16從HPI口自舉加載如果選擇HPI自舉方式,則應(yīng)當(dāng)將和引腳連接在一起。當(dāng)為低電平時,TMS320C54x的中斷標(biāo)志寄存器(IFR)的相應(yīng)位(bit2)置位。發(fā)出以后,自舉加載程序等待20個機(jī)器周期后讀出IFR的bit2。若此位置位(表示

被識別),自舉加載程序就轉(zhuǎn)移到片內(nèi)HPI

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論