C中三个有效值的平均值

时间:2015-12-10 10:53:27

标签: c processing-efficiency

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

为了安全起见,我想对引脚进行3次采样,比较三个值并使用最常见的值(即样本A为1,B为3,C为1,我想使用1,如果AB和C都是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开发板上。

编辑:

我根据答案更改了代码,只读了&#34; z&#34;如果将使用它,并使用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;
}

2 个答案:

答案 0 :(得分:3)

如果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()'而不是虚拟循环。这取决于您平台上的可用内容。

答案 1 :(得分:0)

如果您认为xyz01。然后你可以使用x+y+z>1(如果大多数都是1,则总和大于1,比较评估为1,否则评估为{{1} }})。

否则您的(第二)解决方案可能效率最高。至少如果你不知道结果的可能性。除了睡一个微秒,这将是最耗时的操作。

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

0