将字节的位转换为单个位并返回

标签 c bit-manipulation bitwise-operators stm32

我有下面的结构

typedef struct fpButtons {

  /**     BYTE 0         **/        
  uint8_t       button_1:1;       
  uint8_t       button_2:1;
  uint8_t       button_3:1;
  uint8_t       button_4:1;
  uint8_t       button_5:1;
  uint8_t       button_6:1;
  uint8_t       button_7:1;
  uint8_t       button_8:1;

  /** And BYTE 2 which I didn't paste to save SO's space lol **/
  // button_9:1 to button_16:1
} FP_BUTTONS;

这个函数给出一个无符号整数,它的位应该构建上面的结构

void FP_UpdateData(FP_BUTTONS *data, uint8_t b1, uint8_t b2) 
{
  data->button_1 = (b1 & ( 1 << 1 )) >> 1;
  data->button_2 = (b1 & ( 1 << 2 )) >> 2;
  data->button_3 = (b1 & ( 1 << 3 )) >> 3;
  data->button_4 = (b1 & ( 1 << 4 )) >> 4;
  data->button_5 = (b1 & ( 1 << 5 )) >> 5;
  data->button_6 = (b1 & ( 1 << 6 )) >> 6;
  data->button_7 = (b1 & ( 1 << 7 )) >> 7;
  data->button_8 = (b1 & ( 1 << 8 )) >> 8;

  //Do the same thing for button 9 to 16

}

现在存储后,我必须将它发送到其他地方:

void APP_Send(){

  uint8_t packet[2];

  packet[0] = *((uint8_t*) &FP_BUTTONS_Data);
  packet[1] = *(((uint8_t*) &FP_BUTTONS_Data)+1);    

  //Send stuff away.....
}

尽管付出了所有努力,但上面的代码似乎都不起作用。我在嵌入式处理器上做这件事,它真的很难调试。我想知道是否有一些 C 专家可以告诉我这些代码有什么问题?

最佳答案

位是从 0 开始索引的,但是您将移位编码为好像位是从 1 开始索引的。对于 uint8_t 的转换,您必须使用 07

此外,可以删除右移。

试试这个:

void FP_UpdateData(FP_BUTTONS *data, uint8_t b1, uint8_t b2) 
{
  data->button_1 = (b1 & ( 1 << 0 )) != 0;
  data->button_2 = (b1 & ( 1 << 1 )) != 0;
  data->button_3 = (b1 & ( 1 << 2 )) != 0;
  data->button_4 = (b1 & ( 1 << 3 )) != 0;
  data->button_5 = (b1 & ( 1 << 4 )) != 0;
  data->button_6 = (b1 & ( 1 << 5 )) != 0;
  data->button_7 = (b1 & ( 1 << 6 )) != 0;
  data->button_8 = (b1 & ( 1 << 7 )) != 0;

  //Do the same thing for button 9 to 16
}

void APP_Send()
{
  uint8_t packet[2];

  uint8_t *data = (uint8_t*) &FP_BUTTONS_Data;
  packet[0] = data[0];
  packet[1] = data[1];

  //Send stuff away.....
}

话虽如此,如果您将结构数据包装在 union 中,那么所有这些手动移位都是不必要的:

typedef struct fpButtons {

  /**     BYTE 0         **/        
  union {
    struct {
      uint8_t       button_1:1;       
      uint8_t       button_2:1;
      uint8_t       button_3:1;
      uint8_t       button_4:1;
      uint8_t       button_5:1;
      uint8_t       button_6:1;
      uint8_t       button_7:1;
      uint8_t       button_8:1;
    };
    uint8_t         rawbuttons_1;
  };

  /**     BYTE 1         **/        
  union {
    struct {
      uint8_t       button_9:1;       
      uint8_t       button_10:1;
      uint8_t       button_11:1;
      uint8_t       button_12:1;
      uint8_t       button_13:1;
      uint8_t       button_14:1;
      uint8_t       button_15:1;
      uint8_t       button_16:1;
    };
    uint8_t         rawbuttons_2;
  };

} FP_BUTTONS;

void FP_UpdateData(FP_BUTTONS *data, uint8_t b1, uint8_t b2) 
{
  data->rawbuttons_1 = b1;
  data->rawbuttons_2 = b2;
}

void APP_Send()
{
  uint8_t packet[2];

  packet[0] = FP_BUTTONS_Data.rawbuttons_1;
  packet[1] = FP_BUTTONS_Data.rawbuttons_2;

  //Send stuff away.....
}

关于将字节的位转换为单个位并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30541378/

相关文章:

javascript - javaScript 中的类 C 代码片段定义

c - 汇编中的静态和非静态变量

c - 将位从一个字节移到一个(数组)

sql-server - SQL Server 中的按位运算

c++ - C++ 中 (n & 1 << b) 的含义

c# - 按位运算符让我见鬼去吧

C:可以反转字符数组,但不能反转字符串

c++ - size_t 类型变量的跨平台格式字符串?

javascript - 如何在按位运算期间 chop 大整数以模仿 Ruby 中的 JavaScript?

使用文件指针的 C++ 位移位