实验三  数字振荡器设计实验
一﹑实验目的
1.学习数字振荡器的原理;
2.学习C5402定时器使用;
3.学习中断服务程序编写;
4.实现数字振荡器的设计。
二﹑实验内容
1.设计数字振荡器的算法;
2.综合运用各种知识在C5402芯片上实现数字振荡器的算法;
3.通过CCS提供的图形显示窗口观察输出信号波形以及频谱,分析实验结果。
实验原理与方法
1.数字振荡器原理
设一个传递函数为正弦序列sinkωt,其z变换为
其中,A=2cosωt, B=-1, C=sinωt。设初始条件为0,求出上式的反Z变换得:
y[k]=Ay[k-1]+By[k-2]+Cx[k-1]
这是一个二阶差分方程,其单位冲击响应即为sinkωT。利用单位冲击函数x[k-1]的性质,即仅当k=1时,x[k-1]=1,代入上式得:
      k=0      y[0] = Ay[-1] + By[-2] + 0 = 0
      k=1      y[1] = Ay[0] + By[-2] + c = c
      k=2      y[2] = Ay[1] + By[0] + 0 = Ay[1]
      k=3      y[3] = Ay[2] + By[1]              .
    ……        .
      k=n      y[n]= Ay[n-1] + By[n-2]
k>2以后,y[k]能用y[k-1]y[k-2]算出,这是一个递归的差分方程。
根据上面的说明,我们可以开始数字振荡器的设计。
设该振荡器的频率为2kHz,采样率为40kHz(通过定时器设置,每隔25us中断一次,即产生一个y[n]),则递归的差分方程系数为:
    A=2cosωt=2cos (2 x PI x 2000 / 40000)=2 x 0.95105652
    B=-1
    C=sinωt=sin (2 x PI x 2000 / 40000)=0.30901699
为了便于定点DSP处理,我们将所有的系数除以2,然后用16位定点格式表示为:
               
这便是本实验中产生2kHz正弦信号的三个系数。在本实验中,主程序在初始化时先计算出y[1]y[2],然后开放定时器中断。以后每次进入定时器中断服务程序时,利用前面的y[1]y[2],计算出新的有y[0],通过CCS提供的图形显示工具,我们将在图形窗口中看到一个正弦信号波形。下面是初始化和中断服务程序代码片段:
初始化y[1]y[2]
        ssbx        FRCT        ;置FRCT=1,准备进行小数乘法运算
        st        #INIT_A,AA        ;将常数A装入变量AA
        st        #INIT_B,BB        ;将常数B装入变量BB
        st        #INIT_C,CC        ;将常数C装入变量CC
        pshd        CC                ;将变量CC压入堆栈
        popd    y2                ;初始化y2=CC
        ld        AA,    T            ;装AA到T寄存器
        mpy        y2,a                ;y2乘系数A,结果放入A寄存器
        sth        a,y1                ;将A寄存器的高16位存入变量Y1
中断服务程序片段:
        ld        BB,T            ;将系数B装入T寄存器
        mpy        y2,a                ;y2乘系数B,结果放入A寄存器
        ltd        y1                ;将y1装入T寄存器,同时复制到y2
        mac        AA,a            ;完成新正弦数据的计算,a寄存器中为
                                ;y1*AA+y2*BB
sth        a,1,y1            ;将新数据存入y1,因所有系数都除过2,所以在保
;存结果时转移一位,恢复数据正常大小。
        sth        a,1,y0            ;将新正弦数据存入y0
2C54X的定时器操作
C54X的片内定时器利用CLKOUT时钟计数, 定时器主要由3个寄存器所组成:定时器寄存器(TIMTimer Registers)、定时器周期寄存器(PRDTimer Period Registers)和定时器控制寄存器(TCRTimer Control Registers)。这3个寄存器都是16位存储器映像寄存器,在数据存储器中的地址分别为0024H0025H0026HTIM是一个减1计数器;PRD中存放时间常数;TCR中包含有定时器的控制位和状态位。定时器的功能框图如图1所示。
1中含一个16位的主计数器(TIM)和一个4位预定标计数器(PSC)TIM从周期寄存器PRD加载,PSC从周期寄存器TDDR加载。
1 定时器的功能框图
    定时器的典型操作顺序为
