DSP实验——TSM320F2812

  1. DSP开发基础实验

实验目的

  1. 了解DSP开发系统的基本配置;

  2. 熟悉DSP集成开发环境(CCS);

  3. 掌握C语言开发的基本流程;

  4. 熟悉代码调试的基本方法。

1实验内容

新建工程,对工程进行编译、链接,下载到目标板上后进行实时调试。利用代码调试工具跟踪程序的运行。根据.map文件,指出各段在存储器空间的地址,体会Memory Map的设计思想。

2实验原理

使用CCS进行DSP开发至少需要以下3种文件:1、.c或者.asm程序文件,这是用户写的程序;2、.cmd文件,即配置命令文件,其指定了链接器在链接时存放各段的物理地址;3、.lib文件,是由芯片厂商提供的运行支持库。TSM320C28x系列对应rts2800_ml.lib. 当然除了这3类外,建立项目工程后还会产生.pjt文件,这其实就是一个文本文件,记录了项目中芯片的类型,程序目录,输出目录以及编译器设置等信息。

使用C语言在CCS下开发时,C编译器(Complier)首先将C语言翻译成汇编代码,这一步也会对程序进行一些可选的优化。然后汇编器(Assembler)将汇编代码转换符合公共目标格式COFF的机器码。连接器(Linker)对.obj文件重定位,根据配置命令文件.cmd指定各段的物理地址,输出DSP可执行文件。

DSP的仿真调试可以使用Simulator 和Emulator方式。前者使用计算机的CPU进行仿真,可以实现程序功能的验证,但不能进行外设的模拟和实时性验证。后者是利用仿真器硬件,通过JTAG接口与DSP相连,使用边界扫描技术实时获得芯片的状态,程序是全速运行在DSP上的,因此所见即所得。

3实验步骤

  1. 设备上电,连接计算机。

  2. 设置开发环境。点击“C2000 Setup”图标,设置硬件仿真器的型号,导入配置文件。

  3. 新建工程。打开CCS C2000,新建工程,填写工程名,选择对应的DSP芯片TMS320C28xx,选择工程路径和输出文件格式。点击“确定”即建立了工程。

  4. 添加工程文件。将实验9例程中的.c文件、.h文件、.cmd文件和.lib文件复制到工程目录下。在project窗口中工程名上右键单击,Add File to Project,添加所有上述文件。

  5. 编译链接。

  6. 下载程序到目标板,进行调试。完成实验内容所要求的工作。

4程序设计

第一个实验旨在熟悉CCS的开发环境和DSP开发流程,故而实验程序已经提供,无需改动。

通过对源代码的分析,程序主要干了三件事:1、关闭看门狗;2、在CCS的output窗口输出字符串;3、在存储器中,从一片连续地址取数据,乘以一个增益后存入另一片连续地址。

具体实现如下:

1、关闭看门狗:

图1看门模块

图2 WDCR寄存器定义

直接对WDCR寄存器的WDDIS位写1,关闭看门狗。在对寄存器操作前还要先执行汇编语句eallow,操作完后再执行汇编语句edis.

2、在output窗口输出字符串:

puts语句即可实现:

puts("SineWave example started\n");

3.数据的复制:

首先在头文件中声明了一个结构体IOBuffer,结构体内包含两个长度同为BUFFSIZE的数组input[]和output[],类型为16位int. 然后在main函数中定义了1个该类型的结构体,使用下标遍历整个数组,将input[]中的数值乘以增益系数gian,存入output[]中。这些操作在函数processing()中实现。

这个程序已经足够简单,无需使用框图进一步解释。

5实验结果

5.1子程序和数据的地址

子程序入口地址:

装载程序到DSP后,将鼠标停留在C语言编辑器的函数上,会显示函数的入口地址。如图6-1(a)和6-1(b),显示了dataIO()和processing()的入口地址,分别是0x003F81F5和0x003F81D8.

图3 (a). dataIO()的入口地址 (b). processing()的入口地址

从中还可以看到,dataIO()函数的入口地址比processing()函数大了29,说明processing()的汇编指令至多有29条。而且还说明,链接器在存储器中分配程序空间时,函数的物理地址不一定按照C语言编写时的顺序。实际上对于汇编指令调用函数来说,程序入口地址的顺序并不重要。

