嵌入式DSP实验报告.docx
- 文档编号:10546502
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:14
- 大小:86.12KB
嵌入式DSP实验报告.docx
《嵌入式DSP实验报告.docx》由会员分享,可在线阅读,更多相关《嵌入式DSP实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
嵌入式DSP实验报告
一.DSP实验课中关于硬件程序设计和调试的心得。
DSP实验课是我首次接触的嵌入式硬件设计课程,虽然以前有过汇编语言的学习,但DSP所使用的汇编语言感觉与原来所学习的汇编有相似之处但有更多的不同。
首先DSP为了强化自身的运算速度有其自身的一套独有的算法语句,比如块循环,改变了判断语句的使用使得计算效率有了很大的提高,另外对cmd文件的编写也是原来所没有的,我们需要自己对内存空间进行分配,注意有没有溢出,也可以清楚的看到数据在内存中的存储和改变。
程序的大体结构与一般汇编相似,都是先申明定义数据变量,然后进入主函数,也可调用子函数。
但要注意控制芯片时对端口的读写和对内部寄存器的修改,在cmd文件中也要指明程序入口。
在程序中最大的难点就是对寄存器的灵活使用及块循环的设定,要在理解公式的基础上,准确的算出循环位数。
一些不理解的函数可以通过选中函数按f1查询其用法,根据举例来判断是如何使用,具体循环多少次。
在中断程序的设计中,则要注意语句的位数,有些指令是单周期,有些是双周期,在中断映射表的设计中,都要保证能够通过偏移地址找到正确的中断位置。
在调试程序时,首先保证编译不出现error,然后要调出CPU寄存器的值和内存映像,然后在程序中设断点,比如初始化的位置设断点,看是否初始化个数正确,在循环块语句前和程序结束前设断点看每次计算结果是否正确,循环位数是否正确。
有时可能无法设断点,可以加几个nop语句然后在其位置设断点。
内存和寄存器值改变时颜色会变红,但要注意可能计算时值未改变,则不会变红。
如果内存原先有值,则可重启软件再测,可看的更清楚。
在和硬件结合设计时,要首先确定实验板的完好,在实验时要每次从最开始的试起,确定无误再进行下一步,要保留好历史版本。
程序得不到想要的结果,也可先重启实验板,先确定不是硬件问题,再考虑程序的修改。
二.滤波参数的设计与纯软件测试
MATLAB参数设计
具体代码
clearall;
clf;
N=10000;
fs=10000;
dt=1/fs;
k=1:
N;
f1=400;
f2=800;
f3=4500;
y=sin(2*pi*f1*k*dt)+sin(2*pi*f2*k*dt)+sin(2*pi*f3*k*dt);
lp=4000;
wn1=2*lp/fs;
[b,a]=cheby1(3,0.5,wn1);
b=b/(8*1.0711);
a=a/(8*1.0711);
disp('');disp(b);
disp('');disp(a);
y1=filter(b,a,y);
yf=fft(y,N);
yf1=fft(y1,N);
ypf=yf.*conj(yf);
ypf1=yf1.*conj(yf1);
f=(0:
N/2-1);
subplot(2,1,1)
plot(f,ypf(1:
N/2));
subplot(2,1,2)
plot(f,ypf1(1:
N/2));
实验图像:
CCS仿真结果:
三.Filter和AD程序合成的代码说明与解释
将AD/DA程序和FILTER程序结合成为滤波程序的过程
阶段一:
达到定时器工作正常
阶段二:
达到输出滤波正常
ad.asm文件中的详细修改:
滤波器主要参数的定义赋值
滤波器中的.def.set.uset的添加
ad和da程序的.def.set.uset
中断映射
主函数start
定时器设置采样频率10kHz
中断设置
写状态字
设定滤波器循环长度和CPU寄存器含义
等中断wait函数
用A做计数器并使AR5指向out-data
中断服务程序jump:
发出读信号,ad开始采样
等待几个周期查看波形
读ad采样结果存入out-data中
使读信号无效
读其他端口是ad转换器的cs为高电平
滤波主体程序,使用B寄存器每次循环将B清零将结果给ar5
写da端口,将ar5的值从da输出
程序结束
具体程序如下:
*******************************************************************************
************TLV1571调试程序ad.asm***************************
*******************************************************************************
.mmregs
.defjump
.defstart
.defb1,b2,b3,b4,a1,a2,a3
b1.set3b7H
b2.set0b27H
b3.set0b27H
b4.set3b7H
a1.set788H
a2.set7e7H
a3.set-0a2H
K_DATA_SIZE.set256;输入数据的个数
K_BUFFER_SIZE.set8;缓冲大小,必须大于a和b,并且必须是2的正整数次幂
K_STACK_SIZE.set256;堆栈大小
K_A.set3;a向量的个数
K_B.set4;b向量的个数
K_CIR.setK_BUFFER_SIZE
STACK.usect"stack",K_STACK_SIZE;定义一段未使用的
SYSTEM_STACK.setK_STACK_SIZE+STACK
;DATA_DP.usect"filter_vars",0
filterdata.usect"filter_vars",K_DATA_SIZE
bufferdatay.usect"filter_vars",K_BUFFER_SIZE*2
bufferdatax.usect"filter_vars",K_BUFFER_SIZE*2
;以便查看采集是否正确,也可以供需要分批处理数据的程序调用;以便查看采集是否正确,也可以供需要分批处理数据的程序调用,
K_SAMPLE_NUM.set256;设置保存采样数据的点数
out_data.usect"out_vas",K_SAMPLE_NUM;数据输出位置,大小为K_SAMPLE_NUM,用来保存一批数据,
;以便查看采集是否正确,也可以供需要分批处理数据的程序调用,
;例如FFT。
程序可以用ARX来制定数据的首地址
in_data.usect"in_vas",1
d_cr0_send.usect"cr_send",1
d_cr1_send.usect"cr_send",1;定义2个状态字,此状态字就是需要开始写入TLV1571的初始值
d_temp.usect"temp",1;存放临时数据
k_cr0_send.set0080h;初始化两个状态字的值
k_cr1_send.set0100h
***************************************************************************************************
************************重新映射中断向量的变量*****************************************************
***************************************************************************************************
K_IPTR.set000111000b<<07;指向1C00H新的向量区
;IPTR是DSP内部PMST寄存器的高9位,用于指定中断向量表的位置。
复位时全为1,
;此程序为了调试,重新映射地址1D00处
K_TEMP.set1111111b;定义一个常数,用于以后与PMST的与操作,
;保持PMST的低6位不变
D_PMST.usect"pmst",1
.sect"prog"
.text
.asgAR2,ORIGIN
.asgAR3,INPUT
.asgAR4,FILTER
.asgAR5,OUTPUT
start:
*******************************************************************************
***********************中断设置*****************************
*******************************************************************************
STM#0010h,TCR
STM#176Fh,PRD
STM#0C20h,TCR
STM#0008h,IFR
nop
nop
STM#0008h,IMR
nop
nop
RSBXINTM
nop
LDMPMST,A;取出PMST的值,放入A。
改变PMST的高9位,再放入PMST
AND#K_TEMP,A
OR#K_IPTR,A
STLA,PMST
*******************************************************************************
************设置初始值**********************************************
*******************************************************************************
stm#d_temp,ar2
stm#d_cr0_send,ar1
st#k_cr0_send,*ar1+
st#k_cr1_send,*ar1
stm#d_cr0_send,ar1
LD#K_SAMPLE_NUM,A;用以计数
stm#out_data,ar5
*******************************************************************************
***********************写状态字****************************
*******************************************************************************
portr0FFFFh,*ar2;读别的端口,使A/D转换器的CS为高
nop
nop
nop
portw*ar1+,07FFFh;填A/D转换器的寄存器AR1
rpt#8
nop
portw*ar1,07FFFh;填A/D转换器的寄存器AR1
portr0FFFFh,*ar2;读别的端口,使A/D转换器的CS为高
rpt#10
nop
nop
STM#K_CIR,BK
STM#1,AR0;设置循环缓冲区大小和步长
STM#bufferdatax,INPUT
STM#bufferdatay,FILTER;此时,写好状态字A/D开始采样
*******************************************************************************
*****************等中断用A做计数器,当写完K_SAMPLE_NUM个数据之后
重置计数器A,并使AR5指向out_data的开始地址************************************
*******************************************************************************
WAIT:
NOP
NOP
BCWAIT,ANEQ
NOP
STM#out_data,ar5
LD#K_SAMPLE_NUM,A
BWAIT
NOP
*******************************************************************************
********************中断服务程序,用以读转换信号,放入out_data区**************
*******************************************************************************
jump:
SUB#1h,A;计数
rsbxxf;发出读信号,A/D转换器收到后开始下一次采样
rpt#5
nop
;等待几个周期,便于示波器查看波形
portr07FFFh,*INPUT+0%;读A/D转换数据,写在RAM的out_data数据段
rpt#5
nop
ssbxxf;使读信号无效
nop
portr0FFFFh,*INPUT;读别的端口,使A/D转换器的CS为高
nop
nop
RPTZB,#K_B-1;累加器B置零,INPUT重复减3次
MAR*INPUT-0%
MAC*INPUT+0%,#b4,B
MAC*INPUT+0%,#b3,B
MAC*INPUT+0%,#b2,B
MAC*INPUT+0%,#b1,B
MAC*FILTER+0%,#a3,B
MAC*FILTER+0%,#a2,B
MAC*FILTER+0%,#a1,B;A=b4*x[i]+b3*x[i+1]+b2*x[i+2]+b1x[i+3]+a3*y[i]+a2*y[i+1]+a1*y[i+2]
STHB,*FILTER;将累加器A的值给y[i+3]
STHB,*AR5;y[i+3]赋给输出
RPT#K_A-1-1
MAR*FILTER-0%;调整滤波器使FILTER指向y[i+1],开始新一轮的计算
NOP
NOP
NOP
portw*ar5+,0BFFFh
;从D/A转换器输出
rete;中断返回
.end
四.程序“调试”记录
最开始的程序是以10kHz采样频率的ad采样器直接将采样结果由da输出的程序和一个简单的IIR滤波器程序组成的。
首先这两个程序要能够正常运行,10kHz的ad和da输出可以在示波器上观察到输入输出波形频率基本相等,幅度由于ad是10位,da为12位导致大小有4倍左右的差别,同时da的相位有一定延迟,在示波器上da波形较粗,按下暂停可看到阶梯状的波形,这是由10kHz采样频率造成的,注意ad波形要调整直流电平使其全为正,否则ad无法正确识别负的值。
对于原始滤波程序,在MATLAB,仿真后得到参数,然后再用ccs进行仿真,确认是正常的低通滤波器后开始程序的合成。
首先修改的是cmd文件,将相同的内存区合并然后,并添加新的储存空间,注意地址范围不要重合。
然后添加滤波器的参数定义和数据赋值,一般放在主程序前,和ad的参数定义放在一起,此时就可以保存一次进行编译看是否有错误,参数合成时是不是漏掉或多出定义,然后确定滤波主体程序的位置。
我们需要在ad采样后进行滤波,然后输出给da。
因此应放在ad采样数据读取之后,并且da还未写入数据,因为是及时输入输出,滤波器就不需初始化,直接开始滤波,直接跳过前3个y值开始计算。
然后将计算结果付给ar5,并且将其值由da输出,需要注意的是,在读ad时我们用了一个存储空间,而之后为了停止ad由读了一次,这两次存储位置应不同,也导致了在滤波程序中的循环位数的改变。
在调试过程中要注意硬件是否存在问题,要注意重启实验板进行复查,在程序设计时要多设断点,利用在单个程序中的调试方法检测x,y是否同步,中断返回的位置是否正确。
也要多与同学交流,分享心得,检查自己的错误是在哪,尤其是滤波器返回的位数的错误。
滤波器插入位置的错误。
最终测试时用信号发生器产生正弦信号输入ad中,示波器ch1ch2分别接输入输出,调整信号频率可以观察到滤波器为一低通滤波器,在2kHz以下有良好的通频带,之后随着频率升高输出幅度降低
到4000Hz以上时基本为30mv左右,但仍为正弦波形,频率和输入频率相等,到了5kHz以上时,输出不再显示正弦波,而是一复杂的周波形,幅度较低。
五.实验结果记录与分析
实验图像:
实验参数设计时,是4kHz的3阶低通IIR滤波器,而实际测试时发现通频带仅有1.24kHz,与实验预期相差很大。
但在MATLAB仿真时的结果却非常好。
可能是在参数转换时导致了误差,还有实验板本身的误差。
首先MATLAB产生的数据是10进制小数,由于我们要转换成16进制数,首先将其按比例缩小,使其全小于1,这时便已产生误差,然后乘以32768后,将整数部分转换成16进制,这样就会丢失很多数据,导致不精确。
这次实验中我有一个参数-a2H太小,实际上会有很大误差,在所有参数等比例放大的情况下,可以使滤波器幅值变大,截止频率更接近理论值。
另外,dsp芯片本身的运算速度也不可能和MATLAB的精确仿真相同,matlab给出的是一个接近矩形的滤波器,而dsp必然有一个下降曲线,导致测出的截止频率不同于理论值。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 DSP 实验 报告