[英]Mapping a number to bit position in C
我正在開發在Atmel AT90CAN128上運行的程序。 連接到該控制器的設備有40個,每個設備都有一個狀態(開/關)。 因為我需要通過串行通信向PC報告每個設備的狀態,所以我有40位,用於定義設備是打開還是關閉。 此外,PC可以打開或關閉任何此設備。
因此,我的第一個嘗試是創建以下結構:
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;
問題是PC會發送一個unsigned char address
告訴我設備打開/關閉,因此訪問與該address
號對應的位變得相當復雜...
所以我開始尋找選項,偶然發現了C99 _Bool
類型。 我以為很好,所以現在我將創建一個_Bool data[40]
,僅通過索引data
數組即可訪問address
位。 事實證明,在C(或C ++)中,內存映射需要一個完整的字節來對其進行尋址。 所以,即使我宣布_Bool
是大小_Bool
將8位這是一個問題(它需要盡可能快地讓更多的位我把它變得更慢,而PC將只 specting 40位)溝通效率也不高。 因此,我開始研究位域,並嘗試了以下方法:
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;
我想知道,這是否會將data[40]
映射到大小為40位(5個字節)的后續存儲塊中?
如果沒有,我是否有任何明顯的解決方案? 這似乎不是一件很復雜的事情(如果設備少於32個,將會更簡單,因此我可以使用int
並通過位掩碼進行訪問)。
假設您返回的地址在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|
-----------------------------------------------------------------
設置位i
:
packet.data[i/8] |= (1 << (i%8));
為了清除i
:
packet.data[i/8] &= (1 << (i%8)) ^ 0xff;
要閱讀i
:
int flag = (packet.data[i/8] & (1 << (i%8)) != 0;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.