C语言16位定标,DSP定标方法
DSP定标方法
分类:DSP设计2007/09/27 22:57
DSP定标方法
length;i++)
{
sum=0;
for(j=0;jxout[i]=sum>>15;
}
for(i=0;i}
主程序与浮点的完全一样.
3.3 DSP定点算术运算
定点DSP芯片的数值表示是基于2的补码表示形式.每个16位数用1个符号位、i个整数位和15-i个小数位来表示.因此数00000010.10100000表示的值为 =2.625,这个数可用Q8格式(8个小数位)来表示,它表示的数值范围为-128~+127.996,一个Q8定点数的小数精度为1/256=0.004.
虽然特殊情况(如动态范围和精度要求)必须使用混合表示法,但是,更通常的是全部以Q15格式表示的小数或以Q0格式表示的整数来工作.这一点对于主要是乘法和累加的信号处理算法特别现实,小数乘以小数得小数,整数乘以整数得整数.当然,乘积累加时可能会出现溢出现象,在这种情况下,程序员应当了解数学里面的物理过程以注意可能的溢出情况.下面讨论乘法、加法和除法的DSP定点运算,汇编程序以TMS320C25为例.
3.3.1 定点乘法
2个定点数相乘时可以分为下列3种情况:
1.小数乘小数
Q15×Q15=Q30
例3.9 0.5*0.5 = 0.25
0.100000000000000 ;Q15
× 0.100000000000000 ;Q15
00.010000000000000000000000000000=0.25 ;Q30
2个Q15的小数相乘后得到1个Q30的小数,即有2个符号位.一般情况下相乘后得到的满精度数不必全部保留,而只需保留16位单精度数.由于相乘后得到的高16位不满15位的小数精度,为了达到15位精度,可将乘积左移1位,下面是上述乘法的TMS320C25程序:
LT OP1 ;OP1=4000H(0.5/Q15)
MPY OP2 ;OP2=4000H(0.5/Q15)
PAC
SACH ANS,1 ;ANS=2000H(0.25/Q15)
2.整数乘整数
Q0×Q0 = Q0
例3.10 17×(-5)=-85
0000000000010001=17
× 1111111111111011=-5
11111111111111111111111110101011=-85
3.混合表示法
许多情况下,运算过程中为了既满足数值的动态范围又保证一定的精度,就必须采用Q0与Q15之间的表示法.比如,数值1.2345,显然Q15无法表示,而若用Q0表示,则最接近的数是1,精度无法保证.因此,数1.2345最佳的表示法是Q14.
例3.11 1.5×0.75 = 1.125
01.10000000000000 = 1.5 ;Q14
× 00.11000000000000 = 0.75 ;Q14
0001.0010000000000000000000000000 = 1.125;Q28
Q14的最大值不大于2,因此,2个Q14数相乘得到的乘积不大于4.
一般的,若一个数的整数位为 i位,小数位为 j 位,另一个数的整数位为 m 位,小数位为 n 位,则这两个数的乘积为 ( i + m )位整数位和(j + n)位小数位.这个乘积的最高16位可能的精度为( i + m )整数位和(15 - i - m)小数位.
但是,若事先了解数的动态范围,就可以增加数的精度.例如,程序员了解到上述乘积不会大于1.8,就可以用Q14数表示乘积,而不是理论上的最佳情况Q13.例3.11的TMS320C25程序如下:
LT OP1 ;OP1 = 6000H(1.5/Q14)
MPY OP2 ;OP2 = 3000H(0.75/Q14)
PAC
SACH ANS,1 ;ANS=2400H(1.125/Q13)
上述方法为了保证精度均对乘的结果舍位,结果所产生的误差相当于减去1个LSB(最低位).采用下面简单的舍入方法,可使误差减少二分之一.
LT OP1
MPY OP2
PAC
ADD ONE,14 (上舍入)
SACH ANS,1
上述程序说明,不管ANS为正或负,所产生的误差是1/2 LSB,其中存储单元ONE的值为1.
3.3.2 定点加法
乘的过程中,程序员可不考虑溢出而只需调整运算中的小数点.而加法则是一个更加复杂的过程.首先,加法运算必须用相同的Q点表示;其次,程序员或者允许其结果有足够的高位以适应位的增长,或者必须准备解决溢出问题.如果操作数仅为16位长,其结果可用双精度数表示.下面举例说明16位数相加的两种途径.
1.保留32位结果
LAC OP1 ;(Q15)
ADD OP2 ;(Q15)
SACH ANSHI ;(高16位结果)
SACL ANSLO ;(低16位结果)
2.调整小数点保留16位结果
LAC OP1,15 ;(Q14数用ACCH表示)
ADD OP2,15 ;(Q14数用ACCH表示)
SACH ANS ;(Q14)
加法运算最可能出现的问题是运算结果溢出.TMS320提供了检查溢出的专用指令BV,此外,使用溢出保护功能可使累加结果溢出时累加器饱和为最大的整数或负数.当然,即使如此,运算精度还是大大降低.因此,最好的方法是完全理解基本的物理过程并注意选择数的表达方式.
3.3.3 定点除法
在通用DSP芯片中,一般不提供单周期的除法指令,为此必须采用除法子程序来实现.二进制除法是乘法的逆运算.乘法包括一系列的移位和加法,而除法可分解为一系列的减法和移位.下面来说明除法的实现过程.
设累加器为8位,且除法运算为10除以3.除的过程就是除数逐步移位并与被除数比较的过程,在每一步进行减法运算,如果能减则将位插入商中.
(1)除数的最低有效位对齐被除数的最高有效位.
00001010
- 00011000
11110010
(2) 由于减法结果为负,放弃减法结果,将被除数左移一位再减.
00010100
- 00011000
11111000
(3) 结果仍为负,放弃减法结果,被除数左移一位再减.
00101000
- 00011000
00010000
(4) 结果为正,将减法结果左移一位后加1,作最后一次减.
00100001
- 00011000
00001001
(5) 结果为正,将结果左移一位加1得最后结果.高4位代表余数,低4位表示商.
00010011
即商为0011=3,余数为0001=1.
TMS320没有专门的除法指令,但使用条件减指令SUBC可以完成有效灵活的除法功能.使用这一指令的唯一限制是两个操作数必须为正.程序员必须事先了解其可能的运算数的特性,如其商是否可以用小数表示及商的精度是否可被计算出来.这里每一种考虑可影响如何使用SUBC指令的问题.下面给出两种不同情况下的TMS320C25除法程序.
(1) 分子小于分母
DIV_A:
LT NUMERA
MPY DENOM
PAC
SACH TEMSGN ;取商的符号
LAC DENOM
ABS
SACL DENOM ;使分母为正
ZALH NUMERA ;使分子为正
ABS
RPTK 14
SUBC DENOM ;除循环15次
SACL QUOT
LAC TEMSGN
BGEZ A1 ;若符号为正,则完成
ZAC
SUB QUOT
SACL QUOT ;若为负,则商为负
A1: RET
这个程序中,分子在NUMERA中,分母在DENOM中,商存在QUOT中,TEMSGN为暂存单元.
(2) 规定商的精度
DIV_B:
LT NUMERA
MPY DENOM
PAC
SACH TEMSGN ;取商的符号
LAC DENOM
ABS
SACL DENOM ;使分母为正
LACK 15
ADD FRAC
SACL FRAC ;计算循环计数器
LAC NUMERA
ABS ;使分子为正
RPT FRAC
SUBC DENOM ;除循环16+FRAC次
SACL QUOT
LAC TEMSGN
BGEZ B1 ;若符号为正,则完成
ZAC
SUB QUOT
SACL QUOT ;若为负,则商为负
B1: RET
与DIV_A相同,这个程序中,分子在NUMERA中,分母在DENOM中,商存在QUOT中,TEMSGN为暂存单元.FRAC中规定商的精度,如商的精度为Q13,则调用程序前FRAC单元中的值应为13.
3.4 非线性运算的定点快速实现
在数值运算中,除基本的加减乘除运算外,还有其他许多非线性运算,如对数运算、开方运算、指数运算、三角函数运算等,实现这些非线性运算的方法一般有:(1)调用DSP编译系统的库函数;(2)查表法;(3)混合法.下面分别介绍这三种方法.
1.调用DSP编译系统的库函数
TMS320C2X/C5X 的C编译器提供了比较丰富的运行支持库函数.在这些库函数中,包含了诸如对数、开方、三角函数、指数等常用的非线性函数.在C程序中(也可在汇编程序中)只要采用与库函数相同的变量定义,就可以直接调用.例如,在库函数中,定义了以10为底的常用对数log10( ):
#include double log10(double x);
在C程序中按如下方式调用:
float x,y;
x = 10.0;
y = log10(x);
从上例可以看出,库函数中的常用对数log10( )要求的输入值为浮点数,返回值也为浮点数,运算的精度完全可以保证.直接调用库函数非常方便,但由于运算量大,很难在实时DSP中得到应用.
2.查表法
在实时DSP应用中实现非线性运算,一般都采取适当降低运算精度来提高程序的运算速度.查表法是快速实现非线性运算最常用的方法.采用这种方法必须根据自变量的范围和精度要求制作一张表格.显然输入的范围越大,精度要求越高,则所需的表格就越大,即存储量也越大.查表法求值所需的计算就是根据输入值确定表的地址,根据地址就可得到相应的值,因而运算量较小.查表法比较适合于非线性函数是周期函数或已知非线性函数输入值范围这两种情况,例3.12和例3.13分别说明这两种情况.
例3.12 已知正弦函数y=cos(x),制作一个512点表格,并说明查表方法.
由于正弦函数是周期函数,函数值在-1至+1之间,用查表法比较合适.
由于Q15的表示范围为-1至32767/32768之间,原则上讲-1至+1的范围必须用Q14表示.但一般从方便和总体精度考虑,类似情况仍用Q15表示,此时+1用32767来表示.
(1) 产生512点值的C语言程序如下所示:
#define N 512
#define pi 3.14159
int sin_tab[512];
void main( )
{
int i;
for(i=0;i}
(2) 查表
查表实际上就是根据输入值确定表的地址.设输入x在0~2p之间,则x对应于512点表的地址为:index = (int)(512*x/2p),则 y = sin(x) = sin_tab[index].
如果x用Q12定点数表示,将512/2p用Q8表示为 20861,则计算正弦表的地址的公式为:index = (x*20861L)>>20.
例3.13 用查表法求以2为底的对数,已知自变量取值范围为0.5~1,要求将自变量范围均匀划分为10等分.试制作这个表格并说明查表方法.
(1) 做表:
y = log2(x),由于x在0.5到1之间,因此y在-1到0之间,x和y均可用Q15表示.由于对x均匀划分为10段,因此,10段对应于输入x的范围如表3.2所示.若每一段的对数值都取第1点的对数值,则表中第1段的对数值为y0(Q15) = (int)(log2(0.5)×32768),第2段的对数值为y1(Q15) = (int)(log2(0.55)×32768),依次类推.
表3.2 logtab0 10点对数表(输入0.5~1)
地址 输入值 对数值(Q15)
0 0.50~0.55 -32768
1 0.55~0.60 -28262
2 0.60~0.65 -24149
3 0.65~0.70 -20365
4 0.70~0.75 -16862
5 0.75~0.80 -13600
6 0.80~0.85 -10549
7 0.85~0.90 -7683
8 0.90~0.95 -4981
9 0.95~1.00 -2425
(2) 查表:
查表时,先根据输入值计算表的地址,计算方法为:index=((x-16384)×20)>>15.式中,index就是查表用的地址.例如,已知输入x= 26869,则index=6,因此y=-10549.
3.混合法
(1) 提高查表法的精度
上述方法查表所得结果的精度随表的大小而变化,表越大,则精度越高,但存储量也越大.当系统的存储量有限而精度要求也较高时,查表法就不太适合.那么能否在适当增加运算量的情况下提高非线性运算的精度呢?下面介绍一种查表结合少量运算来计算非线性函数的混合法,这种方法适用于在输入变量的范围内函数呈单调变化的情形.
混合法是在查表的基础上采用计算的方法以提高当输入值处于表格两点之间时的精度.提高精度的一个简便方法是采用折线近似法,如图3.1所示.
仍以求以2为底的对数为例(例3.13).设输入值为x,则精确的对数值为y,在表格值的两点之间作一直线,用y'作为y的近似值,则有:
y'=y0+ y
其中y0由查表求得.现在只需在查表求得y0的基础上增加 y即可. y的计算方法如下:
y=( x/ x0) y= x( y0/ x0)
式中 y0/ x0对每一段来说是一个恒定值,可作一个表格直接查得.此外计算 x时需用到每段横坐标的起始值,这个值也可作一个表格.这样共有三个大小均为10的表格,分别为存储每段起点对数值的表logtab0、存储每段 y0/ x0 值的表logtab1和存储每段输入起始值x0的表logtab2,表logtab1和表logtab2可用下列两个数组表示:
int logtab1[10]={22529,20567,18920,17517,16308,
15255,14330,13511,12780,12124}; /* y0/ x0 : Q13*/
int logtab2[10]={16384,18022,19660,21299,22938,
24576,26214,27853,29491,31130}; /* x0: Q15*/
综上所述,采用混合法计算对数值的方法可归纳为:
①根据输入值,计算查表地址:index=((x-16384)×20)>>15;
②查表得y0=logtab0[index];
③计算 x=x-logtab2[index];
④计算 y=( x×logtab1[index])>>13;
⑤计算得结果y=y0+ y.
例3.14 已知x=0.54,求log2(x).
0.54的精确对数值为y=log2(0.54)=-0.889.
混合法求对数值的过程为:
①定标Q15,定标值x=0.54*32768=17694;
②表地址index=((x-16384)×20)>>15=0;
③查表得y0=logtab0[0]=-32768;
④计算 x=x-logtab2[0]=17694-16384=1310;
⑤计算 y=( xlogtab1[0])>>13=(1310*22529L)>>13=3602;
⑥计算结果y=y0+ y=-32768+3602=-29166.
结果y为Q15定标,折算成浮点数为-29166/32768=-0.89,可见精度较高.
(2) 扩大自变量范围
如上所述,查表法比较适用于周期函数或自变量的动态范围不是太大的情形.对于像对数这样的非线性函数,输入值和函数值的变化范围都很大.如果输入值的变化范围很大,则作表就比较困难.那么能否比较好地解决这个问题,既不使表格太大,又能得到比较高的精度呢?下面讨论一种切实可行的方法.
设x是一个大于0.5的数,则x可以表示为下列形
阅读 (8969) |
收藏 (0)
C语言16位定标,DSP定标方法相关推荐
- c语言16位字节只能用到255,《C语言程序设计》月考试题(第三章).doc
实验五班<C语言程序设计>月考试题 学号 姓名 一.填空题 1.应用程序ONEFUNC.C中只有一个函数,这个函数的名称是________________. 2.在一个C源程序中,注释部分 ...
- 怎么得到16位校检和-c语言,16位CRC校验C语言算法.pdf
16位CRC校验C语言算法.pdf CRC 算法原理及C 语言实现 摘 要 本文从理论上推导出CRC算法实现原理,给出三种分别适应不同计算机或微控 制器硬件环境的C语言程序.读者更能根据本算法原理,用 ...
- 51单片机二进制转bcd码c语言,16位二进制数转换成BCD码的的快速算法-51单片机...
在做而论道上篇博文中,回答了一个16位二进制数转换成BCD码的问题,给出了一个网上广泛流传的经典转换程序. . 说它经典,不仅是因为它已经流传已久,重要的是它的编程思路十分清晰,十分易于延伸推广.做而 ...
- 键盘与显示实验程序c语言,16位微机原理,32位微机原理接口教学实验系统,64位微机原理接口实训...
TW-X38 16.32位微机原理与接口教学实验系统 一.硬件概述 TW-X38现代32位微机原理与接口技术教学实验系统的升级换代产品,采用Intel i386EX嵌入式微处理器作为系统核心,全面支持 ...
- 单片机人机接口编程c语言,16位单片机C语言编程:基于PIC24
第一部分 飞行入门 第1章 首飞 1.1 飞行计划 1.2 飞前备忘录 1.3 飞行 1.3.1 编译和连接 1.3.2 构建第一个项目 1.3.3 端口初始化 1.3.4 重测PORTA 1.3.5 ...
- 生成16位随机字符串的方法
function getNonce(){$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';$noncest ...
- C语言有符号整数最小值,16位带符号整数为什么是
公告: 为响应国家净网行动,部分内容已经删除,感谢读者理解. 话题:16位带符号整数为什么是回答:剩下15位二进制数的最大值是每一位数都是1的情况,即2^15-1=326.326化成二进制为1000 ...
- 使用GCC和GNU Binutils编写能在x86实模式运行的16位代码
使用GCC和GNU Binutils编写能在x86实模式运行的16位代码 不可否认,这次的标题有点长.之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解GCC生成16位实模式代码方法 ...
- 修改计算机显示颜色16位色,教你win10怎么调成16位色
我们电脑屏幕图像是由像素组成的,色味就是每个像素点上颜色的数据位数,我们所说的16位色是指由2的16次方种颜色组成.下面,我就给大家介绍一下win10调节成16位色的方法 win10系统相较于其他系统 ...
最新文章
- 【自然框架】之“元数据”的威力
- java把二维转换为一维_在R语言中什么函数可以将二维数组转换成一维数组
- 单位转换html代码,万能在线单位转换器 转换器网
- 浅析C++开发工程师的薪资与发展
- NHibernate 基础
- 服务器虚拟机的关键特性,VMware Workstation的几大关键特性
- SharedCache-共享缓存概况和初步运用实例(1)
- IPv4地址-地址分类与用途
- 关于游戏中美术文件夹的划分
- Velodyne 16线三维激光雷达
- ResHacker 3.5 汉化绿色版
- Unreal Engine 4学习资料整理
- Model-based evolutionary algorithms: a short survey 阅读笔记
- python dataframe是什么_【Python-pandas】核心数据结构DataFrame介绍
- matlab中cell是什么意思,matlab中cell的用法
- linux 加路由 网络不可达,无法添加静态路由:SIOADDRT:网络不可达
- Tableau阈值设置及其使用
- linux 文件操作write详解
- 几个分形的matlab实现1,几个分形的matlab实现
- 微软飞行模拟器android,微软飞行模拟器2020
热门文章
- mysql性能调优之 max_allowed_packet 详解 解决ERROR 2006 (HY000): MySQL server has gone away
- 满满的干货分享!!!广电网络的那些事~
- 开发用什么linux系统版本,6种适用于开发人员的Linux发行版本!
- pt 软件安装及pt-kill 用法
- 灵眸action_大疆Osmo Action灵眸运动相机值得买吗?
- 易智瑞(ESRI)2019最新ENVI5.5遥感应用专题操作录屏及讲义分享
- 初相识 | 全方位认识 sys 系统库
- Vehicle Spy3软件常用功能之实时监控总线报文
- 物联网卡将加快融入智能城市中
- 放大器:A、B、AB、D、G、H