打印
[STM8]

用stm8s105 做数组求和后取平均后计算错误,请各位帮忙指点指点,谢谢

[复制链接]
1297|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hawk2003454|  楼主 | 2016-5-5 15:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  今天用stm8s105(其他类型的mcu没试过),编译器用IAR for stm8. 取ADC的转换值,中值滤波(连续读取6次ADC转换值,然后按大小排序,去掉最大的,去掉最小的,去中间值的算术平均值),代码如下:

unsigned char i,j;
        unsigned int temp,F_result;
        unsigned int Table[6];
    unsigned long buf;
   
    unsigned char AD_channel_result[5];
    unsigned int result;
   
        for(i=0;i<6;i++) Table[i]=*(table+i);
  
        //测试中值滤波算法是否正确
        //        Table[0]=15; Table[1]=0;Table[2]=4; Table[3]=3;Table[4]=20; Table[5]=2;
    //Table[0]=1; Table[1]=50000;Table[2]=50000; Table[3]=20000;Table[4]=40000; Table[5]=65000;
    //Table[0]=1; Table[1]=535;Table[2]=5000; Table[3]=20000;Table[4]=40000; Table[5]=65000;
    //Table[0]=1; Table[1]=536;Table[2]=5000; Table[3]=20000;Table[4]=40000; Table[5]=65000;
        for(i=0;i<6;i++)
        {
                for(j=i;j<6;j++)
                {
                        if(Table[i]>=Table[j])
                        {
                                temp=Table[i];
                                Table[i]=Table[j];
                                Table[j]=temp;       
                        }
                }
        }
      
    //去掉最大最小值
    //for(i=0;i<6;i++) buf=buf+Table[i];
    // buf =buf>>2;
        F_result=(Table[1]+Table[2]+Table[3]+Table[4])/4;//和超过65535溢出
    //F_result=((32768+32769+32780+32781)/4);
    //F_result=((Table[1]+Table[2])>>1);
    //F_result=(Table[1]+Table[2]+Table[3]+Table[4])/4;
   
    #if 1
    Uart_Send_String("开始\r\n");
        for(i=0;i<6;i++)
    {
        //result=Table[i];
        result=F_result;
        //result=buf;
        //result=60000*4/4;
        AD_channel_result[0] = result/10000+0x30;          //ASCII编码 0x30对应的是数字 0
        AD_channel_result[1] = (result%10000)/1000+0x30;          //ASCII编码 0x30对应的是数字 0
        AD_channel_result[2] = (result%1000)/100+0x30;
        AD_channel_result[3] = (result%100)/10+0x30;
        AD_channel_result[4] = result%10+0x30;

        Uart_Send_Data(AD_channel_result[0]);
        Uart_Send_Data(AD_channel_result[1]);
        Uart_Send_Data(AD_channel_result[2]);
        Uart_Send_Data(AD_channel_result[3]);
        Uart_Send_Data(AD_channel_result[4]);
        Uart_Send_String("\r\n");
    }
    Uart_Send_String("结束\r\n");
#endif
   
        return F_result;

代码如上,(Table[1]+Table[2]+Table[3]+Table[4]之和大于65535就开始出错,我测试过和等于65536,开始出错,感觉好像是计算值溢出,但我并不知道怎么处理。如果  F_result=((32768+32769+32780+32781)/4);串口发送的计算结果并不会错,应该是IAR编译前已经计算好了的缘故吧。请懂的朋友指点指点,计算机水平太差,自己找不到解决办法,度娘过来没结果,希望能在伟大的二姨上找到答案,感谢感谢!

沙发
siemens11| | 2016-5-5 15:43 | 只看该作者
就是溢出啊,同学。。。

使用特权

评论回复
板凳
hawk2003454|  楼主 | 2016-5-5 16:52 | 只看该作者
siemens11 发表于 2016-5-5 15:43
就是溢出啊,同学。。。

请问,怎么改才能使当和大于65535的值时取算术平均值正确,谢谢!实在没解决办法,虚心求教

使用特权

评论回复
地板
技术小小兵| | 2016-5-5 17:26 | 只看该作者
(A+B+C+D)/4,其实等于,A/4+B/4+C/4+D/4,当然,这样的话精度会丢失得比较多。
追求精度的话,用浮点,或者用更长的数据类型。

使用特权

评论回复
5
hawk2003454|  楼主 | 2016-5-5 21:18 | 只看该作者
技术小小兵 发表于 2016-5-5 17:26
(A+B+C+D)/4,其实等于,A/4+B/4+C/4+D/4,当然,这样的话精度会丢失得比较多。
追求精度的话,用浮点, ...

感谢回复,我测试过A=5,B=6,C=7,d=8,代进去,计算结果还是相差较大的。只能用浮点这个方法了吗?

使用特权

评论回复
6
ccw1986| | 2016-5-5 22:14 | 只看该作者
求的这个和你放在多宽的数据里面呢?

使用特权

评论回复
7
hawk2003454|  楼主 | 2016-5-5 22:23 | 只看该作者
ccw1986 发表于 2016-5-5 22:14
求的这个和你放在多宽的数据里面呢?

16位,现在我换成了unsigned long 数组里,计算结果正确,感谢以上各位的解答。基础不过关呀

使用特权

评论回复
8
CI-KE| | 2016-5-6 08:50 | 只看该作者
可以用结构体啊!再大的数目也可以加,不会溢出啊

使用特权

评论回复
9
技术小小兵| | 2016-5-6 11:52 | 只看该作者
ccw1986 发表于 2016-5-5 22:14
求的这个和你放在多宽的数据里面呢?

数据相加,要用多一位的数据类型,如:5bit+5bit,要用6bit来装;数据相乘,要用位数相加的数据类型来装,如6bit*12bit,得用18bit来装。

使用特权

评论回复
10
技术小小兵| | 2016-5-6 12:00 | 只看该作者
hawk2003454 发表于 2016-5-5 21:18
感谢回复,我测试过A=5,B=6,C=7,d=8,代进去,计算结果还是相差较大的。只能用浮点这个方法了吗? ...

事实上,整数除法运算,精度取决于除法使用次数。另外,追求更高的精度应该使用四舍五入,既被除数要在除以除数之前先加上除数的一半,如:(A+B+C+D+2)/4;如果除数是奇数,即应当先转换成偶数,如:((A+B+C+D+E)*2+5)/10;有些专用单片机编译器没有浮点编译的,又要进行大量运算的,就很有用,你用STM8这些单片机的话,浮点随便用啦。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
hawk2003454 + 1 很给力!感谢认真解答
11
hawk2003454|  楼主 | 2016-5-10 21:31 | 只看该作者
怎么结不了贴

使用特权

评论回复
12
迪卡| | 2016-5-11 20:28 | 只看该作者
可以用结构体啊!再大的数目也可以加,不会溢出啊

具体怎么做啊

使用特权

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

本版积分规则

8

主题

61

帖子

0

粉丝