(1) 在每个CLKOUT脉冲后PSC1,直到它变为0
(2) 在下一个CLKOUT周期,TDDR加载新的除计数值到PSC,并使TIM1
(3) 以同样方式,PSCTIM连续进行减操作,直到TIM减为0
(4) 在下一个CLKOUT周期,将定时器中断信号(TINT)送到CPU,同时又用另一脉冲送到TOUT引脚,把新定时器计数值从PRD加载到TIM,并使PSC再次减1
从上面的介绍可以看到定时器实际上可以有20个比特的周期寄存器。它对CLKOUT信号计数,先将PSC1,直到PSC0,然后用TDDR重新装入PSC,同时将TIM1,直到TIM减为0。这时CPU发出TINT中断,同时在TOUT引脚输出一个脉冲信号,脉冲宽度为CLKOUT一致。然后用PRD重新装入TIM,重复下去直到系统或定时器复位。因而定时器中断的频率由下面的公式决定:
其中tc表示CLKOUT的周期。定时器当前的值可以通过读取TIM寄存器和TCR寄存器的PSC比特位得到。下面是本实验中初始化定时器的程序片段:
  stm    #10h,TCR        ;停止定时器
        stm    #2499,PRD        ;设置PRD寄存器值为2499TINT中断频率为
                      Foutclk /2499+1= 100MHz/2500 = 40 KHz
    stm    #20h,TCR        重新装入TIMPSC,然后启动定时器
3C54X中断的使用
C54X中用户可以通过中断屏蔽寄存器IMR来决定开放或关闭一个中断请求。其中, TINT0为定时器0中断。在中断屏蔽寄存器IMR中,1表示允许CPU响应对应的中断,0表示禁止。当然要CPU响应中断,ST1寄存器中的INTM还应该为0(允许所有的中断)。
DSP响应中断时,PC指针指向中断向量表中对应中断的地址,进入中断服务子程序。中断向量表是C5402存放中断服务程序的一段内存区域,大小为80H。在中断向量表中,每一
个中断占用4个字的空间,一般情况是将一条跳转或延时跳转指令存放于此。当然,如果中断服务程序很短(小于或等于4个字),可以直接放入该向量表。中断向量表的位置可以通过修改基地址来改变,其基地址由PMST寄存器中的IPTR15-7 bits)决定。例如C54x复位后其IPTR全为1,所以中断向量表起始位置在0FF80H,因而复位后程序从0FF80H开始运行。响应中断之后,CPU将执行下列操作:
    (1) PC(即返回地址)压入堆栈。
    (2) 将中断向量的地址装入PC;将程序引导至中断服务程序ISR
    (3) 现场保护,将某些要保护的寄存器和变量压入堆栈。
(4) 执行中断服务程序ISR
(5) 恢复现场,以逆序将所保护的寄存器和变量弹出堆栈。
(6) 中断返回,从堆栈弹出返回地址加载到PC
(7) 继续执行被中断的程序。
中断操作流程图如下:
2 中断操作流程图
本实验的初始化程序读取中断向量表的起始地址,然后设置PMST的高9位,以便DSP能正确响应中断,代码如下:
    ld  #0,dp            ;设置DP页指针
    ssbx intm            ;关闭所有中断
    ld  #vector, a        ;读出中断向量(地址vector在中断向量表程序中定义)
    and  #0FF80h, a        ;保留高9位(IPTR   
    andm #007Fh, pmst    ;保留PMST的低7
    or  pmst, a       
stlm a, pmst            ;设置PMST(其中包括IPTR
四﹑ 实验仪器设备
1typec转dpPC机一台;
2CCS开发软件一套;
3DSP教学实验系统一套。
五﹑ 实验步骤:
实验分下面几步完成:
1根据确定数字振荡器的频率,确定系数。数字振荡器系数的确定在前面已经说明,这里不再赘述。
2启动CCS,新建工程文件,如文件名为nco.pjt。选择Project菜单中的Add File to Project选项,将汇编源程序nco.asmvec_table.asm和连接定位d文件依次添加到工程文件中。注意,你可以在添加文件对话框中选择显示不同的文件类型来加快文件选择速度。你也可以使用鼠标右键单击工程文件名(如nco.pjt)并选择Add Files项来添加需要的文件。其中,nco.asm包括初始化代码和中断服务程序,而vec_table.asm包含中断向量表。
3选择Project菜单中的Options选项,或使用鼠标右键单击工程文件名(如nco.pjt)并选择build options项来修改或添加编译、连接中使用的参数。选择Linker窗口,在Output Filename”栏中写入输出OUT文件的名字,如nco.out,你还可以设置生成的MAP文件名。
4完成编译、连接,正确生成OUT文件。然后使用File菜单的Load Program”选项,将生成的OUT文件(如nco.out)装入DSP的片内存储器。这时CCS将显示程序的启始地址_c_int00
5ViewGraphTime/Frequency…打开图形显示设置窗口。在弹出的对话框中按下图设置,主要修改Start Address”为y0y0为生成的正弦波输出变量);Acquisition Buffer Size”为1DSP Data Type”为16-bit signed integer”。
6在汇编源程序的中断服务程序(_tint)中的nop”语句处设置断点。选择DebugAnimate,运行程序,观察输出波形。数一数一个周期的正弦波有多少个点?算算频率是否是2kHz?另外,想想RunAnimate两种运行方式的区别?
3 时域波形观察对话框
7用右键单击图形显示窗口,并选择Properties”项以便修改显示属性。将Display Type”项改为FFT Magnitude”以便显示信号频谱。修改Sampling Rate(Hz)”项为40000,然后退出。注意观察生成的正弦波频率。