存储器地址:

通过菜单上的View – Watch,打开变量查看窗口。输入变量名currentBuffer.input和currentBuffer.output, 查看变量的值。结果如图6-2(a)和(b),两个变量的地址分别是0x00008480和0x00008500, 他们相差了128,也就是一个数组的长度。结构体中的变量是连续存放的。

  

图4 (a). currentBuffer.input的地址 (b). currentBuffer.output的地址

5.2初始时的内存数据

程序载入到DSP后,直接运行整个程序。使用Graph工具,以图像方式显示数组currentBuffer.input和currentBuffer.output中的数据。由于数组的类型是int型,长度为128,所以在GraphView中设置类型为“16bit singned int”,长度为128,变量地址填6.1节中所述的物理地址,或者直接填变量名。运行一段时间后,两个数组的内容如图6-3所示:

 

图5 (a).input数组中的数据 (b).output数组中的数据

从整体来看,input数组中的数据是随机无需的,这是因为DSP在上电后,RAM中的数据是随机的。再看output中数据和input数据的关系,将光标都设置在第10点处,input中的数据是3430,而output中的数据是-13720,是前者的-4倍。证明output中的数据是从input中复制的,而且乘以了增益-4.

5.3用探针导入数据后运行

在processsing()函数之前的位置放置探针,向currentBuffer.input[]中导入正弦波形。程序中的空函数dataIO()正好提供了这样的位置。因此将探针点设置在dataIO()函数上,然后在File-File I/O中对探针进行设置,包括数据文件、地址、长度等。数据文件就是目录下的sine.dat, 地址设为input[]数组的物理地址0x00008480,长度为128d.

图6 探针位置

 

图7探针设置 图8 导入数据

导入数据后,程序复位,重新运行。刷新Graph窗口中的内容,结果图6-7.

图9 (a). 从探针导入数据后的input[]数据 (b).运行之后的output[]数据

这时,input数组中的数据已经是正弦波了,而且运行完processing()函数后,数据也复制到了output中。为了进一步验证复制结果,与上节一样,用光标选取两个数组中相同的位置(本来想都取第35点,写报告时才发现手滑取错了TAT’),input中数据是98,output数据大致是其-4倍。由于乘以了负增益,output中整个波形关于x轴反转了。这些现象都验证了程序功能的正确性。

5.4.map文件与.cmd文件

打开debug目录下编译链接后生成的.map文件,查看其内容。.text、.data、.bss段的起始地址和长度分别如下:

图10 .map文件中各段的地址和长度

其中.text段起始地址为0x003f81c5, 长度为0x0adb;.data没有被分配空间,地址和长度都为0;.bss起始地址为0x00000400,但长度为0.

根据TMS320F2812芯片的memory map(图6-9),可知text位于H0 SARAM中,bss段位于M1 SARAM中。

打开.cmd文件,确实没有定义.data段;.text分配在0x003f8080起始的存储器中,与.print、.cinit段在一起;.bss段为分配在起始地址为0x0400起始的M1 RAM中。

可见,根据芯片的memory map,.cmd文件指定了各段的存储地址,而编译链接后.map文件详细报告了各段的地址分配。这三者是统一的。

图 11 Memory map

图12 cmd文件中指定的段位置

6小结

第一个实验的主要目的是为了熟悉CCS开发环境,了解开发流程。由于之前在CCS上开发过430单片机和5000系列 DSP,何况所有的IDE都大同小异,所以这个实验很快就做完了。作为TI自己的软件,CCS的特点在于对芯片的调试支持非常到位,比如可以通过设置探针,导入和导出数据,可以用Graph工具对内存数据作图。而一般的开发工具似乎只能设置断点慢慢调试。

虽然这个实验很简单,但可以分析的问题还是很多的。实验时,我们记录了在用探针导入数据之前和导入之后数组内的数据,以此说明探针的作用;分析了processing()执行后,input[]和output[]中数据的关系,证明这个函数实现了数据的复制,并乘以了增益-4;通过比对.map和.cmd中各段的地址和长度,将数据对应到了Memory map中的物理存储器,从而对各段数据的存储位置有了直观的认识。

  1. 任意信号发生器

