信息工程学通信工程系.ppt

上传人:小飞机 文档编号:5229678 上传时间:2023-06-16 格式:PPT 页数:122 大小:1.31MB
返回 下载 相关 举报
信息工程学通信工程系.ppt_第1页
第1页 / 共122页
信息工程学通信工程系.ppt_第2页
第2页 / 共122页
信息工程学通信工程系.ppt_第3页
第3页 / 共122页
信息工程学通信工程系.ppt_第4页
第4页 / 共122页
信息工程学通信工程系.ppt_第5页
第5页 / 共122页
点击查看更多>>
资源描述

《信息工程学通信工程系.ppt》由会员分享,可在线阅读,更多相关《信息工程学通信工程系.ppt(122页珍藏版)》请在三一办公上搜索。

1、1,信息工程学通信工程系,DSP技术及应用,Digital Signal Processor数字信号处理器,陈金鹰 副教授,2,第五章 汇编语言编程举例,第一节汇编语言编程的基本方法 第二节 DSP的浮点运算方法 第三节 DSP在信号发生器上的应用 第四节 用DSP实现FIR滤波器,3,第一节 汇编语言编程的基本方法,1堆栈的使用,1.压入数据时,堆栈从高地址向低地址增长。2.压栈时指针先减,SP-1,再压入数据;3.出栈时,先弹出数据后,再SP+1。4.如要用堆栈,必须先设置,后使用。,要点,4,例5-1 设计一存储空间为100个单元的堆栈。size.set 100;设置堆栈空间的;大小为1

2、00stack.usect“STK”,size;设置堆栈段的首地址;和堆栈空间 STM#stack+size,SP;将栈底地址指针送;SP,对其初始化,5,例5-2 编写求解加、减法的程序,计算z=x+y-w。SUM1:LD x,A;将x地址的内容送A ADD y,A;将y地址的内容与A中x值相加 SUB w,A;将A中的内容与w 相减,得z STL A,z;将A的的计算值存入z 地址中例5-3 写求解直线方程的程序,计算y=mx+b。SUM2:LD m,T;将m 地址的内容送T MPY x,A;将x 地址的内容与T中的m相乘,;结果送A ADD b,A;将A中的mx与b 地址的内容相加,;结

3、果送A STL A,y;将A的的计算结果存入y 地址中,2 加、减法和乘法运算,6,传送速度比加载和存储指令要快;传送数据不需要通过累加器;可以寻址程序存储器;与RPT指令相结合(重复时,这些指令都变成单周期指令),可以实现数据块传送。,3 数据块传送,特点,7,(1)数据存储器数据存储器 这类指令有:MVDK Smem,dmad 指令的字数/执行周期 2/2MVKD dmad,Smem;Smem=dmad 2/2MVDD Xmem,Ymem;Ymem=Xmem 1/1(2)程序存储器数据存储器 这类指令有:MVPD pmad,Smem;Smem=pmad 2/3MVDP Smem,pmad;

4、pmad=Smem 2/4pmad为16位立即数程序存储器地址;dmad为16位立即数数据存储器地址;Smem为数据存储器地址;Xmem、Ymem为双操作数数据存储器地址,Xmem从DB数据总线上读出。Ymem从CB数据总线上读出。,8,(3)数据存储器MMR 这类指令有:MVDM dmad,MMR;指令的字数/执行周期 2/2MVMD MMR,dmad;dmad=MMR 2/2MVMM mmrx,mmry;mmry=mmrx 1/1(4)程序存储器(Acc)数据存储器 包括:READA Smem;Smem=prog(A)1/5WRITA Smem;prog(A)=Smem 1/5 mmrx,

5、mmry为AR0AR7或SP;MMR为任何一个存储器映象寄存器;,9,例5-6 将数组x5 初始化为1,2,3,4,5。.data;定义初始化数据段起始地址TBL:.word 1,2,3,4,5;为标号地址TBL;开始的5个单元赋初值.sect“.vectors”;定义自定义段,并获;得该段起始地址 B START;无条件转移到标号为START的地址.bss x,5;为数组x分配5个存储单元.text;定义代码段起始地址START:STM#x,AR5;将x的首地址存入AR5 RPT#4;设置重复执行5次下条指令 MVPD TBL,*AR5+;将TBL开始的5个值传给x,(1)程序存储器数据存储

