c - 找到两个最差的值并删除总和

标签 c microcontroller stm32

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

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

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

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;
}

现在我想扩展此函数以删除 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};

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

最佳答案

  1. 如果您的 ADC 返回 5 到 16 位 14 位的值且电压引用为 3.3V,则电压在 1mV 到 3mV 之间变化。它很可能是正确的读数。为14位ADC设计好的输入电路是非常困难的。

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

第二个信号是非常低幅度的正弦波(9-27mV - 假设 14 位和 3.3Vref) enter image description here

算法:

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;
}

如果 level2 的幂。这个版本只需要 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;
}

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

关于c - 找到两个最差的值并删除总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60416832/

相关文章:

android - 跨原生 GCC 4.8 构建 : libcpp Error: invalid conversion from long long to off_t (aka long int)

c - 如何避免 gcc 编译器使用 -l 选项?

c++ - 为什么 iostream 在 MCU 上占用这么多闪存空间?

microcontroller - 具有32MX4入门指南的MRF24WB0MA WiFi

c - 与 STM32f1xx 的 USART 通信

使用 Unicode 行分隔符编译 UTF-8 编码的源代码

c - 由于不正确的重新分配,我是否遇到了段错误?

c - 为什么在 MSP430-GCC 中优先使用 int 而不是 (unsigned) char 作为小整数

c - 带按钮的 LED 灯闪烁

c - DAC信号发生器stm32