1实验目的

  1. 熟悉DSP硬件开发平台

  2. 熟悉DSP集成开发环境(CCS)

  3. 掌握TMS320F2812的存储器配置表

  4. 学习TMS320F2812的编程开发

  5. 熟悉代码调试的基本方法

2实验内容

分析实验例程,学习DDS的原理,在此基础上对实验程序进行改写,产生线性调频信号:

采样时间内包含1024点离散数值。

3实验原理

DDS的结构框图如下所示,其中频率控制字控制相位累加器的步进量,根据相位累加器中的数值,从波形查找表中取对应的数值,送入DAC,最后经过低通滤波器滤除高频,就得到了波形的模拟输出。

图 1 DDS结构框图

实验箱上的DAC1信号为AD768,位宽16bit,以无符号数表示,0x8000表示0电位。DAC映射到了DSP的地址0x2900, 因此向DAC写数据只要写地址0x2900即可。

实验箱上8个LED数码管共阴,地址从0x2000开始,0x100递增。写入相应的码段之后,在0x2C00写任意数值,刷新锁存器即可。

4实验设计

在这个实验中,没有用到任何外设,因此可以将所有外设时钟关闭。除此之外,设定主时钟锁相环5倍频。这样,外部时钟为30M,CPU工作时钟为150M。实验程序的流程图表示如下:

图 2 程序流程图

其中,波形查找表存储在0x0010 0000起始的内存中,这个是外部的SRAM,使用指针直接操作地址,实现数据存取。

计算波形数据时,使用math.h中的cos()函数,得到的是有符号数,乘以幅度后转换为int型。而DAC接收的是无符号类型,0x0000为-2v,0x8000为0v,0xFFFF为+2v,相当于将一个补码向上整体搬移了0x8000。因此将int型数据转换为DAC的数据,方法如下:

*(DAC1Addr) = (unsigned int)((*(RamAddr+1*i))<<2)+ 0x8000;

在将int型转换为unsigned int之前,还要先左移几位,防止向上搬移0x8000时溢出。

5实验过程

5.1运行实验例程

建立工程后,添加实验所给的例程,编译链接下载到DSP中。例程中实现了正弦波信号的产生,但很不幸的是,运行实验例程,通过示波器观察发现,实验箱上的DAC坏了..

图 3 损坏的DAC输出

如图3,表现为:幅度大于一定值时,输出突然下降一个台阶。为了确认是DAC的问题,在别的实验箱上运行同样的程序,是没有问题的。

所以我们的实验,包括后面的2个实验,用到DAC时,都没有用到满幅度,这样,实际可用的DAC位数是小于16bit的,最大输出幅值也变小了。将正弦波幅度减小4倍后,输出正常。如图4所示,是减小正弦波幅度后的输出,波形正常,但此时峰峰值只有1v了。

图 4 减小幅度,避开DAC故障后的输出

运行例程的价值在于:除了发现DAC故障外,还可以测出1024点输出所需的时间。在例程中,一个正弦波波形由1024点数据组成,测得正弦波频率为1.04626kHz,说明遍历输出一个正弦查找表需要1/1.04626k=9.5579e-4 s, 所以平均输出每个点需要时间:9.5579e-4/ 1024=9.33e-7 s. 无论输出什么波形,这个时间是不会变的。

5.2生成线性调频信号

按照实验要求,1024点的线性调频信号为:

分析可知,在2×0.0128=0.0256s时间内,有1024个离散点,因此每个点代表的时间为0.0256 / 1024 = 1/40000s. 换算成离散坐标,表达式如下:

从而,生成查找表的C代码就是:

for(i=0;i<1024;i++)

*(RamAddr+i) = (int)( (cos(K*Pi*(-512+i)*(-512+i)/N/N)*2048) );

使用Python对上述表达式进行了计算并作图,得到的波形如图5(a).

