基于DSP的正弦信号发生器的设计

发布时间:2011-07-05 20:48:18

基于DSP的正弦信号发生器的设计

1、绪论

1.1 课题背景

数字信号处理(Digital Signal Processing,简称DSP)是一门涉及许多学科而又广泛应用于许多领域的新兴学科。20世纪60年代以来,随着计算机和信息技术的飞速发展,数字信号处理技术应运而生并得到迅速的发展。数字信号处理是一种通过使用数学技巧执行转换或提取信息,来处理现实信号的方法,这些信号由数字序列表示。在过去的二十多年时间里,信号处理已经在通信等领域得到了极为广泛的应用。

长期以来,信号处理技术直用于转换或产生模拟或数字信号。其中应用的最频繁的领域就是信号的滤波。此外,从数字通信、语音、音频和生物医学信号处理到检测仪器仪表和机器人技术等许多领域中,都广泛地应用了数字信号处理技术。数字信号处理己经发展成为一项成熟的技术,并且在许多应用领域逐步代替了传统的模拟信号处理系统。而本文中基于DSP技术设计的正弦波信号发生器已被广泛地应用于通信、仪器仪表和工业控制等领域的信号处理系统中。

1.2 课题内容

利用基于CCS开发环境中的C54x汇编语言来实现正弦信号发生装置。

2、 设计原理

一般情况,产生正弦波的方法有两种:查表法和泰勒级数展开法。查表法是使用比较普遍的方法,优点是处理速度快,调频调相容易,精度高,但需要的存储器容量很大。泰勒级数展开法需要的存储单元少,具有稳定性好,算法简单,易于编程等优点,而且展开的级数越多,失真度就越小。

本文采用了泰勒级数展开法。一个角度为θ的正弦和余弦函数,可以展开成泰勒级数,取其前5项进行近似得:

式中:为θ的弧度值, (是采样频率;f是所要发生的信号频率)

3、 设计方案

本设计采用TMS320C54X系列的DSP作为正弦信号发生器的核心控制芯片。

通过计算一个角度的正弦值和余弦值程序可实现正弦波,其步骤如下:

1.利用sinxcosx子程序,计算0—45°(间 隔为0.5°)的正弦和余弦值

2.利用sin2x)=2sin(x)cos(x)公式,计算0—90°的正弦值(间隔为1°)

3.通过复制,获得0—359°的正弦值

4.0—359°的正弦值重复从PA口输出,遍可得到正弦波

整个系统相应的软件流程图如右图所示。

1 程序流程图

4、程序设计

4.1 产生正弦波程序清单sin.asm

.title "sin.asm" //为汇编文件取名为“sin.asm

.mmregs //定义存储器映像寄存器

.def _c_int00

.ref sinx,d_xs,d_sinx,cosx,d_xc,d_cosx //定义标

sin_x: .usect "sin_x",360 //"sin_x"保留360个存储空间

STACK: .usect "STACK",10 //为堆栈保留10个存储空间

k_theta .set 286 //theta=pi/360(0.5deg)

PA0 .set 0

_c_int00

.text //定义文本程序代码段

STM #STACK+10,SP //设置堆栈指针

STM k_theta,AR0 //AR0-->K_theta(increment)

STM 0,AR1 //(AR1)=X(rad)

STM #sin_x,AR6 //AR6sin(x)

STM #90,BRC //form sin0(deg.)—sin90(deg)

RPTB loop1-1 //重复执行块语句(下条语句开始至

loop1-191

LDM AR1,A

LD #d_xs,DP

STL A,@d_xs //(A)16d_xs

STL A,@d_xc //(A)16d_xc

CALL sinx //调用sinx程序

CALL cosx //调用cosx程序

LD #d_sinx,DP //DPd_sinx

LD @d_sinx,16,A //A=sin(x)

MPYA @d_cosx //B= sin(x)*cos(x)

STH B,1,*AR6+ //AR62*sin(x)*cos(x)

MAR *AR1+0 //修改辅助寄存器AR1

loop1: STM #sin_x+89,AR7 //sin91(deg.)sin179(deg.)

STM #88,BRC

RPTB loop2-1 //重复执行下条指令至loop2-190

