我们正在从引脚读取一些信号,并根据此读数设置更多事件。
为了安全起见,我想对引脚进行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;
}
答案 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)
如果您认为x
,y
和z
是0
或1
。然后你可以使用x+y+z>1
(如果大多数都是1
,则总和大于1
,比较评估为1
,否则评估为{{1} }})。
否则您的(第二)解决方案可能效率最高。至少如果你不知道结果的可能性。除了睡一个微秒,这将是最耗时的操作。
您应该考虑的是,因为读取可能是非易失性的,如果您实际执行第三次读取,它可能会有所不同。您也应该考虑是否需要完全重新阅读。例如,如果您认为如果来自端口的前三个读取都是不同的,并且第四个读取等于第二个或第三个读取,那么您可以使用它作为优化。例如:
0