[英]Mapping a number to bit position in C
I'm developing an programm running on Atmel AT90CAN128. 我正在开发在Atmel AT90CAN128上运行的程序。 Connected to this controller there are 40 devices, each with a status (on/off). 连接到该控制器的设备有40个,每个设备都有一个状态(开/关)。 As I need to report the status of each of this devices to a PC through Serial Communication, I have 40 bits, which define whether the device is on or off. 因为我需要通过串行通信向PC报告每个设备的状态,所以我有40位,用于定义设备是打开还是关闭。 In addition, the PC can turn any of this devices on or off. 此外,PC可以打开或关闭任何此设备。
So, my first attempt was to create the following struct: 因此,我的第一个尝试是创建以下结构:
typedef struct {
unsigned char length; //!< Data Length
unsigned data_type; //!< Data type
unsigned char data[5]; //!< CAN data array 5 * 8 = 40 bits
} SERIAL_packet;
The problem with this was that the PC will send an unsigned char address
telling me the device to turn on/off, so accessing the bit corresponding to that address
number turned out to be rather complicated... 问题是PC会发送一个unsigned char address
告诉我设备打开/关闭,因此访问与该address
号对应的位变得相当复杂...
So I started looking for options, and I stumbled upon the C99 _Bool
type. 所以我开始寻找选项,偶然发现了C99 _Bool
类型。 I thought, great so now I'll just create a _Bool data[40]
and I can access the address
bit just by indexing my data
array. 我以为很好,所以现在我将创建一个_Bool data[40]
,仅通过索引data
数组即可访问address
位。 Turns out that in C (or C++) memory mapping needs an entire byte for addressing it. 事实证明,在C(或C ++)中,内存映射需要一个完整的字节来对其进行寻址。 So even if I declare a _Bool
the size of that _Bool
will be 8 bits which is a problem (it needs to be as fast as possible so the more bits I send the slower it gets, and the PC will be specting 40 bits only ) and not very efficient for the communication. 所以,即使我宣布_Bool
是大小_Bool
将8位这是一个问题(它需要尽可能快地让更多的位我把它变得更慢,而PC将只 specting 40位)沟通效率也不高。 So I started looking into Bit Fields, and tried the following: 因此,我开始研究位域,并尝试了以下方法:
typedef struct {
unsigned char length; //!< Data Length
unsigned data_type; //!< Data type
arrayData data[40]; //!< Data array 5 bytes == 40 bits
} SERIAL_packet;
typedef struct {
unsigned char aux : 1;
} arrayData;
And I wonder, is this going to map that data[40]
into a consequent memory block with a size of 40 bits (5 bytes)? 我想知道,这是否会将data[40]
映射到大小为40位(5个字节)的后续存储块中?
If not, is there any obvious solution I'm missing? 如果没有,我是否有任何明显的解决方案? This doesn't seem like a very complicated thing to do (would be much simpler if there were less than 32 devices so I could use a int
and just access through a bit mask). 这似乎不是一件很复杂的事情(如果设备少于32个,将会更简单,因此我可以使用int
并通过位掩码进行访问)。
Assuming the addresses you get back are in the range 0 - 39 and that a char
has 8 bits, you can treat your data
array as an array of bits: 假设您返回的地址在0到39的范围内,并且char
具有8位,则可以将data
数组视为位数组:
| data[0] | data[1] ...
-----------------------------------------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15|
-----------------------------------------------------------------
To set bit i
: 设置位i
:
packet.data[i/8] |= (1 << (i%8));
To clear bit i
: 为了清除i
:
packet.data[i/8] &= (1 << (i%8)) ^ 0xff;
To read bit i
: 要阅读i
:
int flag = (packet.data[i/8] & (1 << (i%8)) != 0;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.