1基于DSP的定时器实现数字振荡器一、实验目的1.更进一步掌握定时器和中断的使用;2.学会用数字振荡器方法产生正弦/余弦信号;二、实验原理利用定时器及中断产生频率为f正弦信号,定时器被设置成每1/fs产生中断一次(等效于采样速率),在中断服务程序中用迭代算法计算出一个正弦值。用此方法可以很精确地产生某频率的正弦波。设一个传递函数为正弦序列sinT,其Z变换为2111)(BzAzCzzH,其中A=2cosT,B=-1,C=sinT。设初始条件为0,求出其反Z变换得:[][1][2][1]ykAykBykCxk是一个二阶差分方程,其单位冲击响应即为sinkωT,利用单位冲击函数x[k-1]的性质,即仅当k=1时,x[k-1]=1,推导得:[][1][2]ynAynByn在k2以后,y[k]能用y[k-1]和y[k-2]算出,这是一个递归的差分方程。式中2cos2cos(2**/)sATnff,1Bsinsin(2**/)sCTnfffs为采样频率,f为正弦波频率。A为正弦波幅度。可见用数字频率振荡器产生正弦波的实质就是用程序实现上述的递归差分方程。如要产生振荡器的频率为2kHz正弦波,设采样速率为40k,通过定时器设置,每隔25us中断一次,即产生一个y[n]。则递归差分方程系数为:2cos2cos(2**/)sATff2cos(2**2000/40000)2*0.95105652B=-1sinsin(2**/)sin(2**2000/40000)0.30901699sCTff为了便于定点DSP处理,将所有系数除以2,然后用16位定点格式表示为:A=6D4BH,B=C000H,C=214FH,这便是产生2kHz正弦信号的三个系数。主程序初始化时先计算出y[1]和y[2],然后开放定时器中断,以后每次进入定时器中断服务程序时,利用前面计算出的y[1]和y[2]计算出新的y。初始化y[1]和y[2]SSBXFRCT;置FRCT=1,准备进行小数乘法运算ST#0x79BC,AA;将常数装入变量AAST#0xC000H,BB;将常数装入变量BBST#0x13C7H,CC;将常数装入变量CCPSHDCC;将CC压入堆栈POPDY2;初始化Y2=CCLDAA,T;将AA装到T寄存器MPYY2,A;Y2乘以系数A,结果放入A寄存器STHA,Y1;将A寄存器的高16位存入变量Y12;中断服务程序段:LDBB,T;将系数B装入T寄存器MPYY2,A;Y2乘系数B,结果放入A寄存器LTDY1;将Y1装入T寄存器,同时复制到Y2MACAA,A;完成新正弦数据计算,A寄存器;中为Y1*AA+Y2*BBSTHA,1,Y1;将新数据存入Y1,因所有系数都;除过2,在保存结果时转移一位,;恢复数据正常大小STHA,1,Y0;将新正弦数据存入Y0VC5402的片内定时器利用CLKOUT时钟计数,用三个寄存器(TIM、PRD、TCR)来控制定时器。到定时器实际上可以有20个比特的周期寄存器。它对CLKOUT信号计数,先将PSC减1,直到PSC为0,然后用TDDR重新装入PSC,同时将TIM减1,直到TIM减为0。这时CPU发出TINT中断,同时在TOUT引脚输出一个脉冲信号,脉冲宽度为CLKOUT一致。然后用PRD重新装入TIM,重复下去直到系统或定时器复位。因而定时器中断的频率由下面的公式决定:TINT的频率=111PRDTDDRtc,其中tc表示CLKOUT的周期。设置PRD寄存器值为12499,TINT中断频率为40kHz。定时器初始化程序段为:STM#10H,TCR;停止定时器STM#2499H,PRD;设置PRD寄存器值为2499,;TINT中断频率为Foutclk=(2499+1)=100MHz/2500=40kHzSTM#20H,TCR;重新装入TIM和PSC,然后;;启动定时器,在开放中断屏蔽寄存器IMR后,就可以产生频率为2000Hz的正弦波。三、实验内容与步骤1.使用C54x汇编语言实现数字振荡器,并通过CCS提供的显示窗口观察输出信号波形以及频谱。2.根据确定数字振荡器的频率,确定系数。数字振荡器系数的确定在前面已经说明,3.启动CCS,新建工程文件,如文件名为sinewave.pjt。并建立如下文件:汇编源程序exer3.asm.titlefortestINTserviceprogram...(25us).mmregs.global_c_int00,_tint,vectorOFF_INTIMER.set04Ch;vectorofINTtimeratVECTOR+OFF_INTIMERINIT_A.set079bch;A/2=0.9510498INIT_B.set0c000h;B/2=-0.5INIT_C.set013c7h;C/2=0.1545105.bssy0,1.bssy1,1.bssy2,1.bsstemp,1.bssAA,1.bssBB,1.bssCC,13.text_c_int00:ld#0,dpssbxintm;disableallinterrupt!st#1fffh,spld#vector,a;getvectortableaddress!and#0FF80h,aandm#007Fh,pmstorpmst,astlma,pmst;设置IPTRstm#10h,TCR;initTIMERstm#2499,PRD;f=100M/(2499+1)=40kHzstm#20h,TCR;resetTIMERldmIMR,a;readbackIMRor#08h,a;enableTIMERinterruptstlma,IMR;setIMRld#temp,dp;setDPssbxFRCT;prepareforfractionmpyst#INIT_A,AA;initAA,BB,CCst#INIT_B,BB;st#INIT_C,CC;pshdCCpopdy2;inity2,y2=CCldAA,T;T=AAmpyy2,a;y2*AA-astha,y1;y2*AA-y1stm#0h,TCR;enableTIMERnoprsbxintm;enableallint!again:nopbagainnopnopnopnopnopnop;-------------------------------------------------------------;interruptforINT_TIMER!;-------------------------------------------------------------_tint:ld#BB,DPldBB,T;T=BBmpyy2,a;a=y2*BBltdy1;T=y1,y2=y1macAA,a;a=a+y1*AAstha,1,y1;newcosdata-y1stha,1,y0;newcosdata-y0nop;setbreakpointinCCS!!!int1_end:noprete.end4vec_table.asm文件.mmregs.ref_ret.ref_c_int00.ref_tint.globalvector.sect.int_table;--------------------------------------------------------------------;interruptevectortable!;--------------------------------------------------------------------vector:rsb_c_int00nopnopnmib__retnopnopsint17b__retnopnopsint18b__retnopnopsint19b__retnopnopsint20b__ret.word0,0sint21b__ret.word0,0sint22.word01000h.word0,0,0sint23.word0ff80h.word0,0,0sint24.word01000h.word0,0,0sint25.word0ff80h.word0,0,0sint26.word01000h.word0,0,0sint27.word0ff80h.word0,0,0sint28.word01000h.word0,0,0sint29.word0ff80h.word0,0,0sint30.word01000h.word0,0,0int0b__retnopnopint1b__retnopnopint2b__retnop5noptintb_tintnopnopbrint0b__retnopnopbxint0b__retnopnoptrintb__retnopnopdmac1b__retnopnopint3b__retnopnophpintb__retnopnopq26.word0ff80h.word0,0,0q27.word01000h.word0,0,0dmac4b__retnopnopdmac5b__retnopnopq30.word0ff80h.word0,0,0q31.word01000h.word0,0,0;--------------------------------------------------------------------------;endofinterruptevectortable!;-------------------------------------------------------------------------__retrete链接定位sinewave.cmdMEMORY{PAGE1:INT_D:ORIGIN=80h,LENGTH=1F80hPAGE0:EXT_P:ORIGIN=2000h,LENGTH=2000h}SECTIONS{.text:EXT_PPAGE0.int_table:(EXT_PALIGN(128)PAGE(0)).data:INT_DPAGE1}选择Project菜单中的AddFiletoProject选项,将汇编源程序exer3.asm、vec_table.asm和连接定位sinewave.cmd文件依次添加到工程文件中。注意,你可以在添加6文件对话框中选择显示不同的文件类型来加快文件选择速度。你也可以使用鼠标右键单击工程文件名(如sinewave.pjt)并选择AddFiles项来添加需要的文件。其中,exer3.asm包括初始化代码和中断服务程序,而vec_talbe.asm包含中断向量表。4.选择Project菜单中的Options选项,或使用鼠标右键单击工程文件名(如sinewave.pjt)并选择buildoptions项来修改或添加编译、连接中使用的参数。选择Linker窗口,在“OutputFilename”栏中写入输出OUT文件的名字,如sine.out,你还可以设置生成的MAP文件名。5.完成编译、连接,正确生成OUT文件。然后使用File菜单的“LoadProgram”选项,将生成的OUT文件(如sine.out)装入DSP的片内存储器。这时CCS将显示程序的启始地址_c_int00。6.选View→Graph→Time/Frequency…打开图形显示设置窗口。在弹出的对话框中按图8.1设置,图8.1图形属性设置主要修改“StartAddress”为y0(y0为生成的正弦波输出变量);“AcquisitionBufferSize”为1,“DSPDataType”为“16-bitsignedinteger”。想想为什么要这样修改?7.在汇编源程序的中断服务程序(_tint)中的“nop”语句处设置断点。选择Debug→Animate,运行程序,观察输出波形。数一数一个周期的正弦波有多少个点?算算频率是否是2kHz?另