6、器,10,例5-7 将数据存储器中的数组x10复制到数组y10。.title“cjy1.asm”;为汇编源程序取名.mmregs;定义存储器映象寄存器STACK.usect“STACK”,30H;设置堆栈.bss x,10;为数组x分配10个存储单元.bss y,10;为数组y分配10个存储单元.datatable:.word 1,2,3,4,5,6,7,8,9,10.def start;定义标号start.text,(2)数据存储器数据存储器,11,start:STM#0,SWWSR;复位SWWSR STM#STACK+30H,SP;初始化堆指针 STM#x,AR1;将目的地首地址赋给AR1

7、 RPT#19;设定重复传送的次数为20次 MVPD table,*AR1+;程序存储器传送到数;据存储器 STM#x,AR2;将x的首地址存入AR2 STM#y,AR3;将y的首地址存入AR3 RPT#19;设置重复执行20次下条指令 MVDD*AR2+,*AR3+;将地址x开始的20个值;复制到地址y开始的20个单元end:B end.end,12,用间接寻址方式获得操作数,且辅助寄存器只用AR2AR5;占用程序空间小;运行速度快。,4双操作数乘法,特点,例5-8 编制求解 的程序。利用双操作数指令可以节省机器周期。迭代次数越多,节省的机器周期数也越多。本例中,在每次循环中,双操作数指令都

8、比单操作数指令少用一个周期,节省的总机器周期数=1T*N(迭代次数)=NT。,13,单操作数指令方案 双操作数指令方案 LD#0,B LD#0,B STM#a,AR2 STM#a,AR2 STM#x,AR3 STM#x,AR3 STM#19,BRC STM#19,BRC RPTB done-1 RPTB done-1 LD*AR2+,T;1T MPY*AR2+,*AR3+,A;1T MPY*AR3+,A;1T ADD A,B;1T ADD A,B;1Tdone:STH B,y done:STH B,y STL B,y+1 STL B,y+1,14,在单个周期内同时利用C总线和D总线,得到32位

9、操作数。,5长字运算,特点,使用长操作数指令时,按指令中给出的地址存取的总是高16位操作数。这样,有两种数据排列方法:(1)偶地址排列法 指令中给出的地址为偶地址,存储器中低地址存放高16位操作数。如:DLD*AR3+,A执行前:A=00 0000 0000 执行后:A=00 6CAC BD90 AR3=0100 AR3=0102(0100h)=6CAC(高字)(0100h)=6CAC(0101h)=BD90(低字)(0101h)=BD90,15,(2)奇地址排列法 指令中给出的地址为奇地址,存储器中低地址存放低16位操作数。如:DLD*AR3+,A执行前:A=00 0000 0000 执行后

10、:A=00 BD90 6CAC AR3=0101 AR3=0103(0100h)=6CAC(低字)(0100h)=6CAC(0101h)=BD90(高字)(0101h)=BD90推荐采用偶地址排列法,将高16位操作数放在偶地址存储单元中。如:程序存储器.long 12345678 h;偶地址:1234;奇地址:5678 数据存储器.bss xhi,2,1,1;偶地址:xhi;奇地址:xlo 变量名称 字长 页邻接 偶地址排列法,16,例5-9 计算Z32=X32+Y32。标准运算 长字运算 LD xhi,16,A DLD xhi,A ADDS xlo,A DADD yhi,A ADD yhi,

11、16,A DST A,zhi ADDS ylo,A(3个字,3个T)STH A,Zhi STL A,Zlo(6个字,6个T),17,(1)并行运算指同时利用D总线和E总线。其中,D总线用来执行加载或算术运算,E总线用来存放先前的结果。(2)并行指令都是单字单周期指令。(3)并行运算时所存储的是前面的运算结果,存储之后再进行加载或算术运算。(4)并行指令都工作在累加器的高位。(5)大多数并行运算指令都受累加器移位方式ASM位影响。,6并行运算,特点,18,表5-1 并行指令举例,19,例5-10 编写计算z=x+y和f=d+e的程序段。在此程序段中用到了并行存储/加载指令,即在同一机器周期内利用

