40130064 发表于 2010-9-14 16:14:24

求绝世高手帮忙简化几行C语言代码

要d的值,计算一次要2900次,太长了,求绝世高手帮忙.

uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000;
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--)
{
b=(g+c)/a;
c=g%a;
d=d+b;
}

zhangxun0712 发表于 2010-9-14 16:22:34

程序有点问题吧,c没初始化就用?

zhangxun0712 发表于 2010-9-14 16:25:27

c=g%e; 这句是定值就不用放在for里面吧?

40130064 发表于 2010-9-14 16:26:17

我是用来计算梯形减速时 减速阶段产生的脉冲数。

517456 发表于 2010-9-14 16:28:09

b=g/e,因为g%e/e=0
如果其作初值为0的话
d+=b*2900/e
如果收到费用的话会讲的更详细点。(^_^)

40130064 发表于 2010-9-14 16:52:47

哈 我写错了

uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000; //这些值不是一定的,是我假设的.
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--)
{
b=(g+c)/a;
c=g%a;
d=d+b;
}

helloshi 发表于 2010-9-14 17:00:02

优化:
uint16 d = 5189;

40130064 发表于 2010-9-14 17:06:10

回复【7楼】helloshi
-----------------------------------------------------------------------

开始写错了 改了 值是6910

hsztc 发表于 2010-9-14 18:01:48

5楼应该是对的,不过第三行看不懂哈哈,再研究


晕晕我的结果不对, 发现这个b=(g+c)/a;   g+c不能拆开除,因为是整除


g=5 c=5 a=6

这样 b=(5+5)/6=1;

而拆后 b=g/a+c/a=5/6+5/6=0 ...

kingboy100 发表于 2010-9-14 18:18:02

uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000;
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--) //a等于3000(初始值),a如果大于100,执行下面语句后 a--
{
b=(g+c)/a;//b=(2000+c)/a
c=g%a;      //c=2000%a
d=d+b;      //d=d+b
}

whyjld 发表于 2010-9-14 18:45:12

你这个需要从算法的层次好好重新规划一下,感觉是可以吧复杂度降到O(0)的

dengting 发表于 2010-9-14 18:49:59

普通高手,旁观。

NJ8888 发表于 2010-9-14 19:01:09

与CPLD FPGA有啥关系?

minux 发表于 2010-9-14 20:32:59

【11楼】 whyjld

弱问复杂度O(0)是什么概念?再低也只能是O(1)吧?

semonpic 发表于 2010-9-14 21:50:00

VHDL 做梯形加减速,你想复杂了。我曾发过几篇台湾和国外的文章,现在怎么找不到了

tyou 发表于 2010-9-14 22:46:58

这个变量名和 ida 反编译出来的还难懂

40130064 发表于 2010-9-15 08:57:16

回复【15楼】semonpic
-----------------------------------------------------------------------

经验不够 真心求教

就是运动控制的电机缓冲阶段 P从工作速度A降到另一速度B. P的脉冲数量,A,B和A降到B的时间可以自由设定.


在电机停时速度刚好到B,不能偏差太多. 也就是说要先知道什么时候开始减速.

现我能算出减速的位置,效果也相当理想.就是计算花的时间太长了.

electricit 发表于 2010-9-15 09:08:49

一般高手,LOOK,LOOK.

whyjld 发表于 2010-9-15 09:53:53

回复【14楼】minux啊啊?
-----------------------------------------------------------------------

不好意思,个人的错误习惯。
用的时候都是n的怎么怎么样,所以经常把n去掉,1是N的0次方,时间长了O(1)就用成O(0)了,纯属个人习惯,不好意思。

40130064 发表于 2010-9-15 17:17:36

问题还没解决DDDDD

hsztc 发表于 2010-9-15 22:51:36

有问题,删了,下面是没问题的。

real_zyf 发表于 2010-9-15 22:58:08

回复【17楼】40130064
回复【15楼】semonpic 
-----------------------------------------------------------------------

经验不够 真心求教

就是运动控制的电机缓冲阶段 p从工作速度a降到另一速度b. p的脉冲数量,a,b和a降到b的时间可以自由设定.


在电机停时速度刚好到b,不能偏差太多. 也就是说要先知道什么时候开始减速.

现我能算出减速的位置,效果也相当理想.就是计算花的时间太长了.
-----------------------------------------------------------------------

