长话短说,我目前正在用C ++编写C ++包装器,用于提取嵌入式系统寄存器的值。为了监控发生的情况,我需要为某些寄存器读取一个位的值,并为每个寄存器创建一个getter。
基本上,我希望我的方法从存储到uint16_t变量中的位返回一个bool。在一个'天真'和没有咖啡因的方法我做了类似的事情:
bool getBusyDevice(int fd) // fd stands for file descriptor, for each instance of the class
{
uint16_t statusRegVal = 0;
get_commandReg(fd, &statusRegVal); // C-library function to get the value of status register
uint16_t shift = 0; // depends on the bit to access - for reusability
bool Busy = (bool) (statusRegVal >> shift);
return busy;
}
我对结果不太满意,我想知道是否有“正确”的方法来做到这一点......
非常感谢您的建议!
答案 0 :(得分:5)
获得一位的正常方法是使用按位和运算符&
。像例如statusRegVal & bitValue
。如果设置了该位,则结果将等于bitValue
,这意味着要获得布尔结果,您可以进行简单的比较:statusRegVal & bitValue == bitValue
。
因此,如果要检查是否设置了位0(值为0x0001
),那么您可以简单地执行
return statusRegVal & 0x0001 == 0x0001;
答案 1 :(得分:1)
为什么不使用模板:
template<int SHIFT>
bool boolRegVal(uint16_t val) {
return val & (1 << SHIFT);
}
然后用法:
boolRegVal<4>(statusRegVal);
答案 2 :(得分:1)
为了更好地了解您的需求,请查看以下链接
掩蔽:https://en.wikipedia.org/wiki/Mask_(computing) 和
位操作:https://en.wikipedia.org/wiki/Bit_manipulation
结论:
如果要读取变量(寄存器)中的特定位数,则应使用具有位位置的变量进行MASK。
说你有2Byte变量(u16Reg)并且你想读取位[5,7]所以,
value = ((u16Reg & 0x00A0) >> 5)
。
在您的情况下,您想要读取一位并返回状态 TRUE 或 FALSE 。
value = ((u16Reg & (0x0001 << n)) >> n)
其中n是您要读取的位数。
让我们理解它。 说u16Reg = 0x529D = 0b0101001010011101; bit [0] = 1且bit [15] = 0;你想获得第9位。 因此,首先要确保除了你的所有位都是零(9)。
(0b0101001010011101 & (0x0001 << 9)) =
(0b0101001010011101 & 0x0200) =
(0b0101001010011101 & 0b0000001000000000) =
(0b0000001000000000) = 0x0200
这意味着如果您的意思是nonZero为TRUE,则为TRUE。但如果TRUE表示0x01,则应将此位移至位[0],如下所示:
(0x0200 >> 9) = 0x0001
为真
如果你能理解这一点,你可以更简单地说:
value = ((u16Reg >> n) & 0x0001)
答案 3 :(得分:0)
铸造bool不会有帮助,因为它不是1位类型。 你必须清理剩下的部分,然后检查你是否有0。
您可以这样做:
bool Busy = ((statusRegVal >> shift) & 1) ? true : false;
答案 4 :(得分:0)
标准库提供了用于操作位的std :: bitset。这是一个例子,但我相信你能猜出它的作用。
#include <bitset>
#include <iostream>
using namespace std;
int main(int, char**){
typedef bitset<sizeof(int)*8> BitsType; //or uint16_t or whatever
BitsType bits(0xDEADBEEF);
for(int i = 0; i < 5; ++i) //access the bits
cout << "bits[" << i << "] = " << bits[i] << '\n';
cout << "bit[3] = " << bits[3] << '\n'; //original
bits.flip(3);
cout << "bit[3] = " << bits[3] << '\n'; //b[3] = !b[3]
return 0;
}
操作符[](size_t)
被重载以返回引用,因此您也可以分配它。例如bits[4] = false
。最后,当玩完你的位:)你可以转换回长(或ulong)或在你的情况uint16_t value = static_cast<uint16_t>(bits.to_ulong())
。感谢stdlib。