【正文】
(4) 在(1)題的基礎(chǔ)上,新建一個(gè)工程文件,使用‘VC5402的定時(shí)器1產(chǎn)生COS信號(hào),同時(shí)使用定時(shí)器0產(chǎn)生SIN信號(hào)。(2) 重新設(shè)計(jì)和實(shí)現(xiàn)一個(gè)數(shù)字振蕩器,采樣頻率改為20kHz,輸出正信號(hào)毒品率為4kHz。為了驗(yàn)證產(chǎn)生的COS信號(hào),可以同時(shí)生成SIN和COS信號(hào),然后在兩個(gè)圖形窗口中顯示波形。注意觀察生成的正弦波頻率。數(shù)一數(shù)一個(gè)周期的正弦波有多個(gè)電?算算頻率是否是2kHz?同樣用右鍵單擊圖形顯示窗口,顯示信號(hào)頻譜。同樣打開圖形顯示窗口,并將“Start Address”改為128,“Display Data Size”改為128,“DSP Data Type”為“32-bit floating point”。這時(shí)CCS將顯示程序的啟始地址_c_int00. (10)打開C源程序()窗口,在中斷服務(wù)程序(函數(shù)tint())的“con_buf=0。連接,正確生成OUT文件。修改編譯、連接選項(xiàng),加入符號(hào)調(diào)試選項(xiàng),修改生成的OUT文件名。該文件應(yīng)該再CCS安裝目錄中?,F(xiàn)面我們使用C語(yǔ)言完成本實(shí)驗(yàn)。注意觀察生成的正弦波頻率。將“Display Type”項(xiàng)改為“FFT Magnitude”以便顯示信號(hào)頻譜。選擇DebugAnimate,運(yùn)行程序,觀察輸出波形。想想為什么要這樣修改?(6)在匯編源程序的中斷服務(wù)程序(_tint)中的“nop”語(yǔ)句處設(shè)置斷點(diǎn)。這是CCS將顯示程序的起始地址_c_int00.(5)選ViewGraphTime/Frequency…打開圖形顯示設(shè)置窗口。(4)寫成編譯、連接,正確生成OUT文件。例如,選擇Assemble窗口,選擇“Enable Symbolic Debug Information”以便使用匯編代碼級(jí)調(diào)試(你可以在匯編源程序設(shè)置斷點(diǎn)等等)。其中。注意,你可以在添加文件對(duì)話框中選擇顯示不同的文件類型來(lái)加快文件選擇速度。(2)啟動(dòng)CCS,新建工程文件,如文件名為 。實(shí)驗(yàn)分下面幾步完成:(1)根據(jù)確定數(shù)字振蕩器的頻率,確定系數(shù)。 stlma, pmst 。 關(guān)閉所有中斷 1d vector ; 讀出中斷向量(地址vector在中斷向量表程序中定義)and OFF80h, a 。本實(shí)驗(yàn)的初始化程序讀取中斷向量表的起始地址,然后設(shè)置PMST的高9位,以便DSP能正確響應(yīng)中斷,代碼如下:1d 0,dp 。表4-3給出了中斷向量表的各中斷的偏移說(shuō)明。當(dāng)然,如果中斷服務(wù)程序很短(小于或等于4個(gè)字),可以直接放入該向量表。中斷向量表是C54X存放中斷服務(wù)程序的一段內(nèi)存區(qū)域,大小為80H。當(dāng)然要CPU響應(yīng)中斷,ST1寄存器中的INTM還應(yīng)該為0(允許所有的中斷)。 圖4-1 C5402的IMR寄存器其中,HPINT表示HPI接口中斷,INT3INTO為外部引腳產(chǎn)生的中斷,TXINT和TRINT為TDM串口發(fā)送和接受中斷,BXINT0和BRINT0為BSP串口的發(fā)送和接收中斷,TINT0為定時(shí)器0中斷。下面時(shí)本實(shí)驗(yàn)中初始化定時(shí)器得程序片段: stm 10h,TCR :停止定時(shí)器 stm 2499,PDR : 設(shè)置PDR寄存器值為2499,TINT中斷頻率為Foutclk/(2499+1)=100MHz/2500=40KHz stm 20h,TCR :重新裝入TIM和,PSC,然后啟動(dòng)定時(shí)器(3)C54X中斷的使用 在C54X中用戶可以通過中斷屏蔽酒釀起IMR來(lái)決定開放或關(guān)閉一個(gè)中斷請(qǐng)求。因而定時(shí)器中斷得頻率由一下的公式?jīng)Q定: TINT的頻率=其中tc表示CLKOUT的周期。這是CPU發(fā)出TINT中斷,同時(shí)在TOUT引腳輸出一個(gè)脈沖信號(hào),脈沖寬度與CLKOUT一致。所以整個(gè)定時(shí)器得周期寄存器可以有20個(gè)比特(PRD+TDDR).從上面的介紹可以看到定時(shí)器實(shí)際上可以有20個(gè)比特的周期寄存器。TSS=0 表示啟動(dòng)定時(shí)器TSS=1 表示停止定時(shí)器0-3TDDR定時(shí)器擴(kuò)展周期。當(dāng)TRB=1時(shí),CPU將PRD寄存器的值裝入TIM寄存器,將TDDR的值裝入PSC4TSS定時(shí)器停止?fàn)顟B(tài)。當(dāng)PSC減為0后,CPU自動(dòng)將TDDR裝入,然后TIM開始減1。Soft=1 當(dāng)計(jì)數(shù)器被減為0后,停止工作?!甐C5402得另一個(gè)定時(shí)器(定時(shí)器1)的控制寄存器分別為:0 30(TIM1),0 31(PRD1),0 32(TCR1)。下面時(shí)初始化和中斷服務(wù)程序代碼片斷: 初始化y[1]和y[2]:ssbx FRCT :置FRCT =1,準(zhǔn)備進(jìn)行小數(shù)乘法運(yùn)算st #INIT_A,AA :將常數(shù)A裝入變量AAst #INIT_B,BB :將常數(shù)B裝入變量BBst #INIT_C,CC :將常數(shù)C裝入變量CCpshd CC :將變量CC壓入堆棧popd y2 :初始化y2=CCld :裝AA到T寄存器mpy y2,a :y2乘系數(shù)A,結(jié)果放入A寄存器sth a,y1 :將A寄存器得高16位存入變量y1中斷服務(wù)程序片斷l(xiāng)d BB,T :將系數(shù)B 裝入T寄存器mpy y2,a :y2乘系數(shù)B,結(jié)果放入A寄存器ltd y1 :將y1裝入T寄存器,同時(shí)復(fù)制到y(tǒng)2mac AA,a :完成新正弦數(shù)據(jù)的計(jì)算,a寄存器中為 y1*AA+y2*BBsth a,l,y1 :將新數(shù)據(jù)存入y1,因所有系數(shù)都除過2,所以在 保存結(jié)果時(shí)轉(zhuǎn)移一位,恢復(fù)數(shù)據(jù)正常大小sth a,l,y0 :將新正弦數(shù)據(jù)存入y0(2)C54X的定時(shí)器操作 C54X的片內(nèi)定時(shí)器利用CLKOUT時(shí)鐘計(jì)數(shù),用戶使用三個(gè)寄存器(TIM,PRD,TCR)來(lái)控制定時(shí)器,參見表4-1。在本實(shí)驗(yàn)中,主程序在初始化時(shí)先計(jì)算出y[1]和y[2],然后開放定時(shí)器中斷。 根據(jù)上面得說(shuō)明,我們可以開始數(shù)字振蕩器得設(shè)計(jì)。設(shè)初始條件為0,求出上式的反Z變換得: y[k]=Ay[k1]+By[k2]+Cx[k1]這是個(gè)二階差分方程,其單位沖擊響應(yīng)即為sinkwT。2 實(shí)驗(yàn)要求 本實(shí)驗(yàn)利用定時(shí)器產(chǎn)生了一個(gè)2kHz的正弦信號(hào),定時(shí)器被設(shè)置成每25uS產(chǎn)生一次中斷,(等效于采樣速率未40k)利用該中斷,在該中斷服務(wù)程序中用疊代算法計(jì)算出一個(gè)SNT值,病利用CCS的圖形顯示功能查看波形。 本實(shí)驗(yàn)除了學(xué)習(xí)數(shù)字振蕩器的DSP實(shí)現(xiàn)原理外,同時(shí)還學(xué)習(xí)C54X定時(shí)器使用以及中斷服務(wù)程序編寫。通常的方法是講某個(gè)頻率的正弦/余弦值余弦計(jì)算出來(lái)后制成一個(gè)表,DSP工作時(shí)僅作查表運(yùn)算即可。 save low 16 bits of B quot_f quotientfdiv_end: nop 。 if result is negative, then 0 B sub quot_f,B 。 if A0,then jump to label fdiv_end,end div stl B,1,quot_f 。 0 high 16 bits of B bcd fdiv_end,agt 。 repeat SUBC 16 times subc temp2,b 。 load temp1 B (high 16 bits) abs B 。 |B| B stl B,temp2 。 temp1*temp2 A ld temp2,B 。 test DIV (fraction) ld temp1,T 。 init temp1 amp。 save low 16 bits of B quot_i quotientidiv_end: nop 。 if result if negative, then 0 B sub quot_i,B 。 save low 16 bits of B quot_i quotient sth B,remain_i 。 delay jump, run the following two instruction,then 。 repeat SUBC 16 times subc temp2,b 。 load temp1 B (low 16 bits) abs B 。 |B| B stl B,temp2 。 temp1*temp2 A ld temp2,B 。 test DIV (integer) ld temp1,T 。 init temp1 amp。 result in mpy_f nop 。 load temp3 into A (high 16 bits) mpya temp4 。 test MPY (fraction) ssbx FRCT 。 init temp3 amp。 the low 16bit in mpy_i_l nop 。 temp1*temp2 A (result is 32 bit) sth a,mpy_i_h 。 prepare for integer mpy ld temp1,T 。 temp2,18*52=936(0x3a8)。 set breakpoint st VAL1,temp1 st VAL2,temp2 。 (temp316)(temp416) b,ar2++ sth b,sub_result 。 address of temp3 ar2 stm temp4,ar3 。 temp4,(18)18=36(0x0ffdc)。 set breakpoint st VAL6,temp3 st VAL1,temp4 。 a+temp2 a stl a,add_result 。 test ADD ld temp1,a 。 init temp1 amp。 address of 0x08f .text mainstart: ld temp,DP 。 address of 0x08d .bss remain_i,1 。 address of 0x08b .bss mpy_f 。 address of 0x089 .bss mpy_i_h,1 。result register .bss add_result,1 。 address of 0x086 .bss