簡體   English   中英

將數字映射到C中的位位置

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM