搜索
bottom↓
回复: 17

dsPIC的除法运算

[复制链接]

出0入0汤圆

发表于 2010-4-14 11:52:27 | 显示全部楼层 |阅读模式
使用dsPIC30F2020中间有一个除法,a/b,需要的到后面的小数值。
应该最简单的就是用a*(1/b)了,而且这样可以使用dsp内核计算,手工算出1/b是一个很小的数,然后乘a,a为INT型,但是使用DSP内核后读出的结果是0!不知道是什么原因,难道这样除不行吗?那还有没有其它方法呢?

出0入0汤圆

发表于 2010-4-14 11:53:10 | 显示全部楼层
是不是溢出了?

出0入0汤圆

 楼主| 发表于 2010-4-14 12:16:07 | 显示全部楼层
回复【1楼】snail0204  瓜牛
-----------------------------------------------------------------------

1/b已经转成Q15格式小数了,乘INT型变量也会溢出吗?是不是小数部分溢出呢!PIC关于DSP的数据手册写的真的是太模糊了,好多地方都没写清楚!

出0入0汤圆

发表于 2010-4-14 12:32:04 | 显示全部楼层
为什么不是直接a/b,.31精度因该够了。

出0入0汤圆

发表于 2010-4-14 12:38:45 | 显示全部楼层
16位内核(无需动用DSP),有32位/16位的除法指令,比如要算3/2.33,不要小数点,你可以换成300/233来算,要小数点后1位,3000/233,这样的前提是工业控制场合。如果你要做DSP上的一些分析处理,这个方法就算了。

出0入0汤圆

发表于 2010-4-14 12:43:13 | 显示全部楼层
两个数的数据格式不同。在这里 INT x Q15 ?

出0入0汤圆

 楼主| 发表于 2010-4-14 13:16:49 | 显示全部楼层
回复【3楼】xyufo2000  
-----------------------------------------------------------------------

不是精度的关系,主要是我用MPLAB SIM仿真来看float型除法要将近500个指令周期,太夸张了!

回复【4楼】headwolf_83  
-----------------------------------------------------------------------

这个数除出来要送到PID环节里面去调整用的,由于调整量是一个比例系数(小于1),所以必须要有小数,而且这两个值一个是INT型,一个是LONG型的,然后再放大有些麻烦了。


回复【5楼】xyufo2000  
-----------------------------------------------------------------------

确实一个是INT,一个是Q15格式。是不是这样不行啊?用MPLAB仿真环境这样仿真其它计算好像没有问题!只是小数位不见了!

出0入0汤圆

发表于 2010-4-14 13:22:34 | 显示全部楼层
结果寄存器定义成long类型,然后结果右移15位。但是这时候只能取值到整数部分。或者你可以试验一下IQ各市里面有专门将Q15变成浮点型是的函数。

出0入0汤圆

发表于 2010-4-14 13:26:38 | 显示全部楼层
如果a-LONG 则a/b;否则两个q15。

出0入0汤圆

 楼主| 发表于 2010-4-14 13:41:54 | 显示全部楼层
回复【7楼】tiancaigao7  天才杨威利
-----------------------------------------------------------------------

那个转换函数我试了,不过没有效果,因为DSP计算返回的值就是0!

回复【8楼】xyufo2000  
-----------------------------------------------------------------------

就是说如果需要小数的话就只能Q15格式相乘才行!

出0入0汤圆

发表于 2010-4-14 14:48:42 | 显示全部楼层
你怎么直接调用的DSP内核?用的汇编语言?还是内建函数?这个要看看这类函数的输入输出要求。还有这类函数是有益处的可能性的

出0入0汤圆

发表于 2010-4-14 14:59:47 | 显示全部楼层
不知道你的PID算法是怎么样的。我这几天整理了下,全部以整型在跑的标准PID,经过处理,8MIPS下,也不到10个us。
没必要老是考虑以小数来整,实际在在最后一步之前,都可以看成普通的整型来处理。

出0入0汤圆

 楼主| 发表于 2010-4-14 15:32:37 | 显示全部楼层
回复【10楼】tiancaigao7  天才杨威利
-----------------------------------------------------------------------

我是用的内建函数调用的。


回复【11楼】headwolf_83  
-----------------------------------------------------------------------

PID我用的就是内建的那个DSP函数。起始以前用16F73写的程序PID也是用整形变量写的,但是第一次用dsPIC,用SIM仿真的时候发现DSP内核再做INT*INT运算的时候能得出正确的值,但是用__builtin_sac()指令来读出就全都成0了(用汇编指令也是一样的),实在找不到原因(编译器,MPLAB版本都换过)!所以才只能改用小数来运算了,真的也是迫不得已啊!

出0入0汤圆

发表于 2010-4-14 16:34:06 | 显示全部楼层
我的PID都用整型算。dsPIC的,可以搞定的。你如果非得用那个PID库,那肯定是要换Q15的。我就用标准C,配合内建函数,不会算得得很慢啊。
我所谓的内建函数,不过是muluu,mulss,divud等几个乘除法指令。

出0入0汤圆

发表于 2010-4-14 17:04:51 | 显示全部楼层
当然啦,如果你的电机转动速度比较快,又是每个PWM周期调节一次,那整型可能有点慢,只能说可能。因为我只是搞最基本的PID,外加一些限制.

出0入0汤圆

 楼主| 发表于 2010-4-15 08:52:23 | 显示全部楼层
回复【14楼】headwolf_83  
当然啦,如果你的电机转动速度比较快,又是每个PWM周期调节一次,那整型可能有点慢,只能说可能。因为我只是搞最基本的PID,外加一些限制.
-----------------------------------------------------------------------

感谢你的回复,我做的是逆变器。对速度要求还不是特别严格。
没用整型变量主要是由于我在用DSP内核做整型乘法的时候发现没办法把正确的结果读取出来,比如说我用500*20,能看到DSP的累加器中得出正确结果10000,但是用sac指令读出的结果却都是0。我也是第一次用DSP芯片,问了好多人也没解决,没办法才被迫用浮点来运算的!

出0入0汤圆

发表于 2010-4-16 20:39:07 | 显示全部楼层
unsigned long int a ;
unsigned int b,c ;

a = b * c ;这样做不符合你的要求?why?

a = __builtin_muluu(b,c):也可以的。

出0入0汤圆

发表于 2010-4-17 08:54:43 | 显示全部楼层
内建函数不支持浮点运算,因此你用浮点肯定是不行的,其次PID一般都是将参数编程整形然后再计算,最后将结果处理一下。因此PID基本上不需要浮点运算。第三,内建函数如果结果和输入没有超过预期,肯定是可以计算出结果的,我们无数次的用了这些函数,没有出现过错误,因此还是建议你能从函数本身来找找问题。不要一遇到问题就想办法绕过去。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 11:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表