编译链接程序,下载到DSP上,然后运行程序。在Graph工具中查看起始地址0x0010 0000,长度1024点的数据图形,结果如图5(b)

 图 5 (a)仿真结果 (b) 实际运行结果

将输出连到示波器上观察,波形仍然正确。图6显示了示波器测量结果,从右边测量结果看,此时的频率是1.042kHz, 周期为960us.

图 6 频率为1.042kHz的线性调频信号 

5.3调节线性调频信号周期

在上一节中,已经正确产生了频率为1.042kHz,周期为960us的线性调频信号,但题目要求周期是0.0128×2=0.0256s,即25600us. 增加周期只需要增加每个点的输出时间即可,因此可以对每一个点重复输出数次,调整到所需的周期。25600是960的26.6倍,所以对每个点重复输出27次左右即可。通过实验,发现重复28次即可以调整到所需周期。这样,在while(1)内,程序代码就是如下的形式:

while(--j)

{

*(DAC1Addr) = (unsigned int)((*(RamAddr+1*i))<<2)+ 0x8000;

}

j=29;

经过周期调整的输出波形如图7,右边的测量结果显示,此时周期是25.4us,已经很接近要求了。

5.4LED数码管显示

在DSP初始化设置后,操作LED数码管显示字符。数码管的操作方法在第3节原理中已经叙述,直接向特定的地址写数据就行了。我们让数码管显示了NJUST.Lys字样,“Lys”是我们指导老师名字的首字母,感谢老师的教导。

图 7 LED数码管显示

5.5子程序入口地址与.map文件

下载DSP程序后,鼠标悬停可以看到函数的地址。本程序中除了主函数mian()外,还有dispLED()函数。它们的地址分别是:0x0000 0000 和 0x0000002C.

 

图 8 子程序的入口地址

根据memory map,它们都位于M0 Vector RAM 中。查看.map文件,.text段确实从0x0000 0000开始。这里本来是用于存放中断向量的,但程序没有用的中断,存放函数也无妨。

section page origin length input sections

-------- ---- ---------- ---------- ----------------

.text 0 00000000 000002eb

除了.text、.data、.bss段,实际占据内存长度的还有:

.cinit 0 003f8002 0000002d

.reset 0 003fffc0 00000002 DSECT

.stack 1 00000400 00000400 UNINITIALIZED

其中.cinit段是全局变量和静态变量的C初始化记录,.stack是运行时堆栈。

6小结

本实验在第1个实验做完后剩下的时间内接着做的,也比较简单。由于实验箱上的DAC损坏,电压最大幅度只能用到1/4,但这影响不大。首先通过运行实验例程,记录了1024点遍历所需的时间,为后面调整信号周期提供参考(5.1节)。第二步是计算出了线性调频信号的离散表达式(5.2节),并使用python进行了简单的仿真。波形仿真正确后下载到DSP运行,使用graph工具查看波形,与仿真结果相同,示波器也观察到了输出波形。根据题目要求的0.0256s周期,我们通过一个样点多次输出的方法,加大了信号周期,并认为每个点重复28次,可以得到比较接近0.0256s的周期。c程序和调整后的波形在(5.3)节中展示了。但由于对波形查找表的取值是在while(1)中循环的,延时由指令数决定,因而不能做到精确的频率控制。更好的方法是在定时器中断函数内读取查找表,这样就可以通过定时器计数值任意设置波形周期了。此外,还操作了LED数码管,正确显示了预设的字符(5.4节)。最后,查看.map文件,指出了子程序在物理存储器中的位置。

  1. FIR滤波器的DSP实现

1实验目的

1. 巩固数字FIR滤波器的概念;

2. 理解定点DSP中数的定标、有限字长、溢出等概念;

3. 理解算法实现中实时的概念;

4. 掌握DSP开发过程以及基本调试方法;

5. 理解汇编以及高级语言开发DSP实现算法的区别。

2实验内容

确定FIR滤波器参数,设计滤波器系数,完成数据的定标。仿真有限精度截断对FIR冲击响应的影响。验证系统实时性,实验测量幅频响应。

3技术指标设定与可行性分析

我组在实验室北排,要求实现FIR带通滤波器。经过考虑,决定实现50kHz,40阶FIR滤波器,截至频率设为1000Hz和3000Hz.