只是梯形的话,只要每个周期都按照等差数列公式来算一下应不应该开始变速就好了

hsztc 发表于 2010-9-15 23:11:59

有问题,删了,下面是没问题的。

hsztc 发表于 2010-9-15 23:20:06

10MHz的AVR跑完这段要0.1秒。

semonpic 发表于 2010-9-16 00:11:02

你这个加减速是在单片机里做的还是在FPGA中作的,我的是放到FPGA中作的,如果做的是加减速对称的话,比较简单。可以参看MCX314的数据手册。
假设所需发送的脉冲数是N
在速度从VMIN 加到VMAX的过程过程中统计加速脉冲数A。已经发送的脉冲数是B 当N-B<=A时,既可以进行减速操作。在FPGA中就是几个加法器和比较器构成的。很简单。楼主可以测试测试

hsztc 发表于 2010-9-16 02:20:36

有问题,删了,下面是没问题的。

seemrain 发表于 2010-9-16 08:50:32

全部常数计算,直接一次计算好了放在RAM里面不行吗?

40130064 发表于 2010-9-16 08:51:37

多谢各位,特别感谢HSZTC.

avrpicarm 发表于 2010-9-16 09:30:54

AT官方有个App,专门讲了梯形算法,楼主可参考下

lgcHR 发表于 2010-9-16 10:43:15

既然初始值给定,循环次数就不会减少,考虑怎么讲循环体简化一下,貌似循环体中有一句c=g%a会浪费很多计算时间,可以单独提出来,值用另一个变量保存,使用时调用变量即可,通常%运算会浪费大量的运算时间。至于别人使用双层循环,运算时间会升至O(N)的平方级,效率会更低。

hsztc 发表于 2010-9-16 19:23:13

【28楼】 40130064

不客气,互相学习下。原来写的太乱了,出了点小差错。

uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000; //这些值不是一定的,是我假设的.
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--)
{
b=(g+c)/a;
if(g<a) c=g; else if(g<(a+a)) c=g-a; else c=g%a;
d+=b;
}

终于知道错在哪了哈哈,这个是正确的,效率提高1/3的。

应该还有简化的空间,得慢慢想。

hsztc 发表于 2010-9-16 21:05:15

uint16 a,c,d,e,f,g;
e=3100,f=110,g=2100; //这些值不是一定的,是我假设的.
a=0;c=0,d=0;

for(a=e;a>f;a--)
{            
if((g+c)>=a){if((g+c)<(a+a)) d++; else d+=(g+c)/a;}   
if(g<a) c=g; else if(g<(a+a)) c=g-a; else c=g%a;   
}

效率提高了1/2,多测试下。

hsztc 发表于 2010-9-16 21:20:14

只适合没有16位硬件除法的单片机,如果有16位或以上的硬件除法的话,那原来的不用改更快。

warmonkey 发表于 2010-9-17 20:02:55

如果单片机有硬件除法:
uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000; //这些值不是一定的,是我假设的.
a=0;b=0,c=0,d=0;


for(a=e;a>f;a--)
{
b=g/a;
b+=c/a;
c=g%a;
d=d+b;
}

一般来说,除法计算同时能得到余数

40130064 发表于 2010-9-18 10:45:39

看来只能放弃了 采用31楼方法 在ARM7内核下大概是30ms 如果说超过20ms 程序就跑不对.郁闷啊.

real_zyf 发表于 2010-9-18 12:47:22

T曲线变速根本不用这样算啊
每周期算一次以下的东西,看看S是否大于(目标位置-当前位置)即可:
(Vt^2-Vo^2)/2a=S
Vt目标速度Vo当前速度 a加速度 S匀加速运动经过的距离


S小于(目标位置-当前位置),即不需要减速,这个周期继续匀速
到了S 大于等于(目标位置-当前位置)的那个周期,则这个周期开始匀减速,这样到了目标位置的时候速度就能刚好是目标速度

hsztc 发表于 2010-9-18 21:16:34

32位的啊..../emotion/em040.gif


我都是在8位机上测试的,32位的话,数据类型定义为32位的会比16位的快,用 unsigned int


ARM7上有硬件除法吗? CM3上有硬件除法,不用优化都算的更快。
页: [1]
查看完整版本: 求绝世高手帮忙简化几行C语言代码