【DSP学习笔记】定点DSP⼩数乘加计算(转)
由于我装的版本是CCS5.5,此版本只⽀持C55系列的软件仿真⽽不⽀持C54系列的软件仿真,所以本次试验我采⽤TMS320C5510芯⽚进⾏,新建⼯程的过程这⾥不再赘述。
以下分别采⽤汇编语⾔和C语⾔编写⼀个最简单的定点DSP程序 ,计算式⼦:y=0.1*1.2+35*20+15*1.6结果的值。
1、操作数表⽰
在定点DSP芯⽚中,采⽤定点进⾏数值计算,其操作数⼀般采⽤整数来表⽰。⼀个整数型的最⼤表⽰范围取决于DSP芯⽚所能给的字长,⼀般为16位或者24位。字长越长,所能表⽰的范围越⼤,精度也越⾼。
数学运算中的数字不⼀定是整数。定点DSP⽆法直接处理⼩数,需要⼈为将⼩数转化为整数进⾏运算。
2、定标
通过设定⼩数点在⼀个字中的不同位置,可以表⽰不同⼤⼩不同精度的⼩数。
3、Q格式运算
·      定点加减法:须转换成相同的Q格式才能加减;
·      定点乘法:不同Q格式的数据相乘,相当于Q值相加;
·      定点除法:不同Q格式的数据相除,相当于Q值相减;
·      定点左移:左移相当于  Q值增加;
·      定点右移:右移相当于  Q值减少;
不同的Q值所表⽰的数的范围不同,精度也不同。Q值越⼤,数值范围越⼩,但精度越⾼;相反,Q值越⼩,数值的范围越⼤,精度越低。例如:对于16位字长来说,Q0的数值范围是-32768到+32767,其精度为1,⽽Q15的数值范围为-1到0.9999695,精度为
1/32768=0.00003051。对于定点数来说,数值范围与精度是⼀对⽭盾。
4、浮点数与定点数的转换关系
浮点数(x)转换为定点数(Xq):
定点数(Xq)转换为浮点数(x):
例如,浮点数x=0.25,定标Q=15,则定点数,反之,⼀个⽤Q=15表⽰的定点数为8192,则其浮点数为
支持小数点的进制转换器
5、加法计算
设x的Q值为Qx,y的值为Qy,且Qx>Qy,加法结果的定标值为Qz,则对于有:
6、乘法运算
设x的Q值为Qx,y的值为Qy,且Qx>Qy,加法结果的定标值为Qz,则对于z=xy,可得到:
7、汇编程序设计如下(注意以下程序均是基于TMS320C5510芯⽚编写)
.text
.bss x,4
.globalstart
start:
MOV #0066h,AC0H ;设置Q=10    ;x1=0.1 Q=10 =>0.1*2^10=102 =>66H ,放到累加器⾼16位(31~16),最⾼的8位为保护位
MOV #04CDh,AC1H ;设置Q=10    ;x2=1.2 Q=10 =>1.2*2^10 =>04CDH
MPY AC1,AC0            ;C55x系列指令 :AC0=AC0(31~16)*AC1(32~16)
MOV #0460h,AC1H ;设置Q=5
MOV #0280h,AC2H ;设置Q=5
MPY AC2,AC1
MOV #3C00h,AC2H ;Q=10
MOV #0666h,AC3H ;Q=10
MPY AC3,AC2
SFTSC AC0,#-10,AC0  ;C55x累加器移位指令。这⾥设置结果Q=10,将AC0的内容左移10位,保证 结果Q=10
SFTSC AC2,#-10,AC2  ;移位 AC2=AC2<<10
ADD AC0,AC1                    ;求和
ADD AC2,AC1                    ;求最终的结果
说明:在此代码中,设置数据0.1和1.2的Q值为10,设置35和20的Q值为5,设置15和1.6的Q值为10。设置计算结果的Q值为10。
提醒:DSP汇编语⾔需要注意格式问题,该顶格写的语句⼀定不能敲空格,⽐如以上程序的start语句。可以随便修改尝试。
8、汇编语⾔调试过程
注意调试前需要先在需要查看的语句前设置断点。
执⾏第⼀个MPY语句后各个累加器的值:
执⾏第⼆个MPY指令后各个累加器的值:
执⾏第三个MPY指令后各个累加器的值 :
最终结果如下:
计算结果放在累加器AC1中,此处的值为0B5074h,结果设置的Q值为10,则对应的⼗进制为AC1=0B5074H=741492D,实际的数据结果为 ,和实际724.12结果接近。
9、为⽐较结果,采⽤C语⾔编写
源代码如下:
/*
* main.c
*/
int main(void) {
long x1=102;    //x1=0.1Q=10 =>0.1*2^10=102 =>66H
long x2=1229;    //x2=1.2 Q=10 =>1.2*2^10
long x3=1120;    //x3=35  Q=5  =>35*2^5    ;整数的Q值的设置只需要保证计算结果不超出数据范围即可
long x4=640;    //x4=20Q=5  =>20*2^5 ;整数的Q值的设置只需要保证计算结果不超出数据范围即可
long x5=15360;  //x5=15 Q=10 =>15*2^10 ;整数的Q值的设置只需要保证计算结果不超出数据范围即可
long x6=1638;    //x6=1.6 Q=10 =>1.6*2^10
long y1,y2,y3;    //存储各部分值,在这⾥设置结果的Q值为10
long result;  //存储求和结果,在这⾥设置结果的Q值为10
y1=(x1*x2)>>(10+10-10);  //y1计算结果Q=10,移位操作是为了保证Q值为10,⽅便求result
y2=(x3*x4)>>(5+5-10);      //y2计算结果Q=10
y3=(x5*x6)>>(10+10-10);  // y3计算结果Q=100
result=y1+y2+y3;        //result计算结果Q=10
return 0;
}
为了和汇编程序运⾏结果⽐较,所以我再次在这⾥设置设置数据0.1和1.2的Q值为10,设置35和20的Q值为5,设置15和1.6的Q值为10。设置计算结果的Q值为10。
10、C语⾔调试过程
Y1移位前累加器结果:
Y2移位后累加器结果:
Y2最终结果放在累加器AC0:
Y3最终结果放在AC0中如下图:
求得最终结果如下图:
最终结果放在AC0中,可以发现最终结果和⽤汇编语⾔测试结果完全相同,都为0B5074h,因为Q=10,则对应的值为724.113。测试结果正确。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。