DSP课程设计正弦波信号发生器报告.docx
(BRC) =179,重复执行180次STM#sin_x, AR7;AR7指向sinx首地址RPTBloop3-l;LD*AR7+, A;(AR7) -A,然后AR7加 1NEGA;累加器变负STLA,*AR6+;A 低 16 位 f AR6Ioop3:STM#sin_x, AR6;generate sin wave AR6指向sin xSTM#1, ARO;ARG 01STM#360,BK;BKG360loop4:PORTW*AR6+0%, PAO ;PAO=*AR6+0%,向PAO输出数据Bloop4;sinx:,defd_xs, d_sinx;定义标号d_xs, d sinx.data定义数据代码段table_s.word01c7h;cl=l/(8*9).word030bh;cl=l/(6*7). word0666h;cl=l/(4*5).word1556h;cl = 1/(2*3)d_coef_s.usectcoef_s, 4;为 coef_s 保留4个存储空间d_xs.usect rsin_vars , 1;为d_xs中sin_vars保留1个存储空间d_squr_xs, usectsin_vars ,I;为d_squr_xs 中 s in_vars保留 1 个存储空间d_temp_s.usectsin_vars , 1;为d_temp_s中sin_vars保留1个存储空间d_sinx.usect rsin_vars , 1;为d_sinx中sin_vars保留1个存储空间c_l_s, usect1sm vars , i;为d_xs中sin vars保留1个存储空间.text;定义代码开始段SSBXFRCT;设置FRCTE以解决冗余符号位STM#d_coef_s, AR5;AR5指向d_coef_s首地址RPT#3;重复下条,旨令4次MVPD#table_s, *AR5+;table_s中的数复制到AR5指向的单元STM#d_coef_s, AR3;AR3指向d_coef_s首地址STM#d_xs, AR2;AR2指向d_xs首地址STM#c_l_s, AR4;AR4指向c_s首地址ST#7FFFh, c_l_s;7FFFh fc l_sSQUR*AR2+, A:AR2指向累加器A中的数值求其平方STA, *AR2;(A)左移 16位一AR2LD*AR4, B;(AR4)左移 16位一BMASR*AR2+, *AR3+, B, A;从累加器A中减去(AR2) * (AR3)MPYAA;操作数与累加器A中高位相乘STHA, *AR2;(A)高 16位一AR2MASR*AR2-, *AR3+, B, A;从累加器A中减去(AR2) * (AR3)MPYA*AR2+;AR2指向的数与累力口器A的高16位相乘STB, *AR2;(B)左移 16位一AR21 |LD*AR4, B;(AR4)左移 16位一BMASR*AR2-, *AR3+, B, A;从累加器A中减去(AR2) * (AR3)MPYA*AR2+;与累加器A中高16位相乘STB, *AR2;(B)左移 16位f AR21 |LD*AR4, B;(AR4)左移 16位一BMASR*AR2-, *AR3+, B, A;从累加器A中减去(AR2) * (AR3)MPYAd_xs;d_xs指向的操作数与累加器A中高16位相乘STHB, d sinx;(B)高 16位f d sinxRET;返回cosx:.defd_xc, d_cosx; 定义标号d_xc, d_cosxd_coef_c . usectcoef_c,4;为coef_c庶留4个存储空间 data;定义数据代码段table_c . word0249h;cl=l/(7*8), word0444h;c2=l/ (6*5).wordOaabh;c3=l/(3*4) word4000h;c4=l/2d xc.usectcos_vars , 1;为d_xc中cos_vars保存1个存储单元d_squr_xc .usectcos_vars , i;为d_squr_xc 中cos_vars保存 1 个存储单元"一d_temp_c .usectcos_vars,1;为(113叫_(3中(30$_丫1'$保存1个存储单元d cosx .usectcos_vars , 1;为d cosx中cos_vars保存1个存储单元c_l_c.usectcos_vars,1;为c_l_c中cos_vars保存1个存储单元.text;定义文本代码段SSBXFRCT;FRCT=1以清除冗余符号位STM#d_coef_c, AR5;AR5指向d_coef_c首地址RPT#3;重复下条指令4次MVPD#table_c, *AR5+;把table_c中的数复制到中AR5STM#d_coef_c, AR3;AR3指向d_coef_c首地址STM#d_xc,AR2;AR2指向d_xc首地址STM#c_l_c, AR4;AR4指向c_l_c首地址ST#7FFFh, c_l_c;7FFFhf c_l_cSQUR*AR2+, A;求X的平方存放在累加器A中STA, *AR2;(A)左移 16位一AR2|LD*AR4, B;(AR4)左移 16位一BMASR*AR2+, *AR3+, B, A;A=l-x2/56, T=x2MPYAA;A=T*A=x-2(l-x-2/56)STHA, *AR2;(d_temp)= x 2(l-x2/56)MASR*AR2-, *AR3+, B, A;A=1-x2/30(l-x-2/56),T= x2(l-x2/56)MPYA*AR2+;B=x2(l-x2/30(l-x2/56)STB, *AR2;(d_temp)=x'2 (12/30 (12/56)1 |LD*AR4, B;B=1MASR*AR2-, *AR3+, B, A;A= 12/12(12/30 (12/56)SFTAA,-1,A;T/2NEGA9MPYA*AR2+;B=l-x2/2(l-x2/12(l-x2/30;(1-x-2/56)MAR*AR2+9RETD.ADD*AR4, 16, B;B=l2/2d2/12(12/30;(12/56)STHB, *AR2;cos (theta)RET,end.92. *.cmd文件描述输入文件和输出文件,说明系统中有哪些可用存储器、程序段、堆栈及复位向量和中断向量等安排在什么地方。其中MEMORY段就是用来规 定目标存储器的模型,通过这条指令,可以定义系统中所包含的各种形式的存储 器,以及它们占据的地址范围;SECTIONS段说明如何将输入段组合成输出段以 及在可执行文件中定义输出段、规定输出段在存储器中的位置等。正弦波程序链 接命令文件sin. cmd:MEMORYPAGE0:PAGEEPROM:VECS:org = OEOOOh, org = 0FF80h,len = lOOOh len = 0080hSPRAM:org = 0060h,len = 0020hDARAM1:org = 0080h,len = OOlOhDARAM2:org = 0090h,len = OOlOhDARAM3:org = 0200h,len = 0200h1:.text:>EPROMPAGE.data:>EPROMPAGESTACK:>SPRAMPAGEsin vars:>DARAM1PAGE0011SECTIONS文本代码段其实地址为OEOOOh,长度为1000h;数据代码段其实地址为ODOOOh;堆栈起始地址为0060h,长度为0020h;标号为sin_vars段的起始地址为0080;长度为0010hcoef_scos_varscoef c:>DARAM1:>DARAM2:>DARAM2PAGE 1 ;标号为coef_s段的起始地址为0070h;长度为OOlOhPAGE 1 ;标号为cos_vars段的起始地址为0090h;长度为OOlOhPAGE 1 ;标号为coef_c段的起始地址为0080h;长度为0020hsin_x : align(512) > DARAM3 PAGE 1.vectors :>VECS PAGE 03.复位向量文件sin_v. asm: title.ref, sect . sin_v. asm_c_int00 / , vectorsB_c_int00.end设计仿真结果及分析/C54x Siaolator (T ex as Instru>ents)/CPV - C54X (Simulator) - Code Composer Studio - GraphicalO File Edit View Project Debug GEL Option Profile Tools DSP/BIOS Window Help.厕 X|百百尉电亳|T|解 蜀喻筑快编I昌用 至够I靛ri理| shiyan. pj t |Debug* Files王 口 GEL files 日ProjectsB .弟)shiyan. pj t (DebiI Dependent Proje LJ Documents 口 DSP/BIOS Config !_) Generated Files1 Include"I Libraries日Source 囱 sin. asm 国 s i n_v. asm5“图 sin. cmdDJ3 J HALTEDZ)手囱骷后| ®曲玛在CCS集成环境中实现正弦波能够起到防止干扰的作用,同时也大大地减小 了波形的线性失真。同时我们也能从中看出CCS能够精确地对各个角度进行计算 得出相应的正弦值,幅度和频率易于调节,波形也较为稳定,抗干扰能力较强。 最重要的是这种设计方案简单可行,新颖实用,具有很高的实践和推广价值。 分析:通过不断的发现错误、改正错误和调试,最终得到了所希望的图象,即正弦 波信号。设计总结在本次课程设计过程中我遇到一些课堂中从未有过的问题,通过网络查找和同学交流,大大促进了实训进程。并在过程中进一步提高自身的创作、创新水平, 扎实基础,扩展所学。课设过程中经常遇到问题,通过自己在网上查找资料和在老师的帮助下,一 步一步地解决了问题,最终解决了问题得到了结果,使我独立解决问题的能力得 到了很大的提高。并且此次课程设计,基于课程理论知识和网上资料,使我对数 字信号处理课程有了更深一步的了解和掌握,对利用CCS软件编程的数字信号 处理方法有了进一步的了解。在理论课的基础上进行实验实习,是对本门课程的 深入学习和掌握,在以后的工作学习中,数字信号的处理都是采用计算机仿真的 方很大的帮助。虽然DSP原理及应用这门课程的课时很短,但是通过本次课 程设计使我对这门课程有了更深的了解,同时也学会了 C54x DSP芯片的一些简 单的编程和应用。作为通信工程专业的学生,我相信这样一个课程设计对我们的 发展有着极大的帮助!设计题目正弦波信号发生器设计目的学会使用CCS (Code Composer Studio)集成开发环境软件,在此集成开发环 境下完成工程项目创建,程序编写,编译,链接,调试以及数据的分析。同时完 成一个正弦波信号发生器的程序的编写,并在集成开发环境下进行模拟运行,观 察结果。设计内容编写一个产生正弦波信号的程序,在CCS软件下进行模拟运行,观察输出 结果。设计原理正弦波信号发生器已被广泛地应用于通信、仪器仪表和工业控制等领域的信 号处理系统中。通常有两种方法可以产生正弦波,分别为查表法和泰勒级数展开 法。查表法是通过查表的方式来实现正弦波,主要用于对精度要求不很高的场合。 泰勒级数展开法是根据泰勒展开式进行计算来实现正弦信号,它能精确地计算出 一个角度的正弦和余弦值,且只需要较小的存储空间。本次课程设计只要使用泰 勒级数展开法来实现正弦波信号。1 .产生正弦波的算法在高等数学中,正弦函数和余弦函数可以展开成泰勒级数,其表达式为sin(x) = x-3!5!79XX17!9!cos(x) = 1一X2X412!4!68X X 16!8!若要计算一个角度x的正弦和余弦值,可取泰勒级数的前5项进行近似计算。sin(x)=%一3!5!7!9!79+=x 1-231-工 14x5 X21- 6x7x2X4X6X8COS(X)= 1H12!4!6!8!x21 lb1 一六由上述两个式子可以推导出递推公式,即sin(nx)=2cos(x)sin(n-l)x-sin(n-2)xcos(nx)=2cos(x)sin(n-l)x-cos(n-2)x由递推公式可以看出,在计算正弦和余弦值时,不仅需要已知cos(x),而且 还需要 sin(n-l)x> sin(n-2)x和 cos(n-2)xo2 .正弦波的实现计算一个角度的正弦值利用泰勒级数的展开式,可计算一个角度x的正弦值,并采用子程序的调用方式。在意用前先在数据存储器d_xs单元中存放X的弧度值,计算结果存放在 dsinx单元中。实现计算一个角度的正弦值的程序片段如下:sinx:.def d_xs,d_sinx .datatable_s.word01C7H.word030BH.word0666H.word1556Hd_coef_s.usectncoef s”,4d_xs.usectHsin_varsHJd_squr_xs.usectHsin_varsld_temp_s.usect"sin varsn,ld_sinx.usectt f nsin vars ,d_l_s.usecttf Ifsin vars ,.textSSBXFRCT;Cl=l/(8*9) ;C2=l/(6*7) ;C3=l/(4*5) ;C4=l/(2*3)STM #d coef s,AR5RPT #3;move coeffs table_s;A=xA2;(AR2)=xA2;B=1;A=l-xA2/72,T=xA2;A=T*A=xa2(1-xa2/72);(d_temp)=xA2( 1 -xA2/72);A=1 -xA2/42(l -xA2/72);T=xA2(l -xA2/72) ;B=xA2(l-xA2/42(l-xA2/72);(d_temp)=xA2(l -x 八 2/42( 1 -x 八 2/72);B=1;A= 1 -xA2/20(l x 八2/42( 1 x 八2/72)MVPD #table_s,*AR5+STM #d_coeLs,AR3STM #d_xs,AR2STM #d_l_s,AR4ST #7FFFH,d 1 sSQUR *AR2+,AST A,*AR2|LD *AR4,BMASR *AR2+,*AR3+,B,AMPYA ASTH A,*AR2MASR *AR2-,*AR3+,B,AMPYA *AR2+ST B,*AR2|LD *AR4,BMASR *AR2-,*AR3+,B,AMPYA *AR2+;B=xA2( 1 -xA2/20( 1 -xA2/42( 1 -xA2/72)ST B,*AR2;(d_temp)=B|LD *AR4,B;B=1MASR *AR2-,*AR3,B,A;A=1 -x 八 2/6( 1 -x 八 2/20( 1 -x 八 2/42( 1 -x 八 2/72)MPYA d_xs;B=x( 1 -x 八 2/6( 1 -x 八 2/20( 1 -x 八 2/42( 1 -x2/72)STH B,d_sinx;sin(theta)RET计算一个角度的余弦值利用余弦函数展开的泰勒级数的前五项计算一个角度的余弦值,可采用子程 序的调用方式来实理。调用前先将X弧度值放在数据存储器d_xc单元中,计算结 果存放在d_cosx单元中。实现计算一个角度的余弦值的程序片段如下:.defd_xc,d_cosxd_coeCc.usectHcoef_cH,4.datatable_c.word0249H.word0444H.wordOAABH.word4000Hd_xc.usect"cos varsH,ld_squr_xc.usect"cos varsn,ld_temp_c.usect"cos varsn,ld_cosx.usectncos varsH,lc_l_c.usectncos_varsn,l.textSSBXFRCTSTM#d coef c,AR5RPT#3COSX:;Cl=l/(7*8) ;C2=l/(5*6) ;C3=l/(3*4) ;C4=l/2;move coeffs table_cMVPD #table_c,*AR5+STM #d_coeLc,AR3STM #d xc,AR2STM #c 1 c,AR4ST #7FFFH,c_cSQUR *AR2+,AST A,*AR2|LD *AR4,BMASR *AR2+,*AR3+,B,AMPYA ASTH A,*AR2MASR *AR2-,*AR3+,B,AMPYA *AR2+ST B,*AR2|LD *AR4,BMASR *AR2-,*AR3+,B,A;A=xA2;(AR2)=xA2;B=1;A=l-xA2/56,T=xA2;A=T*A=x八2 (1-x八2/56);(d_temp)=xA2(l -xA2/56);A= 1-x 八 2/30( 1-x 八 2/56);T=xA2(l-xA2/56);B=xA2( 1 -xA2/30( 1 -xA2/56);(d_temp)二x 八 2( 1 -x 八 2/30( 1 -x 八 2/56);B=1SFTA A,-,ANEG AMPYA *AR2+MAR *AR2+;A= 1 -x 八 2/12( 1 -x八2/30( 1 -x八2/56) ;-1/2;B=-xA2/2(l-xA2/l 2(l-xA2/30(l -x 八 2/56)RETDADD *AR4/6,BSTH B,*AR2RET正弦波的实现;B=-xA2/2(l-xA2/l 2(l-xA2/30(l-xA2/56) ;cos(theta)利用计算一个角度的正弦值和余弦值程序可实现正弦波。其实现步骤如下:第一步:利用sin_start和cos_start子程序,计算0。45。(间隔为0.5°)的正 弦和余弦值;第二步:利用sin(2x)=2sin(x)cos(x)公式,计算0。90。的正弦值(间隔为1。);第三步:通过复制,获得0°359°的正弦值;第四步:将0。359。的正弦值重复从PA口输出,便可得到正弦波。产生正弦波的程序片段如下:.mmregs.def start.def d_xs,d_sinx,d_xc,d_cosx,sinx,cosxsin_x:.usectSTACK:.usectk_theta.setstart:”sin_x”,36。“STACK”, 10H286;theta=pi/360(0.5deg).textloop 1:STM #STACK+10H,SPSTM k_theta,AROSTM O,AR1STM #sin_x,AR6STM #90,BRCRPTB loopl-1LDM ARI, ALD #d xs,DPSTL A,d_xsSTL A,d_xcCALL sinxCALL cosxLD #d sinx,DPLD d_sinx,16,AMPYA d_cosxSTH B,*AR6+MAR * AR 1+0STM #sin x+89, AR7STM #88,BRC;d_sinx=sin(x);d_cosx=cos(x);A=sin(x);B=sin(x)*cos(x) ;AR62*sin(x);sin9 l(deg.)-sin 179(deg.)Ioop2:loop3:RPTB loop2-lLD *AR7-,A STL A,*AR6+ STM#179,BRCSTM #sin x,AR7 RPTB loop3-l LD *AR7+,A NEG A STL A,*AR6+ STM #sin x,AR6 STM #1,ARO STM #360,BK B loop3;sin 180(deg.)-sin359(deg.)generate sin wave产生正弦波链接命令文件的程序片段如下:MEMORYPAGE 0:EPROM: org=0E000H, len= 1000HVECS:org=0FF80H, len=0080HPAGE 1:SPRAM:DARAM1:DARAM2:DARAM3:)SECTIONSorg=0060H, org=0080H, org=0090H, org=0200H,len=0020Hlen=0010Hlen=0010Hlen=0200H.text:>.data:>STACK :> sin_vars :> coefLs :> cos_vars :> coefLc :> sin_x : .vectors :>EPROM EPROM SPRAM DAR AMI DAR AMIDARAM2 DARAM2 align(512) VECSPAGEOPAGEOPAGE 1PAGE 1PAGE 1PAGE 1PAGE 1 > DARAM3PAGEOPAGE 1)在实际应用中,正弦波是通过D/A 输出的。选择每个正弦周期中的样点 数、改变每个样点之间的延迟,就能够产生不同频率的波形,也可以利用软件改 变波形的幅度以及起始相位。总体方案设计1 .总体实现方案我们知道一个角度为x的正弦和余弦函数,都可以展开为泰勒级数,且其前五项可以看为:3579 /、 X X X Xsin(x) = x113!5!7!9!x2 x4cos(x) = 1+ 2!4!X6 X816!8!1- 2%22x3(X11- 4x51 一目(x21-工8x9(-A1-I 7x8;本程序的编程思想是这样的,正弦波的波形可以看为由无数点组成,这些点 与x轴的每一个角度值相对应,那么我们可以利用DSP处理器处理大量重复计算 的优势来计算,x轴每一点对应的y轴的值(在x轴取360个点来进行逼近),由 于程序的编制采用小数形式,其弧度大于1的正弦值得不到,这就对正弦波的产 生造成了障碍。可由于正弦波的特殊的对称形式给程序的编制找到了出口。sin(%)的弧度为0.7854<1,即。% 之间的任意正弦、余弦值可以利用汇编程序得到N乂可以利用公式:sin2i = 2sinicos。得到。% 之间的正弦值。而 0 %之间的正弦曲线与%之间的正弦曲线通过 = %这条轴左右对称, 那么就可以得到%万的正弦值,而0的正弦曲线的相反数通过了 = %这条 轴与万2万左右对称。这样万2万的正弦值也得到了。一个周期内完整的正弦 波就得到了。正弦波产生的流程图如下:2 .具体实现步骤本课程设计需要使用C54X汇编语言产生正弦波,并通过CCS的图形显示 工具观察波形。设计分以下几步完成:启动CCS,操作如下:1 .建立新的工程文件:点击Projectf New,保存文件名为sinx. pjt。2 .建立汇编源程序:点击File-New-Source File菜单命令,打开一个空白文 档,将汇编源程序逐条输入后,单击Flie-Save菜单命令,文件类型保存为 (*.asm),单击“保存”按钮,以上汇编程序被存盘。3 .建立连接命令文件:点击File-New-Source File菜单命令,打开一个空白 文档,将链接命令文件逐条输入后,单击Flie-Save菜单命令,文件类型保存 为(礼cmd),单击“保存”按钮,以上链接命令文件被存盘。4 .选择Project菜单中的Add File to Project选项,将汇编源程序sin.asm和链 接定位sin.cmd文件依次添加到工程文件中。5 .选择Project菜单中的Options选项,并选择build options项来修改或添加 编译、连接中使用的参数。选择Linker窗口,在“Output Filename”栏中写入输出 OUT文件的名字,如sin.out,还可以设置生成的map文件名。6 .完成汇编,编译和链接,正确产生.out文件:点击Project菜单中的Rebuild all,请注意在监视窗口显示的汇编,编译和链接的相关信息。如果没有错误, 将产生sin. out文件;如果有错,在监视窗口以红色字体显示出错误行,用鼠标 双击该行,光标跳将至源程序相应的出错行。修改错误后,重新汇编链接。7 .在Project选项中打开sin.pjt文件,使用Build选项完成编译、连接。8 .使用File菜单中的Load Program将OUT文件装入。然后选择Debugs Run,程序执行过程中可以使用Debug -Halt暂停程序的执行:9 .选择View-Graph-> Time/Frequency菜单打开一个图形显示窗口。将"Start Address”项改为地址 sin_x,将 “Acquisition Buffer Size”项设置为 360,将“Display Data Size”项设置为 360,将“DSP Data Type”改为“16-bit signed integer”。即将Graph Property Dialog对话框改为见下图:这样,将在图形显示窗口中显示从sin_x (首地址)开始的360个点的16位有符号整数的图形。主要参数1. sin(theta) =x(1-x 2/2*3(l-x 2/4*5(1-x 2/6*7 (1-x 2/8*9)2. cos(theta)=l-x 2/2*3(1-x 2/4*5(1-x 2/6*7(l-x-2/8*9)3. sin (2*theta) =2*sin (theta) Mos (theta)源程序1.产生正弦波程序清单sin. asm:.title . sin. asm;为汇编文件取名为“sin. asm” mmregs定义存储器映像寄存器.defcintOO.refsinx, d_xs, d_sinx, cosx, d_xc, d_cosx; 定义标号sin_x:.usectsin_x, 360;为sin_x保留360个存储空间STACK:.usect"STACK", 10;为堆栈速留10个存储空间k_theta.set286;theta=pi/360(0. 5deg)PAO.set0_c_int00.text;定义文本程序代码段STM#STACK+10, SP;设置堆栈指针STMk_theta, ARO;ARO->K_theta(increment)STM0, ARI;(ARI) =X (rad)STM#sin_x, AR6;AR6- - >sin(x)STM#90, BRC;form sinO (deg.) sin90 (deg);重复执行块语句(下条语句开始至loopl-1 ) 91次RPTBloopl-1LDMARI, ALD#d_xs, DP;DPdxsSTLA, d_xs;(A)低 16 位 f d_xsSTLA, d_xc;(A)低 16 位 f d_xcCALLsinx;调用sinx程序CALLcosx;调用conx程序LD#d_sinx, DP;DP<- d_sinxLDd_sinx, 16, A;A=sin(x)MPYAd_cosx;B= sin (x) Mos (x)STHBJ*AR6+;AR6- - >2*sin(x)*cos(x)MAR*AR1+0;修改辅助寄存器ARIloopl:STM#sin_x+89, AR7;sin91(deg.)- -sinl79 (deg.)STM#88, BRC;重复执行下条指令至loop2TRPTBloop2-l;处90次LD*AR7-, A;(AR7) -A,然后AR7减去 1STLA,*AR6+;(A)低 16位一AR6loop2:STM#179,BRC;sinl80 (deg. )- -sin359 (deg.)