- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
目前遇到一个技术问题,想改进之前的实现,情况是:
我有 5 个 GPIO 引脚,我需要使用这些引脚作为硬件标识符,例如:
pin1: LOW
pin2: LOW
pin3: LOW
pin4: LOW
pin5: LOW
这意味着我的硬件变体之一,因此我们可以有多种组合。在之前的设计中,开发者使用if-else
来实现,就像:
if(PIN1 == LOW && ... && ......&& PIN5 ==LOW)
{
HWID = variant1;
}
else if( ... )
{
}
...
else
{
}
但是我觉得这样不好,因为它会有200多个变体,而且代码会变得很长,我想把它改成一个mask。我的想法是将这五个引脚视为一个五位寄存器,因为我可以根据 GPIO 状态预测我需要分配哪个变体(这已经由硬件团队定义,他们提供了一个变体列表,其中包含所有这些 GPIO 引脚配置) ,因此,代码可能如下所示:
enum{
variant 0x0 //GPIO config 1
...
variant 0xF3 //GPIO config 243
}
然后我可以先读取这五个 GPIO 引脚状态,然后与某个掩码进行比较,看它们是否相等。
问题
但是对于GPIO来说,它有三种状态,分别是:LOW、HIGH、OPEN。有什么好的计算方法可以得到一个3D掩模吗?
最佳答案
您有 5 个引脚,每个引脚有 3 个状态。您可以通过几种方式来表示这一点。
首先,想象一下使用这种框架:
#define LOW (0)
#define HIGH (1)
#define OPEN (2)
uint16_t config = PIN_CONFIG(pin1, pin2, pin3, pin4, pin5);
if(config == PIN_CONFIG(LOW, HIGH, OPEN, LOW, LOW))
{
// do something
}
switch(config) {
case PIN_CONFIG(LOW, HIGH, OPEN, LOW, HIGH):
// do something;
break;
}
uint16_t config_max = PIN_CONFIG(OPEN, OPEN, OPEN, OPEN, OPEN);
uint32_t hardware_ids[config_max + 1] = {0};
// init your hardware ids
hardware_ids[PIN_CONFIG(LOW, HIGH, HIGH, LOW, LOW)] = 0xF315;
hardware_ids[PIN_CONFIG(LOW, LOW, HIGH, LOW, LOW)] = 0xF225;
// look up a HWID
uint32_t hwid = hardware_ids[config];
此代码正是您想要对引脚配置进行的那种操作。唯一需要实现的是 PIN_CONFIG
第一种方法是继续将其用作位域,但不是每个引脚 1 位,而是使用 2 位来表示每个引脚状态。我认为这是最干净的,即使您为每个引脚“浪费”了一半。
#define PIN_CLAMP(x) ((x) & 0x03)
#define PIN_CONFIG(p1, p2, p3, p4, p5) \\
(PIN_CLAMP(p1) & \\
(PIN_CLAMP(p2) << 2) & \\
(PIN_CLAMP(p3) << 4) & \\
(PIN_CLAMP(p4) << 6) & \\
(PIN_CLAMP(p5) << 8))
这有点不错,因为如果您稍后要进行搜索,它会为“无关”或“无效”值留出空间。
或者,您可以使用算术运算,确保使用所需的最少位数。也就是说,~1.5 位来编码 3 个值。正如预期的那样,这从 0 到 242 总共有 3^5=243 个状态。在不了解您的情况的情况下,我相信这是您的引脚状态的最小完整编码。(实际上,您必须使用 8 位来编码 243 个值,因此每个引脚高 1.5 位)
#define PIN_CLAMP(x) ((x) % 3) /* note this should really assert */
#define PIN_CONFIG(p1, p2, p3, p4, p5) \\
(PIN_CLAMP(p1) & \\
(PIN_CLAMP(p2) * 3) & \\
(PIN_CLAMP(p3) * 9) & \\
(PIN_CLAMP(p4) * 27) & \\
(PIN_CLAMP(p5) * 81))
如果你不喜欢预处理器的东西,你可以使用像这样的函数:
enum PinLevel (low = 0, high, open);
void set_pin(uint32_t * config, uint8_t pin_number, enum PinLevel value) {
int shift = pin_number * 2; // 2 bits
int mask = 0x03 << shift; // 2 bits set to on, moved to the right spot
*config &= ~pinmask;
*config |= (((int)value) << shift) & pinmask;
}
enum PinLevel get_pin(uint32_t config, uint8_t pin_number) {
int shift = pin_number * 2; // 2 bits
return (enum PinLevel)((config >> shift) & 0x03);
}
这遵循第一种(每个值 2 位)方法。
使用 C 的酷位域语法的另一种方式:
struct pins {
uint16_t pin1 : 2;
uint16_t pin2 : 2;
uint16_t pin3 : 2;
uint16_t pin4 : 2;
uint16_t pin5 : 2;
};
typedef union pinconfig_ {
struct pins pins;
uint16_t value;
} pinconfig;
pinconfig input;
input.value = 0; // don't forget to init the members unless static
input.pins.pin1 = HIGH;
input.pins.pin2 = LOW;
printf("%d", input.value);
input.value = 0x0003;
printd("%d", input.pins.pin1);
union 让您可以将位域视为数字,反之亦然。
(注意:所有代码都完全未经测试)
关于c - 如何制作 3D 面具,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29246416/
我正在尝试在图像上绘制蒙版,蒙版是 body-pix (在 NodeJS 中)完成的处理的结果。出于性能原因,我想使用 OpenCV 来绘制蒙版,而不是 htmlcanva。 const se
在我的数据框中,我想用 nan 替换低于 1 和高于 5 的每个值。 此代码有效 persDf = persDf.mask(persDf 5)) 我不知道为什么会这样。我已经检查了手册页和关于明显类
我正在使用 Explaining and Harnessing Adversarial Examples 中的 FGSM 方法实现对抗性训练使用自定义损失函数: 使用自定义损失函数在 tf.keras
我有以下功能: def delta(r, dr): res = np.zeros(r.shape) mask1 = (r >= 0.5*dr) & (r = 0.5*dr) & (r <=
我有一个给定的数据框,我希望每一行都能够选择高于该行给定百分位数的值。 让我们考虑这个数据框: df = pd.DataFrame({'A' : [5,6,3,4, 0,5,9], 'B' : [1,
目前遇到一个技术问题,想改进之前的实现,情况是: 我有 5 个 GPIO 引脚,我需要使用这些引脚作为硬件标识符,例如: pin1: LOW pin2: LOW pin3: LOW pin4: LOW
我有一个字典,其中包含多个 pandas 掩码作为特定数据帧的字符串,但我找不到使用这些掩码的方法。 这是一个简短的可重现示例: df = pd.DataFrame({'age' : [10, 24,
我有一个 bool 掩码列表,该列表是通过将不同的搜索条件应用于数据框而获得的。这是一个包含 4 个掩码的示例列表: mask_list = [mask1, mask2, mask3, mask4]
我在 pandas 掩码子集上执行了一项任务: pdxy = pd.DataFrame(data,columns=['X','Y','C','CC']) mask = pdxy[:]['Y']==8
所以我有一个输入,默认情况下我希望它的值为 0.00。很简单。 当用户开始输入时,我想从右边开始填充。所以当他们输入“5”时,输入将显示“0.05”。然后他们输入一个零,输入变为“0.50”,依此类推
我是一名优秀的程序员,十分优秀!