12、E总线存储和D总线加载。数据存储器分配如图5-4所示。.title“cjy3.asm”.mmregsSTACK.usect“STACK”,10H.bss x,3;为第一组变量;分配3个存储单元.bss d,3;为第二组变量;分配3个存储单元.def start.datatable:.word 0123H,1027H,0,1020H,0345H,0,20,.text start:STM#0,SWWSR STM#STACK+10H,SP STM#x,AR1 RPT#5 MVPD table,*AR1+STM#x,AR5;将第一组变量的首地址传给AR5 STM#d,AR2;将第二组变量的首地址传给A

13、R2 LD#0,ASM;设置ASM=0 LD*AR5+,16,A;将x的值左移16位放入A的高端字 ADD*AR5+,16,A;将y值左移16位与A的高端字x相加 ST A,*AR5;将A中的和值右移16位存入z中 LD*AR2+,B;将d的值左移16位放入B的高端字 ADD*AR2+,16,B;将e值左移16位与B的高端字d相加 STH B,*AR2;将B的高端字中的和值存入f中end:B end.end,21,764位加法和减法运算,例5-11 编写计算Z64=W64+X64-Y64的程序段。这里的W、X、Y和结果Z都是64位数,它们都由两个32位的长字组成。利用长字指令可以完成64位数的

14、加/减法。w3 w2 w1 w0(W64)+x3 x2 C x1 x0(X64)低32位相加产生进位C-y3 y2 C y1 y0(Y64)低32位相减产生借位C_ z3 z2 z1 z0(Z64),22,DLD w1,A;A=w1w0DADD x1,A;A=w1w0+x1x0,产生进位CDLD w3,B;B=w3w2ADDC x2,B;B=w3w2+x2+CADD x3,16,B;B=w3w2+x3x2+CDSUB y1,A;A=w1w0+x1x0-y1y0,产生借位CDST A,z1;z1z0=w1w0+x1x0-y1y0SUBB y2,B;B=w3w2+x3x2+C-y2-CSUB y3

15、,16,B;B=w3w2+x3x2+C-y3y2-CDST B,z3;z3z2=w3w2+x3x2+C-y3y2-C由于没有长字带进(借)位加/减法指令,所以上述程序中只能用16位带进(借)位指令ADDC和SUBB。,23,8.32位乘法运算,x1 x0 S U y1 y0 S U_ _ x0*y0 U*U y1*x0 S*U x1*y0 S*Uy1*x1 S*S_ _w3 w2 w1 w0 S U U U,例5-12 编写计算W64=X32*Y32的程序段。32位乘法算式如下:,图5-5,24,其中,S为带符号数,U为无符号数。数据存储器分配如图5-5所示。在32位乘法运算中,实际上包括了三

16、种乘法运算:U*U、S*U和S*S。一般的乘法运算指令都是两个带符号数相乘,即S*S。所以,在编程时,要用到以下三条乘法指令:MACSU Xmem,Ymem,src;无符号数与带符号数相乘并累加;src=U(Xmem)*S(Ymem)+src MPYU Smem,dst;无符号数相乘;dst=U()*U(Smem)MAC Xmem,Ymem,src;两个符号数数相乘并累加;src=S(Xmem)*S(Ymem)+src32位乘法的程序段如下:,25,STM#x0,AR2;将x的首地址放入AR2 STM#y0,AR3;将y的首地址存入AR3 LD*AR2,T;T=x0 MPYU*AR3+,A;A

17、=ux0*uy0 STL A,w0;w0=ux0*uy0 LD A,-16,A;A=A16 MACSU*AR2+,*AR3-,A;A+=y1*ux0 MACSU*AR3+,*AR2,A;A+=x1*uy0 STL A,w1;w1=A LD A,-16,A;A=A16 MAC*AR2,*AR3,A;A+=x1*y1 STL A,w2;w2=A的低16位 STH A,W3;w3=A的高16位,26,9小数运算,整数运算的问题(1)两个16位整数相乘,乘积总是“向左增长”。这意味着多次相乘后,乘积将会很快超出定点器件的数据范围。(2)保存32位乘积到存储器,要开销2个机器周期以及2个字的存储器单元。