可行性分析:

ADC的采样频率由定时器触发,设置EVA时钟分频位TPS=2,高速外设分频数HSPCLK=2,T1PR=374,此时定时器触发ADC的周期为:

30M×5/ 2 / 2^2 /(374+1)=0.05M=50kHz

即可以得到精确的50kHz采样率。

此时CPU时钟为150M, 平均每个中断周期内可以分配到3000条指令执行时间。40阶FIR滤波器包括40次乘加运算,由于使用了循环数组,只需少量的内存更新操作,再加上DSP的流水线结构,加上逻辑判断操作后,保守估计一个样点计算使用多达20条指令,40阶也只有800条,小于3000的裕量。

在50kHz采样率下,将通带设置在1kHz~3kHz,是满足采样定理的,一个周期可以分到20个样点左右,还原出来的波形直接输到示波器上,尚可辨别。

4FIR滤波器系数设计

FIR滤波器可以利用matlab的可视化滤波器设计工具箱fdatool来设计,设计界面如图1所示。利用该工具可以直接得到41个滤波器系数,记为h[n],这些都是绝对值小于1的小数。TMS320F2812是定点DSP,因此在DSP中运算时,使用的是精度有限的定点数。在C语言中实现小数点标定的方法是:使用扩大了2的n次方的int型表示小数,参与运算,在最后的结果上通过右移n位,得到真实的数值。

在本实验中,我们使用16位int型存储滤波器系数,标定为Q14. 从matlab的浮点小数转换为16位定点数,必然会造成精度的损失。利用matlab可以仿真截断后的冲击响应幅频特性。仿真结果如图2.

图 1 fdatool设置参数

 

图 2 FIR系数的定点仿真

5程序设计

FIR滤波器实验建立在实验3的基础上。在上次实验中,已经实现了ADC数据的采集和DAC的输出,设计FIR滤波器时,只需要重新设置EVA时钟中断周期,其余无需改动。本实验更多的关注点在于算法的设计。

5.1运算数据类型

F2812的片内ADC位数为16bit 无符号,由于附加了外部电路,输入模拟信号时,0v电平对应的二值数据为0x8000,这与DAC接收数据的格式是一样的。FIR滤波器系数使用Q14定标,转换为了16位int型。根据FIR滤波器的表达式:

                      (1)

ADC采样值16bit uint 和滤波器系数 16bit int 相乘,最大将扩展到32位。所以运算过程中的使用的数据类型转换如下所示:

 

图 3 运算中数据类型的转换

其中,运算求和后得到的32bit long,在输给DAC之前,要转换移位为16bit. 滤波器系数定标时使用了Q14,原本对结果也右移14位即可,但实验所用DAC是坏的(实验2中提到过),只能用到14位,所以对求和结果右移了16位,避免了DAC因故障而跳变。

5.2算法设计

上一个实验中,对ADC采样数据的存储使用了循环数组来实现,在40阶FIR滤波器中,这个数组长度是41. 并且由于数组中存储的数据是一个”环”, 环的起点下标由一个变量buffIndex来表示,所以需要仔细考虑采样点数据与滤波器系数的对应关系。下图展示了采样值与滤波器系数相乘时的对应关系,这将是整个算法的精华。

 

图 4 循环数组中x[n]与h[n]的对应关系

从图中可以看到,由于存储采样点存储顺序不是与数组下标对应的,需要引入队列头位置变量buffIndex,与FIR系数h[n]对应起来。FIR的乘加可以分为part1和part2两部分计算,在part1中,h[0]对应了buffer[buffIndex], h[1]对应buffer[buffIndex-1],……以此类推,part1中共有buffIndex+1次乘加运算。同样的方法,根据图4,也可以得到part2中两个数组的对应关系。

记当前队列头的数组下标为index,则计算两部分乘加结果的方法可以用伪代码表示如下:

Order=41

Sum=0

firIndex=buffIndex

for(i=0; i<=index; i++) //计算part1的乘加

sum=sum + h[k]*buffer[firIndex]

firIndex=firIndex-1

end

