找出两个最差的值并删除总和

sgt*_*nny 3 c microcontroller stm32

微控制器负责采样 ADC 值(模数转换)。由于这些部分受容差和噪声的影响,因此可以通过删除 4 个最差值来显着提高精度。查找和删除确实需要时间,这并不理想,因为它会增加循环时间。

想象一下 100MHz 的频率,所以软件的每个命令确实需要 10ns 来处理,命令越多,控制器被阻止执行下一组样本的时间就越长

所以我的目标是尽可能快地完成排序过程,我目前使用这个代码,但这只会删除最糟糕的两个!

uint16_t getValue(void){

    adcval[8] = {};
    uint16_t min = 16383 //14bit full
    uint16_t max = 1;    //zero is physically almost impossible!
    uint32_t sum = 0;    //variable for the summing

    for(uint8_t i=0; i<8;i++){
     if(adc[i] > max) max = adc[i];
     if(adc[i] < min) min = adc[i];
     sum=sum+adcval[i];
    }
    uint16_t result = (sum-max-min)/6;   //remove two worst and divide by 6
    return result;
}
Run Code Online (Sandbox Code Playgroud)

现在我想扩展这个函数以删除 8 个样本中的 4 个最差值以获得更高的精度。关于如何做到这一点的任何建议?

此外,构建一个高效的函数来查找偏差最大的值,而不是最高和最低值,这将是很棒的。例如,想象这两个数组

uint16_t adc1[8] {5,6,10,11,11,12,20,22};
uint16_t adc2[8] {5,6,7,7,10,11,15,16};
Run Code Online (Sandbox Code Playgroud)

第一种情况将通过所描述的机制获得精度(删除 4 个最差的)。但是第二种情况会删除值 5 和 6 以及 15 和 16。但这理论上会使计算变得更糟,因为删除 10、11、15、16 会更好。有没有删除4个最偏离的快速解决方案?

P__*_*J__ 5

  1. 如果您的 ADC 返回 5 到 16 个 14 位的值且电压参考为 3.3V,则电压从 1mV 到 3mV 不等。这很可能是正确的阅读。为 14 位 ADC 设计好的输入电路是非常困难的。

  2. 最好运行运行平均值。什么是运行平均值?它是软件低通滤波器。 X 蓝色是来自 ADC 的读数,红色是运行平均值

第二个信号是幅度非常低的正弦波(9-27mV - 假设 14 位和 3.3Vref) 在此处输入图片说明

算法:

static int average;
int running_average(int val, int level)
{
    average -= average / level;
    average += val * level;
    return average / level;
}

void init_average(int val, int level)
{
    average = val * level;
}
Run Code Online (Sandbox Code Playgroud)

如果level是 的力量2。这个版本只需要 6 条指令(没有分支)来计算平均值。

static int average;

int running_average(int val, int level)
{
    average -= average >> level;
    average += val << level;
    return average >> level;
}

void init_average(int val, int level)
{
    average = val << level;
}
Run Code Online (Sandbox Code Playgroud)

我假设平均值不会溢出。如果是,您需要选择更大的类型