18、(3)由于乘法器都是16位相乘,因此很难在后续的递推运算中,将32位乘积作为乘法器的输入。小数运算的优点(1)乘积总是“向右增长”。这就味着超出定点器件数据范围的将是不太感兴趣的部分。(2)既可以存储32位乘积,也可以存储高16位乘积,这就允许用较少的资源保存结果。(3)可以用于递推运算。,小数运算与整数运算的比较,27,C54x采用2的补码表示小数,其最高位为符号位,数值范围从-11。一个16位2的补码小数(Q15格式)的每一位的权值为:MSB(最高位)LSB(最低位)-1.1/2 1/4 1/8 2-15一个十进制小数乘以32768之后再将其十进制整数部分转换成十六进制数,就能得到这个十进

19、制小数的2的补码表示了。1 7FFFh0.5正数:乘以32768 4000h0 0000h-0.5 负数:其绝对值部分乘以32768,再取反加1 C000h-1 8000h,(1)小数的表示方法,28,在汇编语言中,是不能直接写入十进制小数的,可写为整数运算式。如果要定义一个系数0.707,可以写成:.word 32768*707/1000不能写成32768*0.707。,注意,Q格式表示法,在Q格式中,Q之后的数字(如Q15格式中的15)决定小数点右边有多少位二进制位,故Q15表示在小数点后有15位小数。当用一个16位的字来表示Q15格式时,在MSB(最高位)的右边有一个小数点,而MSB表示

20、符号位。所以Q15的表示数字可表示范围从+1(以+0.999997表示)到-1的值。,29,通过合适的Q格式,可以把数值根据所需的精确度做适当地转换,以便定点数的DSP也可以处理高精度的浮点数。下面以Q15为例,说明转换的过程。1)先确定准备转换的十进制数值N,是在Q15格式的数值范围之间,即-1.000000N+0.999997。2)数值N乘以215,即N=N215=N327683)把步骤2)的结果加216,即N=N+216=N+65536。4)步骤3)的结果转换成十六进制,并把第17位舍弃掉,得到的结果就是N的Q15转换值。,30,下面通过把-0.2345及+0.2345转换成Q15格式来

21、说明转换方法。-0.2345的转换为:-0.234532768=-7684.1-7684-7684+65536=5785257852转换成十六进制数值为0E1FCh,所以结果为E1FCh。+0.2345的转换为:0.234532768=7684.176847684+65536=7332073320转换成十六进制数值为11E04h,并把第17位舍弃掉,结果为1E04h。,31,以字长为4位和8位累加器为例,先看一个小数乘法的例子。0 1 0 0(0.5230.5=(4)10=(0100)2)1 1 0 1(-0.37523(-0.375)=(-3)10 0 1 0 0=(1101)补)0 0 0

22、 0 0 1 0 01 1 0 0(-0100)1 1 1 0 1 0 0(-0.1875=-12/26-12=(1110100)补),(2)小数乘法与冗余符号位,32,上述乘积是7位,当将其送到8位累加器时,为保持乘积的符号,必须进行符号位扩展,这样,累加器中的值为11110100(-0.09375=-12/27),出现了冗余符号位。原因是:S x x x(Q3)S y y y(Q3)S S z z z z z z(Q6格式)即两个带符号数相乘,得到的乘积带有2个符号位,造成错误的结果。同样,对于两个十六位数相乘,乘积只有30位,在最高的两位也是符号位,同样会造成错误的结果。,33,解决冗余

23、符号的办法是:在程序中设定状态寄存器ST1中的FRCT(小数方式)位1,在乘法器将结果传送至累加器时就能自动地左移1位,累加器中的结果为:zzzzzz0(Q7格式),即11101000(-0.1875=-24/27-24=(11101000)补),自动地消去了两个带符号数相乘时产生的冗余符号位。所以在小数乘法编程时,应当事先设置FRCT位:SSBX FRCT MPY*AR2,*AR3,ASTH A,Z这样,C54x就完成了Q15*Q15=Q15的小数乘法。,34,例5-13 编制计算 的程序段,其中数据均为小数:a1=0.1,a2=0.2,a3=-0.3,a4=0.4,x1=0.8,x2=0.

24、6,x3=-0.4,x4=-0.2。.title“cjy4.asm”.mmregsSTACK.usect“STACK”,10H.bss a,4;为a分配4个存储单元.bss x,4;为x分配4个存储单元.bss y,1;为结果y分配1个存储单元.def start.data;定义数据代码段,35,table:.word 1*32768/10;在table开始的8个.word 2*32768/10;地址放数据.word-3*32768/10.word 4*32768/10.word 8*32768/10.word 6*32768/10.word-4*32768/10.word-2*32768/1

