搜索
bottom↓
回复: 12

51单片机做乘除法运算【如何避免】

[复制链接]

出0入0汤圆

发表于 2016-6-24 09:15:13 | 显示全部楼层 |阅读模式
我现在就有一个算法就是每隔20分钟会执行一次,这个算法就是用到了乘除法。
现在在通讯快的时候偶尔会出现数据掉包的情况,如何优化乘除法这部分代码。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2016-6-24 09:18:37 | 显示全部楼层
1、乘除计算改用移位;2、无法避免乘除运算则尽量用整数乘除;3、把复杂的计算拆分成多个步骤分散执行

出0入93汤圆

发表于 2016-6-24 11:06:20 | 显示全部楼层
51带有硬件乘除法器,你避免它的结果将会是掉包概率增加而不是减少。

出0入0汤圆

 楼主| 发表于 2016-6-24 12:03:28 | 显示全部楼层
yangsen 发表于 2016-6-24 09:18
1、乘除计算改用移位;2、无法避免乘除运算则尽量用整数乘除;3、把复杂的计算拆分成多个步骤分散执行 ...

   capacity/3600  这个不好移位吧!

而且还有循环的乘除法  

for(loop=0;loop<CCTABLE_TIMES;loop++)
capcity_temp = ((long)EE_TABLE[PARA_FIXCAP_CAPPER0+(loop<<1)]*(CAPACITY_FULL))/100;

出0入14汤圆

发表于 2016-6-24 12:17:00 | 显示全部楼层
通讯用终端就是啊,怎么会掉包?

你的意思是一包数据的周期不足以完成一次运算?

一眼的数据不需要这么频繁的发送吧,我觉得有50ms 100ms足够了

出0入0汤圆

发表于 2016-6-24 12:17:03 | 显示全部楼层
这么长的间隔, 把计算分开一步步完成。
或者通讯完全用中断实现。

出0入93汤圆

发表于 2016-6-24 12:19:54 | 显示全部楼层
dhw5qq 发表于 2016-6-24 12:03
capacity/3600  这个不好移位吧!

而且还有循环的乘除法  

没有什么不可以的。
capacity/3600 = capacity * 0x400000 /3600 / 0x400000 = capacity *  1165 >> 22
= capacity *  0b10010001101 >> 22
= (capacity >> 12) + (capacity  >> 15) + (capacity >> 19) + (capacity  >> 20) + (capacity >> 22)

不过说实在的,我真的不知道对于51来说,移位有什么好处。代码冗余,消耗时间变长,唯一的好处就是中断响应时间变短了那么几个周期。
如果你真的确认这个对你有用那你就用吧。

出0入0汤圆

发表于 2016-6-24 12:35:48 来自手机 | 显示全部楼层
每隔20分钟才一次计算,那为什么不提前几豪秒做预算呢?

出0入0汤圆

发表于 2016-6-29 00:51:48 | 显示全部楼层
51一般用移位

出0入84汤圆

发表于 2016-6-29 01:25:15 | 显示全部楼层
串口用中断怎么可能会丢包,除非数据没传输完你就拿来运算了,那就用缓冲呗,接收的和处理的不相同的RAM,传输完就把数据复制到需要处理的RAM区,这个复制时间很短很短,不会影响的

出0入4汤圆

发表于 2016-6-29 09:10:58 来自手机 | 显示全部楼层
中断接收到缓存,计算完成再处理,肯定不会丢包的。

出0入0汤圆

发表于 2016-6-29 09:49:14 | 显示全部楼层
takashiki 发表于 2016-6-24 12:19
没有什么不可以的。
capacity/3600 = capacity * 0x400000 /3600 / 0x400000 = capacity *  1165 >> 22
=  ...

这样计算出来的结果有误差的。0x400000/3600=1165.08444444444444
不过这种算法非常不错。移位,可以使用联合体公用内存实现快速移位(特别字节数特别大的情况)。
怎样可以使用这种算法实现浮点数除法呢?
如capacity/3600.3

出0入93汤圆

发表于 2016-6-29 10:15:31 | 显示全部楼层
lzf713 发表于 2016-6-29 09:49
这样计算出来的结果有误差的。0x400000/3600=1165.08444444444444
不过这种算法非常不错。移位,可以使用 ...

无论哪种算法,都有误差,只是看你能不能接受。
规规矩矩的,15/8,误差达到了87.5%,你也得忍。
0x400000/3600=1165.08444444444444,误差十万分之7,基本上还算是差不多的。

同样,下面是3600.3的:
0x400000/3600.3 = 1164.9873621642640891036858039608,同样取值1165,误差十万分之一。
如果你觉得这个精度还是太差了,那用这个:
0x10000000/3600.3 = 1192947.0588562064272421742632558,取值1192947,误差4.9E-8

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-26 03:50

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

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