函数信号发生器.docx
《函数信号发生器.docx》由会员分享,可在线阅读,更多相关《函数信号发生器.docx(17页珍藏版)》请在冰豆网上搜索。
函数信号发生器
课程设计报告
题目函数信号发生器
课程名称DSP应用技术课程设计
院部名称
专业
班级
学生姓名
学号
课程设计地点
课程设计学时
指导教师
金陵科技学院教务处制
实验项目名称:
实验学时:
同组学生姓名:
实验地点:
实验日期:
实验成绩:
批改教师:
批改时间:
一、课程设计的目的和要求
1、设计目的
(1)、掌握信号发生器的设计方法和测试技术。
(2)、了解函数发生器的工作原理和应用,了解其内部组成原理。
(3)、了解信号发生器程序设计的程序流程图。
2、设计要求
通过课程设计,加深对DSP芯片TMS320C54x的结构、工作原理的理解,对DSP相关技术进行运用,掌握设计DSP系统的基本方法。
通过使用汇编语言或者C语言编写具有完整功能的图形处理程序,学会DSP和MATLAB相关工具的连接,在CSS里面输出相关波形和频谱图形。
二、系统功能介绍及总体设计方案
1、系统功能介绍
本课题是基于DSP的函数信号发生器设计与仿真,用汇编语言设计出一个数字波形发生器,能产生正弦波、方波、三角波,并且信号频率可调。
矩形、三角、正弦等信号都是函数型信号,因此在程序设计时,对信号波形的有关参数(如幅度大小)进行设置。
波形信号一个周期内有N个量化值,在DSP存储器中开辟一个缓冲区用来存放N个量化值,当一个周期输出结束后,再从缓冲区起始处重新开始读取信号量化值输出,如此往复,就可以得到连续的信号波形。
若要产生较复杂的波形,只要修改源程序,改变DSP中缓冲区中的N个量化值,而不用重新改装电路。
通过改变信号的采样率,即改变定时器中断频率,就可以改变输出改变信号的频率,因此系统灵活性较好。
2、设计方案
A、使用MATLAB编写程序产生信号波形
B、进行DSP编程
C、查看程序运行后的输出波形并与先前波形进行比较
三、主要内容和步骤
1、概述
在本实验中使用MATLAB模拟产生信号,观察产生的波形。
MATLAB仿真后,进行DSP编程,在DSP中实现函数波形输出,与使用MATLAB编程产生的波形进行比较,观察是否输出正确波形。
2、整体操作步骤
在CCS中,编写相关汇编文件或者C语言文件,加载.out程序。
编译运行,可得到输出的相关波形,修改程序,得到不同类型的输出波形。
3、CCS汇编程序流程图
主程序流程图
子程序流程图
四、详细设计
1.各函数信号产生的算法的实现方法
A、一般来说,产生正弦波的方法由两种:
(1)查表法。
此种方法对于精度要求不是很高的场合。
如果精度要求高,表就很大,相应的存储器容量也就要增大。
(2)泰勒级数展开法。
这是一种更为有效的方法。
与查表法相比,需要的存储单元更少,而且精度高。
一个角度为
的正弦和余弦函数,都可以展开成泰勒级数,取其前五项进行近似为:
(1)
(2)
上式中x为
的弧度值。
本试验采用泰勒级数展开法。
在正弦信号发生器的设计中,先以前面的算法计算
(间隔为
)的sin和cos值,再利用
求出
的sin值(j间隔为
)。
然后,通过复制,获得
的正弦值,重复输出该值就可以得到正弦波。
B、方波产生程序比较简单,定义一个周期的存储空间,在前半个周期中输出幅度1,后半个周期输出-1,重复输出该值就可以得到方波。
C、三角波产生程序中,在前1/4周期内定义一个斜率为k满足k×1/4T,产生前1/4个周期的三角波,然后通过复制得到一个周期的三角波,储存在存储器中,重复输出该值就可以得到三角波。
2、MATLAB仿真的源代码及输出波形
由于三角波和正弦波信号产生的算法都比较简单,这里就不再做仿真验证了,只对正弦波信号产生的算法进行仿真验证。
程序如下:
clearall;
x=0:
pi/360:
pi/4-pi/360;
sinx=x.*(1-x.*x/(2*3).*(1-x.*x/(4*5).*(1-x.*x/(6*7).*(1-x.*x/(8*9)))));
cosx=1-x.*x/2.*(1-x.*x/(3*4).*(1-x.*x/(5*6).*(1-x.*x/7*8)));
cosx=1-x.*x/2.*(1-x.*x/(3*4).*(1-x.*x/(5*6).*(1-x.*x/7*8)));
sinx=2*sinx.*cosx;%产生
波形
sinx2=[sinx,sinx(90:
-1:
1)];%产生
波形
sin=[sinx2,-sinx2];%产生
波形
y=pi/180:
2*pi/360:
2*pi;
plot(y,sin);
得到如下波形:
3、信号发生器的源代码及注释
.title"hanshu.asm";为汇编语言原程序命名
.mmregs;定义MMR
.def_c_int00;定义标号_c_int00
.global
sinx,d_xs,d_sinx,cosx,d_xc,d_cosx,zhengxianbo_out,fangbo_out,sanjiaobo_out
sin_x:
.usect"sin_x",360
STACK:
.usect"STACK",10;为堆栈空间分配16个存储单元
interval.set1
.bsscount,1;为count分配4个存储单元
.bssoutput,1800;为OUTPUT分配1800个单元
主程序:
主要功能是选择将要输出的波形。
通过存放在AR7中的立即数与输出波形的型号相比较,若匹配,则输出相应的波形。
_c_int00:
ST#0,*(count)
STM#STACK+10,SP;设置堆栈指针
STM#2,AR7;选择输出波形的类型
CMPMAR7,#3;#3产生方波
BCrect_sub,TC
CMPMAR7,#2;#2产生三角波
BCtria_sub,TC
CMPMAR7,#1;#1产生正弦信号
BCsin_sub,TC
NOP
end:
Bend;循环等待
调用子函数,从而输出相应的波形:
zhengxianbo_sub:
nop
nop
CALLzhengxianbo_out;调用zhengxianbo_out
BCON;无条件转移
fangbo_sub:
nop
nop
CALLfangbo_out;调用fangbo_out
nop
nop
BCON
sanjiaobo_sub:
nop
nop
CALLsanjiaobo_out;调用sanjiaobo_out
nop
nop
BCON
CON:
STM#sin_x,AR5;AR5指向sin_x
STMinterval,AR0
STM#360,BK;设置缓冲区长度
STM#output,AR2
loop4:
MVDD*AR5+0%,*AR2+;数据存储器内部传送数据
ADDM#1,*(count)
CMPM*(count),3600
NOP
NOP
BCdone,TC;条件分支转移
Bloop4
done:
Bdone
产生方波的函数
rect_out:
k_rtheta.set7FFFh;theta=pi/180(1deg.)
.text
LD#7FFFh,A;A=7FFFFh
STM#sin_x,AR6;将sin_x首地址送入AR6
STM#180,BRC;设置循环次数
RPTBloopr1-1
STLA,*AR6+
loopr1:
STM#180,BRC
RPTBloopr3-1
LD#0h,A;累加器A清零
STLA,*AR6+
loopr3:
RET
产生三角波的函数
实现步骤如下:
第一步:
计算0——90(间隔为1(deg.))的值,存于AR6中;
第二步:
利用*AR6-计算91——180的值;
第三步:
利用NEG取负计算181——270的值;
第四步:
同理计算271——360的值。
sanjiaobo_out:
k_ttheta.set364;theta=1/90(0.5deg.)
.text
ssbxfrct;设置小数运算
ST#0,*(count)
LD#0,A;累加器A清零
LD#-1,A
STM#STACK+10,SP;设置堆栈指针
STMk_ttheta,AR0;设置增量
STM0,AR1;AR0=x=0
STM#sin_x,AR6;sin_x首地址送入AR6
STLA,*AR6+
STM#89,BRC;设置循环次数
RPTBloopt1-1;loopt1-1为循环结束地址
ADDAR0,A;累加器运算,并修改地址
STLA,*AR6+
loopt1:
STM#sin_x+89,AR7;AR6指向sin_x+89单元
STM#89,BRC;设置重复次数
RPTBloopt2-1;loopt2-1为循环地址
LD*AR7-,A
STLA,*AR6+
loopt2:
STM#178,BRC;设置循环次数
STM#sin_x+1,AR7;AR7指向sin_x+1单元
RPTBloopt3-1;loopt3-1为循环结束地址
LD*AR7+,A
NEGA
STLA,*AR6+
loopt3:
STM#sin_x,AR5;AR5指向sin-x单元
STMinterval,AR0
STM#360,BK;设置缓冲区长度
STM#output,AR2
loopt4:
MVDD*AR5+0%,*AR2+;数据存储器内部传送数据
ADDM#1,*(count);存储器加1
CMPM*(count),1800;比较count与立即数
BCdonet,TC;条件分支转移
bloopt4;循环输出,产生波形
donet:
bdonet
RET
正弦波的实现
实现步骤如下:
第一步:
利用sin_start和cos_start子程序,计算0(~45((间隔为0.5()的正弦和余弦值;
第二步:
利用sin(2x)=2sin(x)cos(x)公式,计算0(~90(的正弦值(间隔为1();
第三步:
通过复制,获得0(~359(的正弦值;
第四步:
将0(~359(的正弦值重复从PA口输出,便可得到正弦波。
zhengxianbo_out:
k_stheta.set286;theta=pi/360(0.5deg.)
.text
STMk_stheta,AR0;AR0-->k_stheta
STM0,AR1;AR1=x
STM#sin_x,AR6;AR6指向sin_x
STM#90,BRC;fromsin0---sin90(deg)
RPTBloop1-1
LDMAR1,A;取X值
LD#d_xs,DP;设置页指针
STLA,@d_xs;将x值送入d_xs单元
STLA,@d_xc;将x值送入d_xc单元
CALLsinx;(d_sinx)=sin(x)
CALLcosx;(d_cosx)=cos(x)
LD#d_sinx,DP;切换到正弦指数据区
LD@d_sinx,16,A;A=sin(x)
MPYA@d_cosx;B=sin(x)*cos(x)
STHB,1,*AR6+;AR6-->2*sin(x)*cos(x)
MAR*AR1+0;每次增加0.5
loop1:
STM#sin_x+89,AR7;sin(91)---sin(179)
STM#88,BRC;设置重复次数,计算sin91到sin179
RPTBloop2-1
LD*AR7-,A
STLA,*AR6+
loop2:
STM#179,BRC;sin(180)---sin(359)
STM#sin_x,AR7;AR7指向sin_x单元
RPTBloop3-1
LD*AR7+,A
NEGA;累加器变负
STLA,*AR6+
loop3:
RET
*sin(theta)=x(1-x^2/2*3(1-x^2/4*5(1-x^2/6*7(1-x^2/8*9))))
sinx:
.defd_xs,d_sinx
.data;定义程序空间存放系数
table_s.word01c7h;1/(8*9)
.word030bh;1/(6*7)
.word0666h;1/(4*5)
.word1556h;1/(2*3)
d_coef_s.usect"coef_s",4;定义数据空间存放系数
d_xs.usect"sin_vars",1;定义1个数据空间存放x
d_squr_xs.usect"sin_vars",1;定义1个数据空间存放x2
d_temp_s.usect"sin_vars",1;定义1个暂存单元
d_sinx.usect"sin_vars",1;定义数据空间存放结果
c_1_s.usect"sin_vars",1;定义数据空间存放数值1
.text
SSBXFRCT;设置小数运算
STM#d_coef_s,AR5;设置系数表首地址
RPT#3;下一条指令执行4次
MVPD#table_s,*AR5+;向系数表传送泰勒级数
STM#d_coef_s,AR3;系数表首地址送往AR3
STM#d_xs,AR2;X单元的地址送往AR2
STM#c_1_s,AR4;数值1送往AR4
ST#7FFFh,c_1_s;7fffh==1
SQUR*AR2+,A;求x的平均方值
STA,*AR2;存入X平方值
||LD*AR4,B;B=1
MASR*AR2+,*AR3+,B,A;A=1-x2/72,T=x2
MPYAA;A=T(A=x2(1-x2/72)
STHA,*AR2;AR2-->d_temp_s
MASR*AR2-,*AR3+,B,A;A=1-x2/20(1-x2/42(1-x2/72))
MPYA*AR2+;B=x2(1-x2/20(1-x2/42(1-x2/72)))
STB,*AR2
||LD*AR4,B
MASR*AR2-,*AR3+,B,A;B=1
MPYAd_xs;A=1-x2/6(1-x2/20(1-x2/42(1-x2/72)))
STHB,d_sinx;B=x(1-x2/6(1-x2/20(1-x2/42(1-x2/72)
RET;计算sinx结果存入d_sinx单元
*cos(theta)=1-x^2/2(1-x^2/3*4(1-x^2/5*6(1-x^2/7*8)))
cosx:
.defd_xc,d_cosx
d_coef_c.usect"coef_c",4;为"coef_c"分配4个单元
.data;定义数据段代码
table_c.word0249h;1/(7*8)
.word0444h;1/(5*6)
.word0aabh;1/(3*4)
.word4000h;1/2
d_xc.usect"cos_vars",1;定义1个数据空放x
d_squr_xc.usect"cos_vars",1;定义1个数据空间存放x2
d_temp_c.usect"cos_vars",1;定义1个暂存单元
d_cosx.usect"cos_vars",1;定义数据空间存放结果
c_1_c.usect"cos_vars",1;定义数据空间存放数值1
.text
SSBXFRCT;设置小数运算
STM#d_coef_c,AR5;设置系数表首地址
RPT#3;设置重复操作次数
MVPD#table_c,*AR5+;向系数表传送泰勒系数
STM#d_coef_c,AR3;系数表首地址送AR3
STM#d_xc,AR2;x单元地址送AR2
STM#c_1_c,AR4;数值1地址送AR5
ST#7FFFh,c_1_c;将数值1送c_l_s单元
SQUR*AR2+,A;求x的平方值
STA,*AR2;x2值存入d_squr_xs单元
||LD*AR4,B;B=1
MASR*AR2+,*AR3+,B,A;A=1-x2/72,T=x2
MPYAA;A=T(A=x2(1-x2/72)
STHA,*AR2;(d_temp_s)=x2(1-x2/72)
MASR*AR2-,*AR3+,B,A;A=1-x2/42(1-x2/72)
;T=x2(1-x2/72)
MPYA*AR2+;B=x2(1-x2/42(1-x2/72))
STB,*AR2;(d_temp_s)=x2(1-x2/42(1-x2/72))
||LD*AR4,B
MASR*AR2-,*AR3+,B,A;B=1
SFTAA,-1,A
NEGA
MPYA*AR2+
MAR*AR2+;修改AR2
RETD
ADD*AR4,16,B;AR4内容左移16位存入B中
STHB,*AR2
RET
.end
五、实验过程
1、实验步骤与内容
具体步骤:
在桌面上点击"SetupCCS2"图标,双击进入,会有如下界面选择图中所示的仿真器的型号,完成图中操作后,按"saveandquit"进行下一步。
选择菜单项Project→New。
输入标题shiyunxia,ok,在对话框中右击选择AddFilestoProject,在文件类型框中选择*.asm。
选择hanshu.asm并点击Open。
同理,将hanshu_v.asm、hanshu.cmd文件均加入其中。
其过程见下图所示:
点击工具栏按钮CCS重新编译、汇编和连接工程中的所有文件,有关此过程的信息显示在窗口底部的信息框中。
选择File→LoadProgram,选择刚重新编译过的程序shiyunxia.out(它应该在c:
\ti\myprojects\shiyunxia文件夹中)并点击Open。
点击工具栏按钮RUN在VIEW里选择graph,time-frequency,并在弹出的对话框中修改参数。
2、CCS程序运行后的各种输出结果
若程序如下所示,产生三角波
_c_int00:
ST#0,*(count)
STM#STACK+10,SP;设置堆栈指针
STM#2,AR7;选择输出波形的类型
CMPMAR7,#3;#3产生方波
BCrect_sub,TC
CMPMAR7,#2;#2产生三角波
BCtria_sub,TC
CMPMAR7,#1;#1产生正弦信号
BCsin_sub,TC
NOP
end:
Bend;循环等待
STM#2,AR7语句中将2改成3,产生方波
STM#2,AR7语句中将2改成1,产生正弦波
六、结论与体会
1、实验中遇到的问题
2、实验心得
七、参考文献
[