25、0,36,.text;定义可执行程序代码段start:SSBX FRCT;设置FRCT位,表示进行小数乘 STM#x,AR1;将x的首地址传给AR1 RPT#7;重复8次下条指令 MVPD table,*AR1+;将程序空间8个数传给数据存储器 STM#x,AR2;将数据存储器第一个数x1的地址传给AR2 STM#a,AR3;将数据存储器第五个数a1的地址传给AR3 RPTZ A,#3;将A清零,重复4次下条指令 MAC*AR2+,*AR3+,A;执行乘法累加和,结果放在A中 STH A,y;将A的高端字存入结果y,低端字省去end:B end;原处循环等待.end 结果y=0 x1EB7。转

26、换为十进制数:y=(1163+14162+11161+7160)/32768=0.24,37,10 除法运算,条件减法指令的功能如下:SUBC Smem,src;(src)-(Smem)15 ALU;输出端,如果ALU输出端0,;则(ALU输出端)1+1src,;否则(src)1src。,方法:减法指令加重复指令实现无符号运算,(1)当被除数除数 此时商为小数。,38,例5-14 编写0.4(-0.8)的程序段。.title“cjy5.asm”.mmregsSTACK.usect“STACK”,10H.bss num,1;为分子分配单元.bss den,1;为分母分配单元.bss quot,1

27、;为商分配单元.data;定义数据段起始地址table:.word 4*32768/10;在以table为地址的;单元放入 0.4.word-8*32768/10;在以table为地址的;下一单元放入-0.8.def start,39,.text;定义数据段起始地址start:STM#num,AR1;将分子所在单元的地址传给AR1 RPT#1;重复执行下一指令2次 MVPD table,*AR1+;传送程序空间的2个数据(分子、;分母)至地址为num开始的数据存储器单元 LD den,16,A;将分母移到累加器A(3116)MPYA num;(num)*(A(3116)B,;获取商的符号(在累

28、加器B中)ABS A;分母取绝对值 STH A,den;分母绝对值存回原处 LD num,16,A;分子加载到A(3116)ABS A;分子取绝对值 RPT#14;15次减法循环,完成除法 SUBC den,A;XC 1,BLT;如果B0(商是负数),则需要变号 NEG A;如果B0执行求反,否则跳过此指令 STL A,quot;保存商end:B end.end,40,a)被除数除数商为小数 b被除数除数商为整数,41,10 除法运算,(2)当被除数除数时 商为整数。,例5-15 编写16384512的程序段。将上例程序段仅作两处修改,其它不变,就得本例的程序段:LD num,16,A 改成

29、LD num,ARPT#14 改成 RPT#15本例的程序段为:.title“cjy6.asm”.mmregsSTACK.usect“STACK”,10H,42,.bss num,1;为分子分配单元.bss den,1;为分母分配单元.bss quot,1;为商分配单元.data;定义数据段起始地址table:.word 66*32768/100;在以table为地址;的单元放入16384.word-33*32768/100;在以table为地址;的下一单元放入512.def start.text;定义数据段起始地址start:STM#num,AR1;将分子所在单元地址传给AR1 RPT#1;

