C中三个值的有效平均值

我们正在读取一些引脚信号,并根据此读数设置更多事件。

为了安全起见,我想对引脚进行3次采样,比较三个值并使用最常见的值(即样本A是1,B是3,C是1,如果AB和C都是,我想使用1 2然后使用2,但如果A是1,B是2和C是3,我想再次捕获三个样本)。

目前我正在使用:

int getCAPValues (void)
{
//  Get three samples to check CAP signals are stable:  

        uint32_t x = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // First set of CAP values
        for (uint32_t i = 0; i < 7; i++) dummy = i;                                                     // Pause
        uint32_t y = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // second set
        for (uint32_t i = 0; i < 7; i++) dummy = i;                                                     // Pause
        uint32_t z = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // third set

        if (x == y) || (x == z)
        {
            //use the x value
        }
        else if (y == z)
        {
            // use the y value
            x = y;
        }
        else
        {           
            x = -1;
        }

    return x;
}

但是这对我来说似乎不是很有效率,有没有更好的方法来做到这一点?

这是在C的SAMD21 Xplained Pro开发板上。

编辑:

我已根据答案更改了代码,只读取“z”值(如果将使用该值),并使用delay_us()代替虚拟循环:

int getCAPValues (void)
{
//  Get three samples to check CAP signals are stable:  

        uint32_t x = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // First set of CAP values
        delay_us(1);
        //for (uint32_t i = 0; i < 7; i++) dummy = i;                                                   // Pause
        uint32_t y = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // second set
        // Using most common value, or error code of -1 if all different

        if (!(x == y))
        {
            delay_us(1);
            //for (uint32_t i = 0; i < 7; i++) dummy = i;                                               // Pause
            uint32_t z = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;       // third set
            if (x == z)
            {
                // use the x/z value
                return x;
            }
            else if (y == z)
            {
                // use the y/z value
                return y;
            }
            else
            {           
                return -1;
            }
        }
    return x;
}

如果x==y您将使用x的值。 所以在这种情况下,你可以避开三读。

我不知道你的价值观有多变化,但如果有争议的价值实际上很少,它可以有效地提高近一倍的性能,以避免第二次延期。

事实上,如果它们不是罕见的,那么整个原理可能是无效的。

int getCAPValues (void)
{
//  Get three samples to check CAP signals are stable:  

        uint32_t x = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // First set of CAP values
        for (uint32_t i = 0; i < 7; i++) dummy = i;                                                     // Pause
        uint32_t y = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // second set
        if(x!=y){
            //x & y are different. Get a tie-breaker...
            for (uint32_t i = 0; i < 7; i++) dummy = i;                                                     // Pause
            uint32_t z = (PORT->Group[IN_PORT_CAP].IN.reg & IN_PORT_CAP_MASK) >> IN_PORT_CAP_PIN;           // third set
            if (y == z) {
                // use the y value
                x = y;
            } else if(x!=z){
                //tie-breaking failed...
                x=-1;
            }
        }
        return x;
}

PS:我也认为你应该使用`usleep()'而不是虚拟循环。 这取决于您的平台上可用的功能。


如果您可以假设xyz01 。 然后你可以使用x+y+z>1 (如果它们大多数是1那么总和大于1 ,比较结果为1 ,否则结果为0 )。

否则你的(第二个)解决方案可能是最有效的。 至少如果你不知道结果的可能性。 此外,睡眠时间为1微秒,这将是最耗时的操作。

你应该考虑的是,因为读取可能是非易失性的,所以如果你真的做了第三次读取,它可能会有所不同。 你也应该考虑是否需要重新阅读。 例如,如果您认为如果从端口读取的前三个读数都是不同的,并且第四个读取值等于第二个或第三个读取值,那么您可以使用它作为优化。 例如:

 x = read_port();
 y = read_port();

 if( x == y )
    return x;

 for(;;) {
    z = read_port();
    if( z == x || z == y )
        return z;
    x = y;
    y = z;
 }
链接地址: http://www.djcxy.com/p/31079.html

上一篇: Efficient Average of Three Values in C

下一篇: Maven set dependency mediation strategy to newest rather than nearest