LD *AR7-,A //((AR7)) A,然后AR7减去1

STL A,*AR6+ //(A) 16AR6

loop2: STM #179,BRC //sin180(deg.)sin359(deg.)

(BRC)=179,重复执行180

STM #sin_x,AR7 //AR7指向sin_x首地址

RPTB loop3-1

LD *AR7+,A //((AR7)) A,然后AR71

NEG A //累加器变负

STL A,*AR6+ //A16AR6

loop3: STM #sin_x,AR6 //AR6指向sin_x

STM #1,AR0 //AR01

STM #360,bk //BK360

loop4: PORTW *AR6+0%,PA0 //PA0=*AR6+0%,PA0输出数据

B loop4

sinx:

.def d_xs,d_sinx //定义标号d_xs,d_sinx

.data //定义数据代码段

table_s .word 01c7h //c1=1/(8*9)

.word 030bh //c1=1/(6*7)

.word 0666h //c1=1/(4*5)

.word 1556h //c1=1/(2*3)

d_coef_s .usect "coef_s",4 //"coef_s"保留4个存储空间

d_xs .usect "sin_vars",1 //d_xssin_vars保留1个存

储空间

d_squr_xs .usect "sin_vars",1 //d_squr_xssin_vars保留1存储空

d_temp_s .usect "sin_vars",1 //d_temp_ssin_vars保留1

存储空间

d_sinx .usect "sin_vars",1 //d_sinxsin_vars保留1个存储空间

c_l_s .usect "sin_vars",1 //d_xssin_vars保留1个存储

空间

.text //定义代码开始段

SSBX FRCT //设置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中的数值求其平方

ST A,*AR2 //A)左移16AR2

||LD *AR4,B //AR4)左移16B

MASR *AR2+,*AR3+,B,A //从累加器A中减去(AR2*AR3

MPYA A //操作数与累加器A中高位相乘

STH A,*AR2 //A)高16AR2

MASR *AR2-,*AR3+,B,A //从累加器A中减去(AR2*AR3

MPYA *AR2+ //AR2指向的数与累加器A的高16位相

ST B,*AR2 //B)左移16AR2

||LD *AR4,B //AR4)左移16B

MASR *AR2-,*AR3+,B,A //从累加器A中减去(AR2*AR3

MPYA *AR2+ //与累加器A中高16位相乘

ST B,*AR2 //B)左移16AR2

||LD *AR4,B //AR4)左移16B

MASR *AR2-,*AR3+,B,A //从累加器A中减去(AR2*AR3

MPYA d_xs //d_xs指向的操作数与累加器A中高16位相乘

STH B,d_sinx //B)高16d_sinx

RET //返回

cosx:

.def d_xc,d_cosx //定义标号d_xc,d_cosx

d_coef_c .usect "coef_c",4 //coef_c保留4个存储空间

.data //定义数据代码段

table_c .word 0249h //c1=1/(7*8)

.word 0444h //c1=1/(6*5)

.word 0aabh //c1=1/(3*4)

.word 4000h //c1=1/2

d_xc .usect "cos_vars",1 //d_xccos_vars保存1个存储单元

d_squr_xc .usect "cos_vars",1 //d_squr_xccos_vars保存1

存储单元

d_temp_c .usect "cos_vars",1 //d_temp_ccos_vars保存1个存储单元

d_cosx .usect "cos_vars",1 //d_cosxcos_vars保存1个存储单元

c_l_c .usect "cos_vars",1 //c_l_ccos_vars保存1个存储单元

.text //定义文本代码段

SSBX FRCT //FRCT=1以清除冗余符号位

STM #d_coef_c,AR5 //AR5指向d_coef_c首地址

RPT #3 //重复下条指令4

MVPD #table_c,*AR5+ //table_c中的数复制到中AR5

STM #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 //7FFFhc_l_c

SQUR *AR2+,A //x的平方存放在累加器A

ST A,*AR2 //A)左移16AR2

||LD *AR4,B //AR4)左移16B

MASR *AR2+,*AR3+,B,A //A=1-x^2/56,T=x^2

MPYA A //A=T*A=x^2(1-x^2/56)

STH A,*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)