firIndex=buffIndex //firIndex归位

for(i=index+1; i<Order; i++) //计算part2的乘加

sum=sum + h[k]*buffer[firIndex]

firIndex=firIndex-1

end

6实验结果

6.1幅频响应测量

调整信号源产生正弦信号,输出频率从低频扫描高频,覆盖带通区域,调整输出信号幅度尽可能大,但使滤波结果不溢出。测量得到不同频率下输出幅度,作图结果如下:

 

图 5 测得幅频响应

 

图 6 实测幅频特性与理论值比较

观察实测结果,滤波器的通带位于1000Hz至3000Hz,这与理论是相符的,在通带之外,测得的衰减值小于理论,这可能是由于32位int型下误差的积累造成的。

6.2失败案例分析

以上分析的算法和所得实验结果是我们第二版程序,第一次实验时没有成功。第一次的实验使用了浮点表示滤波器系数,但由于没有分析清楚数据转换的格式,最后输入DAC的值产生了混乱,同时,在定点器件上模拟浮点运算,造成运算量大,迫近实时性极限。

最后一次实验,在进入实验室之前又重新写了实验程序,使用Q14表示FIR系数,理清了数据转换过程。然而最后DAC输出的波形出现了倒置。

 

图 7 DAC输出的波形倒置

分析认为,这是因为最后DAC的数据发生了溢出。在传递给DAC之前,又多右移了2位,输出结果正确。

7实验总结

FIR滤波器实验是建立在实验3的基础上的,ADC采样,DAC输出的链路已经调通,寄存器设置也无需作大改动。本实验主要考验软件算法的设计以及小数定标的选择。这个实验写了两个版本,均在进入实验室之前写好,程序中使用了条件编译,可以先测试ADC采样频率,然后切换到FIR计算功能,最大限度利用好实验时的宝贵时间。第一个版本使用了浮点小数做FIR系数,结果运算量巨大,最后输入到DAC的数据格式混乱,没有成功。下一次实验之前,用Q14定标的16位小数作FIR滤波器系数,写了第二个版本。并且为了防止实验时产生实时性问题,我们准备了3组滤波器方案,分别是25kHz采样率30阶,50kHz采样率30阶和50kHz采样率40阶。最后进入实验室实际运行时,50kHz采样率40阶完全是可行的。这得益于精心安排的数据存储结构和系数-样点对应方法(5.2节)。调试成功后,实测了滤波器的幅频特性响应,与理论进行了比较(6.1节),结果显示,在通带内实际和理论符合较好,在通带外的衰减能力实际并没有理论那么高。

  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
TMS320F2812是德州仪器(TI)推出的一款数字信号处理器芯片,用于控制和处理实时数字信号。在将程序下载至TMS320F2812芯片之前,需要进行一系列步骤。 首先,需要确定所需的下载工具。常用的下载工具有JTAG仿真器,如XDS100、XDS510等。选择适合自己的仿真器,然后将仿真器连接至计算机,并通过JTAG接口与TMS320F2812芯片连接。 接下来,需要选择合适的下载软件。TI官方提供了一款名为Code Composer Studio(简称CCS)的集成开发环境(IDE),可用于下载程序至TMS320F2812芯片。确保已在计算机上安装CCS软件。 在CCS软件中,需要创建一个新的项目。选择TMS320F2812作为目标芯片,并配置好仿真器的连接方式。然后,在项目中添加所需的源代码文件,并进行编译。确保编译成功,生成可执行文件。 然后,需要将生成的可执行文件下载至TMS320F2812芯片。在CCS软件中,点击下载按钮,选择仿真器和目标芯片,并设置好下载参数。然后,点击确定开始下载。此过程将把可执行文件烧录至TMS320F2812芯片的闪存中。 下载完成后,可以重新启动TMS320F2812芯片,使其执行新下载的程序。如果一切顺利,程序将开始运行,并根据代码的要求执行相应的任务。 总之,TMS320F2812程序下载需要选择合适的下载工具和下载软件,创建项目并编译生成可执行文件,最后将可执行文件下载至芯片中。这样,我们就能够成功下载程序至TMS320F2812芯片,并使其正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值