DSP课程设计正余弦信号的产生Word文档下载推荐.docx
《DSP课程设计正余弦信号的产生Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《DSP课程设计正余弦信号的产生Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
利用泰勒级数的展开式,可计算一个角度x的正弦值,并采用子程序的调用方式。
在调用前先在数据存储器d_xs单元中存放x的弧度值,计算结果存放在d_sinx单元中。
实现计算一个角度的正弦值的程序片段如下:
sinx:
.defd_xs,d_sinx
.data
table_s.word01C7H;
C1=1/(8*9)
.word030BH;
C2=1/(6*7)
.word0666H;
C3=1/(4*5)
.word1556H;
C4=1/(2*3)
d_coef_s.usect"
coef_s"
4
d_xs.usect"
sin_vars"
1
d_squr_xs.usect"
d_temp_s.usect"
d_sinx.usect"
d_l_s.usect"
.text
SSBXFRCT
STM#d_coef_s,AR5;
movecoeffstable_s
RPT#3
MVPD#table_s,*AR5+
STM#d_coef_s,AR3
STM#d_xs,AR2
STM#d_l_s,AR4
ST#7FFFH,d_l_s
SQUR*AR2+,A;
A=x^2
STA,*AR2;
(AR2)=x^2
||LD*AR4,B;
B=1
MASR*AR2+,*AR3+,B,A;
A=1-x^2/72,T=x^2
MPYAA;
A=T*A=x^2(1-x^2/72)
STHA,*AR2;
(d_temp)=x^2(1-x^2/72)
MASR*AR2-,*AR3+,B,A
;
A=1-x^2/42(1-x^2/72);
T=x^2(1-x^2/72)
MPYA*AR2+;
B=x^2(1-x^2/42(1-x^2/72))
STB,*AR2
;
(d_temp)=x^2(1-x^2/42(1-x^2/72))
||LD*AR4,B;
MASR*AR2-,*AR3+,B,A
A=1-x^2/20(1-x^2/42(1-x^2/72))
MPYA*AR2+
B=x^2(1-x^2/20(1-x^2/42(1-x^2/72)))
STB,*AR2;
(d_temp)=B
MASR*AR2-,*AR3,B,A
A=1-x^2/6(1-x^2/20(1-x^2/42(1-x^2/72)))
MPYAd_xs;
B=x(1-x^2/6(1-x^2/20(1-x^2/42(1-x^2/72))))
STHB,d_sinx;
sin(theta)
RET
计算一个角度的余弦值
利用余弦函数展开的泰勒级数的前五项计算一个角度的余弦值,可采用子程序的调用方式来实现。
调用前先将x弧度值放在数据存储器d_xc单元中,计算结果存放在d_cosx单元中。
实现计算一个角度的余弦值的程序片段如下:
cosx:
.defd_xc,d_cosx
d_coef_c.usect"
coef_c"
.data
table_c.word0249H;
C1=1/(7*8)
.word0444H;
C2=1/(5*6)
.word0AABH;
C3=1/(3*4)
.word4000H;
C4=1/2
d_xc.usect"
cos_vars"
d_squr_xc.usect"
d_temp_c.usect"
d_cosx.usect"
c_l_c.usect"
STM#d_coef_c,AR5;
movecoeffstable_c
RPT#3
MVPD#table_c,*AR5+
STM#d_coef_c,AR3
STM#d_xc,AR2
STM#c_l_c,AR4
ST#7FFFH,c_l_c
SQUR*AR2+,A;
STA,*AR2;
||LD*AR4,B;
MASR*AR2+,*AR3+,B,A;
A=1-x^2/56,T=x^2
MPYAA;
A=T*A=x^2(1-x^2/56)
STHA,*AR2;
(d_temp)=x^2(1-x^2/56)
MASR*AR2-,*AR3+,B,A;
A=1-x^2/30(1-x^2/56)
T=x^2(1-x^2/56)
B=x^2(1-x^2/30(1-x^2/56))
STB,*AR2
(d_temp)=x^2(1-x^2/30(1-x^2/56))
MASR*AR2-,*AR3+,B,A
A=1-x^2/12(1-x^2/30(1-x^2/56))
SFTAA,-1,A;
-1/2
NEGA
B=-x^2/2(1-x^2/12(1-x^2/30(1-x^2/56)))
MAR*AR2+
RETD
ADD*AR4,16,B;
STHB,*AR2;
cos(theta)
正弦波的实现
利用计算一个角度的正弦值和余弦值程序可实现正弦波。
其实现步骤如下:
第一步:
利用sin_start和cos_start子程序,计算
(间隔为
)的正弦和余弦值;
第二步:
利用sin(2x)=2sin(x)cos(x)公式,计算
的正弦值(间隔为
);
第三步:
通过复制,获得
的正弦值;
第四步:
将
的正弦值重复从PA口输出,便可得到正弦波。
产生正弦波的程序片段如下:
.mmregs
.defstart
.defd_xs,d_sinx,d_xc,d_cosx,sinx,cosx
sin_x:
.usect"
sin_x"
360
STACK:
STACK"
10H
k_theta.set286;
theta=pi/360(0.5deg)
start:
STM#STACK+10H,SP
STMk_theta,AR0
STM0,AR1
STM#sin_x,AR6
STM#90,BRC
RPTBloop1-1
LDMAR1,A
LD#d_xs,DP
STLA,@d_xs
STLA,@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)
MAR*AR1+0
loop1:
STM#sin_x+89,AR7;
sin91(deg.)-sin179(deg.)
STM#88,BRC
RPTBloop2-1
LD*AR7-,A
STLA,*AR6+
loop2:
STM#179,BRC;
sin180(deg.)-sin359(deg.)
STM#sin_x,AR7
RPTBloop3-1
LD*AR7+,A
loop3:
STM#sin_x,AR6;
generatesinwave
STM#1,AR0
STM#360,BK
Bloop3
产生正弦波链接命令文件的程序片段如下:
MEMORY
{
PAGE0:
EPROM:
org=0E000H,len=1000H
VECS:
org=0FF80H,len=0080H
PAGE1:
SPRAM:
org=0060H,len=0020H
DARAM1:
org=0080H,len=0010H
DARAM2:
org=0090H,len=0010H
DARAM3:
org=0200H,len=0200H
}
SECTIONS
.text:
>
EPROMPAGE0
.data:
STACK:
SPRAMPAGE1
sin_vars:
DARAM1PAGE1
coef_s:
cos_vars:
DARAM2PAGE1
coef_c:
sin_x:
align(512){}>
DARAM3PAGE1
.vectors:
VECSPAGE0
在实际应用中,正弦波是通过D/A口输出的。
选择每个正弦周期中的样点数、改变每个样点之间的延迟,就能够产生不同频率的波形,也可以利用软件改变波形的幅度以及起始相位。
第二章总体方案设计
2.1.总体实现方案
我们知道一个角度为x的正弦和余弦函数,都可以展开为泰勒级数,且其前五项可以看为:
本程序的编程思想是这样的,正弦波的波形可以看为由无数点组成,这些点与
轴的每一个角度值相对应,那么我们可以利用DSP处理器处理大量重复计算的优势来计算,
轴每一点对应的y轴的值(在x轴取360个点来进行逼近),由于程序的编制采用小数形式,其弧度大于1的正弦值得不到,这就对正弦波的产生造成了障碍。
可由于正弦波的特殊的对称形式给程序的编制找到了出口。
的弧度为0.7854<
1,即
之间的任意正弦、余弦值可以利用汇编程序得到N又可以利用公式:
得到
之间的正弦值。
而
之间的正弦曲线与
之间的正弦曲线通过
这条轴左右对称,那么就可以得到
的正弦值,而
的正弦曲线的相反数通过
这条轴与
左右对称。
这样
的正弦值也得到了。
一个周期内完整的正弦波就得到了。
正弦波产生的流程图如下:
2.2.具体实现步骤
本课程设计需要使用C54X汇编语言产生正弦波,并通过CCS的图形显示工具观察波形。
设计分以下几步完成:
启动CCS,操作如下:
1.建立新的工程文件:
点击Project→New,保存文件名为sinx.pjt。
2.建立汇编源程序:
点击File→New→SourceFile菜单命令,打开一个空白文档,将汇编源程序逐条输入后,单击Flie→Save菜单命令,文件类型保存为(*.asm),单击“保存”按钮,以上汇编程序被存盘。
3.建立连接命令文件:
点击File→New→SourceFile菜单命令,打开一个空白文档,将链接命令文件逐条输入后,单击Flie→Save菜单命令,文件类型保存为(*.cmd),单击“保存”按钮,以上链接命令文件被存盘。
4.选择Project菜单中的AddFiletoProject选项,将汇编源程序sin.asm和链接定位sin.cmd文件依次添加到工程文件中。
5.选择Project菜单中的Options选项,并选择buildoptions项来修改或添加编译、连接中使用的参数。
选择Linker窗口,在“OutputFilename”栏中写入输出OUT文件的名字,如sin.out,还可以设置生成的map文件名。
6.完成汇编,编译和链接,正确产生.out文件:
点击Project菜单中的Rebuildall,请注意在监视窗口显示的汇编,编译和链接的相关信息。
如果没有错误,将产生sin.out文件;
如果有错,在监视窗口以红色字体显示出错误行,用鼠标双击该行,光标跳将至源程序相应的出错行。
修改错误后,重新汇编链接。
7.在Project选项中打开sin.pjt文件,使用Build选项完成编译、连接。
8.使用File菜单中的LoadProgram将OUT文件装入。
然后选择Debug→Run,程序执行过程中可以使用Debug→Halt暂停程序的执行。
9.选择View->
Graph->
Time/Frequency菜单打开一个图形显示窗口。
将“StartAddress”项改为地址sin_x,将“AcquisitionBufferSize”项设置为360,将“DisplayDataSize”项设置为360,将“DSPDataType”改为“16-bitsignedinteger”。
即将GraphPropertyDialog对话框改为见下图:
这样,将在图形显示窗口中显示从sin_x(首地址)开始的360个点的16位有符号整数的图形。
第三章源程序
主要参数
1.sin(theta)=x(1-x^2/2*3(1-x^2/4*5(1-x^2/6*7(1-x^2/8*9))))
2.cos(theta)=1-x^2/2*3(1-x^2/4*5(1-x^2/6*7(1-x^2/8*9)))
3.sin(2*theta)=2*sin(theta)*cos(theta)
源程序
1.产生正弦波程序清单sin.asm:
.title"
sin.asm"
;
为汇编文件取名为“sin.asm”
.mmregs;
定义存储器映像寄存器
.def_c_int00
.refsinx,d_xs,d_sinx,cosx,d_xc,d_cosx;
定义标号
360;
为"
保留360个存储空间
10;
为堆栈保留10个存储空间
k_theta.set286;
PA0.set0
_c_int00
.text;
定义文本程序代码段
STM#STACK+10,SP;
设置堆栈指针
STMk_theta,AR0;
AR0-->
K_theta(increment)
STM0,AR1;
(AR1)=X(rad)
STM#sin_x,AR6;
AR6-->
sin(x)
STM#90,BRC;
formsin0(deg.)—sin90(deg)
;
重复执行块语句(下条语句开始至loop1-1)91次
RPTBloop1-1
LD#d_xs,DP;
DPd_xs
STLA,@d_xs;
(A)低16位→d_xs
STLA,@d_xc;
(A)低16位→d_xc
CALLsinx;
调用sinx程序
CALLcosx;
调用conx程序
LD#d_sinx,DP;
DPd_sinx
LD@d_sinx,16,A;
MPYA@d_cosx;
B=sin(x)*cos(x)
STHB,1,*AR6+;
2*sin(x)*cos(x)
MAR*AR1+0;
修改辅助寄存器AR1
STM#sin_x+89,AR7;
sin91(deg.)--sin179(deg.)
STM#88,BRC;
重复执行下条指令至loop2-1
RPTBloop2-1;
处90次
LD*AR7-,A;
((AR7))→A,然后AR7减去1
STLA,*AR6+;
(A)低16位→AR6
STM#179,BRC;
sin180(deg.)--sin359(deg.)
(BRC)=179,重复执行180次
STM#sin_x,AR7;
AR7指向sin_x首地址
RPTBloop3-1;
LD*AR7+,A;
((AR7))→A,然后AR7加1
NEGA;
累加器变负
A低16位→AR6
generatesinwaveAR6指向sin_x
STM#1,AR0;
AR01
STM#360,BK;
BK360
loop4:
PORTW*AR6+0%,PA0;
PA0=*AR6+0%,向PA0输出数据
Bloop4;
.defd_xs,d_sinx;
定义标号d_xs,d_sinx
.data;
定义数据代码段
table_s.word01c7h;
c1=1/(8*9)
.word030bh;
c1=1/(6*7)
.word0666h;
c1=1/(4*5)
.word1556h;
c1=1/(2*3)
4;
保留4个存储空间
1;
为d_xs中sin_vars保留1个存储空间
为d_squr_xs中sin_vars保留1个存储空间
为d_temp_s中sin_vars保留1个存储空间
为d_sinx中sin_vars保留1个存储空间
c_l_s.usect"
定义代码开始段
SSBXFRCT;
设置FRCT=1以解决冗余符号位
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_l_s首地址
ST#7FFFh,c_l_s;
7FFFh→c_l_s
SQUR*AR2+,A;
AR2指向累加器A中的数值求其平方
STA,*AR2;
(A)左移16位→AR2
||LD*AR4,B;
(AR4)左移16位→B
MASR*AR2+,*AR3+,B,A;
从累加器A中减去(AR2)*(AR3)
MPYAA;
操作数与累加器A中高位相乘
STHA,*AR2;
(A)高16位→AR2
MASR*AR2-,*AR3+,B,A;
MPYA*AR2+;
AR2指向的数与累加器A的高16位相乘
STB,*AR2;
(B)左移16位→AR2
与累加器A中高16位相乘
(AR4)左移16位→BMASR*AR2-,*AR3+,B,A;
MPYAd_xs;
d_xs指向的操作数与累加器A中高16位相乘
STHB,d_sinx;
(B)高16位→d_sinx
RET;
返回
.defd_xc,d_cosx;
定义标号d_xc,d_cosx
为coef_c保留4个存储空间
table_c.word024