【发布时间】:2016-03-15 23:30:42
【问题描述】:
我们正在从引脚读取一些信号,并根据这些读数设置更多事件。
为了安全起见,我想对引脚进行 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 开发板上。
编辑:
我已根据答案更改了代码,仅读取“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;
}
【问题讨论】:
-
编译器可能会优化出
for (uint32_t i = 0; i < 7; i++) dummy = i;,因为它是无操作的。改用睡眠。 -
听起来更适合 codereview.stackexchange.com
-
我认为取值的逻辑无法进一步改进。为什么你认为它效率低下?
-
如果
x == y测试z没有意义,但除此之外,它看起来对我来说非常理想。也许尽管 OP 希望函数在每次迭代中花费大致相同的时间。不过,您需要修复那个“延迟”循环。 -
您计算的是“模式”,而不是“平均值”。