MPYA *AR2+ //B=x^2(1-x^2/30(1-x^2/56))

ST B,*AR2 //(d_temp)= x^2(1-x^2/30(1-x^2/56))

||LD *AR4,B //B=1

MASR *AR2-,*AR3+,B,A //A= 1-x^2/12(1-x^2/30(1-x^2/56))

SFTA A,-1,A

NEG A

MPYA *AR2+ //B=1-x^2/2(1-x^2/12(1-x^2/30(1-x^2/56)))

MAR *AR2+

RETD

ADD *AR4,16,B //B=1-x^2/2(1-x^2/12(1-x^2/30(1-x^2/56)))

STH B,*AR2 //cos(theta)

RET

.end

4.2 正弦波程序链接命令文件sin.cmd

.cmd文件描述输入文件和输出文件,说明系统中有哪些可用存储器、程序段、堆栈及复位向量和中断向量等安排在什么地方。其中MEMORY段就是用来规定目标存储器的模型,通过这条指令,可以定义系统中所包含的各种形式的存储器,以及它们占据的地址范围;SECTIONS段说明如何将输入段组合成输出段以及在可执行文件中定义输出段、规定输出段在存储器中的位置等。

MEMORY

{

PAGE 0:

EPROM: org = 0E000h, len = 1000h

VECS: org = 0FF80h, len = 0080h

PAGE 1:

SPRAM: org = 0060h, len = 0020h

DARAM1: org = 0080h, len = 0010h

DARAM2: org = 0090h, len = 0010h

DARAM3: org = 0200h, len = 0200h

}

SECTIONS

{

.text :>EPROM PAGE 0 //文本代码段其实地址为0E000h,长度为

1000h

.data :>EPROM PAGE 0 //数据代码段其实地址为0D000h

STACK :>SPRAM PAGE 1 //堆栈起始地址为0060h,长度为0020h

sin_vars :>DARAM1 PAGE 1 //标号为sin_vars段的起始地址为0080

长度为0010h

coef_s :>DARAM1 PAGE 1 //标号为coef_s段的起始地址为0070h

长度为0010h

cos_vars :>DARAM2 PAGE 1 //标号为cos_vars段的起始地址为0090h

长度为0010h

coef_c :>DARAM2 PAGE 1 //标号为coef_c段的起始地址为0080h

长度为0020h

sin_x : align(512) {} > DARAM3 PAGE 1

.vectors :>VECS PAGE 0

}

5、仿真与调试

5.1 CCS工程项目的调试

利用 CCS 集成开发环境,用户可以在一个开发环境下完成工程定义、程序 编辑、编译链接、调试和数据分析等工作环节。

创建工程(project)文件

选择 ProjectNew,在“Project”文本框中键入将要创建的工程项目名,本例工程项目名为“sin

向工程中添加文件

选择 ProjectAdd Files to Project,将 sine.asm文件自动添加到 ProjectSource 中。 用同样的方法 sine.cmd 文件添加到对应的目录中。

构建工程,

工程所需文件编辑完成后,可以对该工程进行编译链接,产生可执行文件, 为调试做准备。

选择 ProjectBuild,系统提示没有出错信息后,系统自动生成一个可执行文件,sine.out 文件。

载入可执行文件

选择 FileLoad Program 载入编译链接好的可执行文件sine.out

运行程序

选择 DebugRun运行,可以通过查看内存表等方法,看到程序运行的结果。

5.2 仿真结果

选择 ViewGraphTime/Frequence

得到的正弦波形如下图所示:

输出结果显示,在CCS图形观察窗口得到了频率稳定,信号干扰小,波形失真度较小的正弦信号。

6、心得体会

通过这次的课程设计使我进一步加深了对于DSP这门课程的学习以及对于平时所学内容的实际应用。在设计中发现问题和同学互相讨论研究,并在编程过程中进一步提高自身的创作、创新水平,扎实基础,扩展所学。在输入程序时发现编程确实是要求很认真细心的,如果稍有差错就会导致整个程序的错误,也由此体现了DSP这门课程的严谨性。相信在以后的学习中一定会更好的应用所学内容的。

基于DSP的正弦信号发生器的设计

相关推荐