【发布时间】:2021-03-02 00:09:29
【问题描述】:
如上所述,如何在不将所有值添加到浮点数的情况下对一组值进行平均,这旨在用于 8 位/16 位微控制器,以减轻时间紧迫的浮点数。我想出了一个方法,但我担心它比将所有内容添加到浮点数中并划分更麻烦。我将在下面附上代码。
平均值减少到 ADCsample 数组中的第一个元素
平均.c
#include <xc.h>
#include "Average.h"
#include "Initialize.h"
/*
(x+y)=((x&y)*2)+(x^y)
(x+y)/2=(x&y)+((x^y)>>1)
Does not overflow data type when done in pairs
* No need for floats
* array must have 2/4/8/16/32...values to be averaged
* Accurate rounding
*/
void Average(void)
{
x=0;
for (x=0; x<ADCsamplesize; ++x)
{
ADCsamples[x].value=ADCsampleraw[x];
ADCsamples[x].upflag=0;
}
x=0;
y=0;
z=ADCsamplesize/2;
while(z!=0)
{
if (((ADCsamples[y].value&0x01)^(ADCsamples[y+1].value&0x01))==1) //is rounding needed? (even/odd mismatch)
{
if((ADCsamples[y].upflag^ADCsamples[y+1].upflag)==1) //if ONE has been rounded before
{
if (ADCsamples[y].upflag==1) //which to round down?
{
ADCsamples[y].value--;
ADCsamples[y].upflag=0;
}
else
{
ADCsamples[y+1].value--;
ADCsamples[y+1].upflag=0;
}
}
else //round up
{
if (ADCsamples[y].value!=65535) //overflow protection
{
ADCsamples[y].value++;
}
else
{
ADCsamples[y+1].value++; //in the event of a mismatch y and y+1 cannot both be data type max
}
ADCsamples[x].upflag=1; //mark as being rounded up
}
}
else
{
ADCsamples[x].upflag=0; //as elements are reused, clear rounded flag
}
ADCsamples[x].value=(ADCsamples[y].value&ADCsamples[y+1].value)+((ADCsamples[y].value^ADCsamples[y+1].value)>>1); //bitwise average of 2 values, not possible to overflow
if (x+1!=z)
{
x++;
y=y+2;
}
else
{
z=z>>1;
x=0;
y=0;
}
}
}
平均.h
#ifndef AVERAGE_H
#define AVERAGE_H
#include <xc.h> // include processor files - each processor file is guarded.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
unsigned char z;
unsigned char x;
unsigned char y;
unsigned char const ADCsamplesize=8;
unsigned int ADCsampleraw[]=
{
123,516,4569,3521,852,456,981,852
};
typedef struct sample{
unsigned int value;
unsigned int upflag;
}sample;
sample ADCsamples[8];
void Average(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XC_HEADER_TEMPLATE_H */
【问题讨论】:
-
任一读数的最大值是多少?
int的大小是多少? -
您的问题是什么?您想要修复的方法中是否存在错误或问题?你想知道它是否有错误吗?您想要更好还是不同的解决方案?
-
Int 为 16 位,任何读数的最大值可能会填充 16 位,具体取决于 ADC 精度,
-
问题是这是否通过保持在总线宽度内来减轻 CPU 的压力以及除了暴力添加到对 8/16 位 MCU 来说非常 CPU 密集的浮点数之外还有什么其他方法
-
以最容易实现并远离浮点的方式编译它。求和为更大的(如有必要)整数类型,然后转移到除法并将实现细节留给编译器。如果吞吐量存在瓶颈,然后寻找更好的解决方案。无论如何,无论是显式地将计算拆分为多个部分,还是隐式地将每个值拆分为多个部分(通过使用更大的类型),您都需要对 CPU 施加压力。