30、重复执行下一指令2次 MVPD table,*AR1+;传送程序空间的2;数据(分子、分母)至地址为;num开始的数据存储器单元,43,LD den,16,A;将分母移到累加器A(3116)MPYA num;(num)*(A(3116)B,;获取商的符号(在累加器B中)ABS A;分母取绝对值 STH A,den;分母绝对值存回原处 LD num,A;分子加载到A(150)ABS A;分子取绝对值 RPT#15;16次减法循环,完成除法 SUBC den,A;XC 1,BLT;如果B0(商是负数),则需要变号 NEG A;如果B0执行求反,否则跳过此指令 STL A,quot;保存商end:B

31、 end.end;结果为quot=0 x0020=32。,44,第二节 DSP的浮点运算方法,1浮点数的表示方法,(1)C54x 本身是定点DSP芯片;(2)用定点DSP芯片进行浮点数运算,必须先将定点数转换为浮点数。,要点,浮点数表示定点数,采用尾数和指数两部分来表示,定点数=尾数2-(指数)或 x=m2e,45,2定点数转换成浮点数,这是一条提取指数的指令,所提取的指数保存在T寄存器中。如果累加器A=0,则0T;否则,累加器A的冗余符号位数减8T。累加器A中的内容不变。,转换要点,(1)先将定点数放在累加器A或B中,然后用指令:EXP A 或EXP B。,注意,由于C54x DSP用16位

32、表示数字,其对浮点数的表示与IEEE 754-1985标准的32位表示法略有不同。采用一个单元保存指数和一个单元保存尾数的两个16位表示法。,46,例5-16 提取A=FF FFFF FFCB中的指数值。执行指令:EXP A 执行前 执行后 A=FF FFFF FFCB A=FF FFFF FFCB T=0000 T=0019(25)本例中,由于A0,需要先求出A的冗余符号位并减去8。A=F F F F F F F F C B 1111 1111 1111 1111 1111 1111 1111 1111 1100 1011 33位冗余符号位1,33-8=25=0 x0019,47,例5-17

33、 提取B=07 8543 2105中的指数值。执行指令:EXP B 执行前 执行后 B=07 8543 2105 B=07 8543 2105 T=0007 T=FFFC(-4)本例中,由于B0,需要先求出B的冗余符号位并减去8。A=0 7 8 5 4 3 2 1 0 5 0000 0111 1000 0101 0100 0011 0010 0001 0000 0101 4位冗余符号位0,4-8=-4=0 xFFFC-4=-(0 x0004)=(1111 1111 1111 1011+1)补=(0 xFFFC)补,48,(2)使用指令 ST T,EXPONENT,将保存在T寄存器中的指数存放到

34、数据存储器的指定单元EXPONENT中。如 EXP AST T,e1;将指数存入数据存储器;e1所指定的单元中。,转换要点,(3)使用指令NORM A。,按寄存器中的内容对累加器A进行归一化处理。这里的将定点数转换成浮点数所进行的归一化处理,指通过左移或右移,使一个二进制数变为一个小数,且小数点后的第一个数不为零,移动的位数用指数表示。,49,例如:0.3=(0.010011)22-0=(0.10011)22-1,-0.8=-0.82-0=-(0.110011)22-0,-0.24=-(0.001111)2-0=-(0.1111)22-2。3=(11)22-0=(0.11)222-8=-(10

35、00)22-0=-(0.1)224-24=-(11000)22-0=-(0.11)225,上例中,对于小数,当转换成小数点后第一位为1的归一化数时,通过将小数点右移实现,指数为负数。对于整数,则将小数点左移实现,指数搂正数。,50,例5-18 对累加器A进行归一化处理。执行指令:NORM A执行前 执行后A=FF FFFF F001 A=FF 8008 0000T=0013 T=0013(19)执行时,按T中的十进制数值,这里为正19,对累加器A中的值左移19位,即将在A=FF FFFF F001中的值左移19位,低位添零,高位溢出丢弃。A=(1111 1111 1111 1111 1111

36、1111 1111 0000 0000 0001)21111 1111 1111 1111 1111 1111 1111 0000 0000 0001 0000 0000 0000 0000 000左移出去掉的19位 左移进19位添0(1111 1111 1000 0000 0000 1000 0000 0000 0000 0000)2=(FF 8008 0000)16,51,例5-19 对累加器B中的值进行归一化处理后存入A。执行指令:NORM B,A执行前 执行后A=FF FFFF F001 A=00 4214 1414B=21 0A0A 0A0A B=21 0A0A 0A0AT=FFF9

37、 T=FFF9(-7)将B移-7位,即右移7位:B=(0010 0001 0000 1010 0000 1010 0000 1010 0000 1010)2 0000 000 0010 0001 0000 1010 0000 1010 0000 1010 0000 1010右移进7位添0 去掉移出的7位(0000 0000 0100 0010 0001 0100 0001 0100 0001 0100)2=(00 4214 1414)16,52,3浮点数转换成定点数,转换要点,在将浮点数转换成定点数时,按指数值将尾数右移(指数为负时左移)即可。其操作与定点数转换为浮点数相反。这种相反方向的移位

38、是通过对指数取反实现的。,使用指令 NEG A NORM A,53,如指数在A中,尾数在x中,则将浮点数转换成定点数的指令为:NEG A;指数反号STL A,temp;将指数暂存在数据存储单元中LD temp,T;将指数装入T寄存器LD x,16,A;将尾数装入A的高16位NORM A;将尾数按T移位,由于T中的指数;是已经取反了的,所进行的移;位为反向移位。转换后的定点;数在A中。,54,例5-20 编写浮点乘法程序,完成x1x2=0.3(-0.8)运算。程序清单为:.title“float.asm”;程序名.def start;定义标号STACK:.usect“STACK”,100;设置堆

39、栈.bss x1,1;为被乘数x1预留1个单元的空间.bss x2,1;为乘数x2预留1个单元的空间.bss e1,1;为被乘数的指数e1预留1个单元空间.bss m1,1;为被乘数的尾数m1预留1个单元空间.bss e2,1;为乘数的指数e2预留1个单元的空间.bss m2,1;为乘数的尾数m2预留1个单元的空间.bss ep,1;为乘积的指数ep预留1个单元的空间.bss mp,1;为乘积的尾数mp预留1个单元的空间.bss product,1;为乘积留空间.bss temp,1;为暂存留空间,55,.data;定义数据段table:.word 3*32768/10;设初值 0.3.wor

40、d-8*32768/10;设初值-0.8.text;定义代码段start:STM#STACK+100,SP;设置堆栈指针初值 MVPD table,x1;送0.3、-0.8 MVPD table+1,x2;至数据存储器 LD x1,16,A;将x1送到A EXP A;取A中指数 ST T,e1;存指数到e1 NORM A;对A归一化 STH A,m1;存尾数到m1 LD x2,16,A;将x2送到A EXP A;提取A中指数,放入T ST T,e2;保存x2的指数到e2 NORM A;对累加器A归一化 STH A,m2;保存x2的尾数到m2 CALL MULT;调用浮点乘法子程序 end:B

41、end;循环等待,得0.3的浮点数,-0.8的浮点数,56,MULT:SSBX FRCT;设置小数乘法运算 SSBX SXM;数据进入ALU之前进行符号位扩展 LD e1,A;x1指数送A ADD e2,A;x2与x1指数相加 STL A,ep;乘积指数存入ep LD m1,T;x1尾数送T MPY m2,A;x1与x1尾数相乘,结果在A中 EXP A;提取A中指数,放入T ST T,temp;尾数乘积中提取的指数存入temp NORM A;对累加器A进行归一化处理 STH A,mp;保存提取指数后的尾数在mp中 LD temp,A;修正乘积指数,尾数乘积指数送A ADD ep,A;(ep)+

42、(temp)STL A,ep;保存乘积指数在ep中 NEG A;将浮点数乘积转换成定点数 STL A,temp;乘积指数反号后存入temp LD temp,T;并加载到T寄存器,对积求指数并归一化,57,LD mp,16,A;将乘积的尾数装入A的高16位NORM A;将尾数按T中的指数移位STH A,product;保存定点乘积到product中RET;返回.end,程序执行结果为:0.3(-0.8)乘积的浮点数尾数0 x8520,指数为0 x0002。乘积的定点数为0 xE148,对应的十进制数为-0.23999。程序执行后数据存储器中的数据值如图5-8所示。,58,第三节 DSP在信号发生

43、器上的应用,1.一个角度正弦值的计算,要点,按C54x系列采用的Q15格式,将转换为十进制小数的2的补码形式为:=0.785432768=6487h弧度。再将要计算的值放在d_x单元中,计算结果放在d_sinx单元中。,59,60,.title“sinx.asm”;为程序取名.mmregs;定义存储器映象寄存器.def start;定义标号start.ref sin_start,d_x,d_sinx;引用别处定义的;sin_start,d_x,d_sinxSTACK:.usect“STACK”,10;设置堆栈空间的大小和起始位置 start:STM#STACK+10,SP;设置堆栈指针初始指向

44、的栈底位置 LD#d_x,DP;设置数据存储器页指针的起始位置 ST#6487h,d_x;将值送入地址为d_x的单元中 CALL sin_start;调用计算正弦值的子程序end:B end;循环等待sin_start:.def sin_start;定义标号sin_start的起始位置d_coeff.usect“coeff”,4;定义4个单元的未初始化段coeff,61,.datatable:.word 01c7h;在程序空间定义4个系数,c1=1/(8*9).word 030bh;c2=1/(6*7).word 0666h;c3=1/(4*5).word 1556h;c4=1/(2*3)d_

45、x.usect“sin_vars”,1;在自定义的未初始化段sin_vars中d_squr_x.usect“sin_vars”,1;保留5个单元的的空间,它们通常d_temp.usect“sin_vars”,1;被安排在RAM中,用于暂存变量d_sinx.usect“sin_vars”,1 c_1.usect“sin_vars”,1.text;完成正弦计算的可执行代码段SSBX FRCT;设置进行小数乘法,以便自动左移一位 STM#d_coeff,AR5;将4个系数的首地址d_coeff 送AR5,62,RPT#3;重复执行下一指令4次,以便将程序空MVPD#table,*AR5+;间的4个系

46、数传送到数据空间d_coeffSTM#d_coeff,AR3;将系数所在空间d_coeff首地址送AR3STM#d_x,AR2;将所在地址送AR2STM#c_1,AR4;将小数的最大值7fff地址c_1送AR4ST#7FFFh,c_1;将#7FFFh(即整数1)送c_1SQUR*AR2+,A;A=x2,AR2指向d_squr_xST A,*AR2;d_squr_x=x2(A右移16位,即存高字节)LD*AR4,B;B=1(7FFFh左移16位放在B的高字节)MASR*AR2+,*AR3+,B,A;A=1-x2/72,T=x2,AR2指向d_temp,;AR3指向c2(凑整运算为结果加215再对

47、15-0位清0)MPYA A;A=T*A=x2(1-x2/72)STH A,*AR2;(d_temp)=x2(1-x2/72)MASR*AR2-,*AR3+,B,A;A=1-x2/42(1-x2/72);T=x2(1-x2/72),63,MPYA*AR2+;B=x2(1-x2/42(1-x2/72)ST B,*AR2;(d_temp)=x2(1-x2/42(1-x2/72)LD*AR4,B;B=1MASR*AR2-,*AR3+,B,A;A=1-x2/20(1-x2/42(1-x2/72)MPYA*AR2+;B=x2(1-x2/20(1-x2/42(1-x2/72)ST B,*AR2;(d_te

48、mp)=B=x2(1-x2/20(1-x2/42(1-x2/72)LD*AR4,B;B=1MASR*AR2-,*AR3+,B,A;A=1-x2/6(1-x2/20(1-x2/42(1-x2/72)MPYA d_x;B=x(1-x2/6(1-x2/20(1-x2/42(1-x2/72)STH B,d_sinx;sin(theta)RET.end,64,2.用z变换计算余弦值,下面采用z变换和反z变换来求cos(x),其的方法为:根据z变换定义,序列x(n)的变换公式为:,反z变换为x(n)=-1X(z)可用留数法、部分分式展开法和长除法求得。则cos(0n)u(n)的z变换为:H(z)=cos(

49、n)u(n)=ej0n+e-j0nu(n),65,其中C-cos0,A=2cos0T,B=-1。0为余弦输出信号的频率,T为离散余弦序列的采样频率。如果以该函数设计一离散时间系统,为则其单位冲击响应就是余弦输出信号。此时的输出序列Y(k)为H(z)的反z变换。,66,Y(k)=-1H(z)=AYk-1+BYk-2+Xk+CXk-1当k=-1时Y(k)=Y(-1)=AY-2+BY-3+X-1+CX-2=0当k=0时 Y(k)=Y(0)=AY-1+BY-2+X0+CX-1=0+0+1+0=1当k=1时 Y(k)=Y(1)=AY0+BY-1+X1+CX0=1+0+0+C=A+C当k=2时 Y(k)=

50、Y(2)=AY1+BY0+X2+CX1=AY1+BY0当k=3时 Y(k)=Y(3)=AY2+BY1+X3+CX2=AY2+BY1当k=n时 Y(k)=Y(n)=AYn-1+BYn-2在k2以后,Y(k)能用Yk-1和Yk-2算出,这是一个递归的差分方程。如果按第七章实验二的方式产生余弦信号,对应的初始化程序为:,初始化y1和y2:SSBX FRCT;置FRCT=1,准备进行小数乘法运算ST#INIT_A,AA;将常数A装入变量AAST#INIT_B,BB;将常数B装入变量BBST#INIT_C,CC;将常数C装入变量CC,67,PSHD CC;将变量CC压入堆栈POPD Y2;初始化Y2=C

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号