发新帖我要提问
12
返回列表
打印
[应用相关]

cotex M3开方函数SQRT

[复制链接]
楼主: fqingy2003
手机看帖
扫描二维码
随时随地手机跟帖
21
香水城| | 2008-11-19 09:53 | 只看该作者 回帖奖励 |倒序浏览

哈哈,热烈欢迎

谢谢老狼,造福社会呀。

使用特权

评论回复
22
香水城| | 2008-11-19 15:43 | 只看该作者

楼上的这个想法让我想起来曾经在8位单片机上做的一个开平

就是使用ST7的乘法指令,采用试探与二分法相结合,现在已经忘记效率如何了。

使用特权

评论回复
23
杨容| | 2008-11-19 16:57 | 只看该作者

开方函数SQRT

老狼的程序我也用过,编译后看到汇编代码实在太长。我现在的程序是我自己用汇编写的,很短。用的是TI 280X的DSP

使用特权

评论回复
24
lianshumou| | 2008-11-19 18:13 | 只看该作者

改天有时间写个牛迭的汇编版!

使用特权

评论回复
25
hfx| | 2008-11-24 21:02 | 只看该作者

最后的晚餐

最后的回复是正途。

使用特权

评论回复
26
fqingy2003|  楼主 | 2008-12-1 15:10 | 只看该作者

多谢大家的帮助

现在问题已经解决,快速开方
//32位无符号定点开方
u16 qsqrt(u32 a)
{
  u32 rem = 0, root = 0, divisor = 0;
  u16 i;
  for(i=0; i<16; i++)
  {
    root <<= 1;
    rem = ((rem << 2) + (a>>30));
    a <<= 2;
    divisor = (root << 1) + 1;
    if(divisor <= rem)
    {
      rem -= divisor;
      root++;
    }
  }
  return root;
}
现在,625us一次运算,动作速度达到ms级精度,定值时间卡的相当的准,
当然makesoft是对的,我的程序结构不好,但是我的东东没有一个反应是慢的,呵呵,让你见笑了 

使用特权

评论回复
27
fqingy2003|  楼主 | 2008-12-1 15:52 | 只看该作者

多谢,我好像回复了,怎么没有贴上呢

多谢大家指点
u16 qsqrt(u32 a)
{
  u32 rem = 0, root = 0, divisor = 0;
  u16 i;
  for(i=0; i<16; i++)
  {
    root <<= 1;
    rem = ((rem << 2) + (a>>30));
    a <<= 2;
    divisor = (root << 1) + 1;
    if(divisor <= rem)
    {
      rem -= divisor;
      root++;
    }
  }
  return root;
}

使用特权

评论回复
28
fqingy2003|  楼主 | 2008-12-1 16:02 | 只看该作者

netjob 兄弟真慷慨,给过全的啥

netjob 兄弟真慷慨,给过全的啥
不知道是否可以PK

使用特权

评论回复
29
ijk| | 2008-12-1 17:16 | 只看该作者

开方1次625us

  开方1次625us,感觉慢了,努力一下,应该可以做到100us以下。看看28楼什么时候出一个代码。

使用特权

评论回复
30
fqingy2003|  楼主 | 2008-12-2 17:21 | 只看该作者

27楼的同志,你的<0.5是如何处理的

TI28有专门的数符号位指令,CORTEX3没有(至少我现在还没有发现)如果这个用循环的话,还不如使用我现在这个函数了,不知道你的函数可以给我分享一下

使用特权

评论回复
31
zhiwei| | 2008-12-4 10:01 | 只看该作者

看看我的程序吧。

我在avr上面用4M开方32bit也只200多uS啊。高手都怎么搞的,呵呵。
汇编,献丑了。
在STM32上面36M可能50uS都不到就搞定了。抽空移植一下吧。
这个程序是我原创,以前发过贴的。

.org 0x0000

main: 
       ldi   r16, 0x21
       ldi   r17, 0x43
       ldi   r18, 0x65
       ldi   r19, 0x87

       rcall sqrt
here:  rjmp  here


//U16 Sqrt(U32 num)
//input : num -> r19:r16
//output: res -> r17:r16
//use volatile registers r9:r0, 
//r1:r0   -> result
//r4:r2   -> result left shift temp 
//r26:r24 -> source num left shift extend

sqrt:  
       clr   r0      ;clr result
       clr   r1
       movw  r2, r0  ;clr result shift
       movw  r4, r0  ;const - 0
            movw  r24,r0
       movw  r26,r0
       ldi   r27,0x11;

wait:       rcall shiftb
       rcall shiftb
       dec   r27
       cpi   r27, 0x1
       breq  cal
       cpi   r24, 0
       breq  wait  
       
cal:
            inc   r2
       cp    r24, r2;extend - (4 result + 1)
       cpc   r25, r3
       cpc   r26, r4
            brcc  hig
       clc
       rjmp  calend
hig:       
            sub   r24, r2
       sbc   r25, r3
       sbc   r26, r4
            sec

calend:       
            rol   r0    ;result reflash
       rol   r1

            dec   r27
       breq  cend 

            movw  r2, r0;init 4 * result
       clr   r4
       rcall shifta;result and input number shift   
            rcall shifta
            rjmp  cal

cend:
            movw  r16,r0
       ret

shifta:
            lsl   r2
       rol   r3
       rol   r4
shiftb:lsl  r16
       rol   r17
       rol   r18
       rol   r19
       rol   r24
       rol   r25
       rol   r26
            ret

使用特权

评论回复
32
ijk| | 2008-12-4 10:53 | 只看该作者

36楼说得好

  36楼说得好,其实我想在STM32上面72M可能10us就能做好。要做到10us,多半得用一些汇编:先做归一,然后通过查表(表不用大,256字节就足够)先得到准确的初值,之后通过硬件除法(应该使用CortexM3的这个特性来加快运算速度)而不是使用移位,硬件除法只需几个循环就可以得到最终结果。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则