【问题标题】:How to initiate two arrays storing 16 bits each and creating a third array by XOR on the first two in C?如何启动两个数组,每个数组存储 16 位,并通过 XOR 对 C 中的前两个数组创建第三个数组?
【发布时间】:2019-09-08 16:20:24
【问题描述】:

我正在构建鼓机,我想要两个 16 位数组来定义机器的状态。一个数组“current_led”,在对应于当前播放的第 16 个音符的索引处设置了 1。

当用户对要播放的声音进行编程时,例如在第 1 步和第 4 步,我希望一个 16 位数组“selected_steps”在索引 0 和 3 处设置 1。

所以我希望,在每分钟节拍定义的每一步更新中,“current_led”移动位,但“selected_steps”是静态的。

我想要一个由

构造的最终数组“led_array”
led_array = XOR(selected_steps,current_led)

这样我就可以在每一步更新时使用移位寄存器来点亮正确的 LED。

但是由于我在 C 中定义和使用位和数组时遇到了一些麻烦,所以我不明白如何正确初始化数组并使用它们。

我想要的东西像

  int current_led[16];
  int selected_steps[16];
  int led_array[16];

  //Function is called every 0.5 s if BPM 120.
  void step(void) {
  step_number = step_number < 15 ? step_number +1 : 0;
  }

我正在使用 2 个 PISO 移位寄存器将 16 个按钮的输入输入到我的微控制器。我将并行负载引脚设置为高电平,这样每当用户按下按钮时,移位寄存器上的相应引脚设置为 1。因此我每次都读取每 16 个引脚以查看用户是否按下了任何按钮。

  //Check which steps are selected by the user. This function is called every 1 ms
  void scan_buttons() {
  for (int j = 0; j<16 ; j++) {
      if (PIND & 0b01000000){
            selected_steps[j] = 1;
            } else {
            selected_steps[j] = 0;
        }


  void update_led(void) {
     current_led = (1 << step_number);
     led_array = current_led^selected_steps;

     for (int j = 15; j>=0 ; j--) {
        if (led_array[j] == 1) {
           do something...
        } else {
           do something else...
        }
     }
  } 

为了清楚起见,下面是一个 LED 应如何表示该状态的示例。 如果 BPM 设置为 120,并且我们有 16 步(4 节拍),则步长应每 60/BPM 秒(0.5 秒)递增。当前步骤由一个明亮的 LED 指示。我还通过始终让 LED 在当前步骤亮起来向用户指示他/她在哪个步骤上编程了声音。

第 1 步:step_number = 0

LED: [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

第 2 步:step_number = 1

LED: [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

第三步:step_number = 2, selected_step[7] = 1, selected_step[11] = 1,

(用户在步骤 8 和 12 中选择通过按下按钮 8 和 12 输入声音)

LED: [0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0]

第 4 步:step_number = 3,selected_step[7] = 1,selected_step[11] = 1,

(自上一步以来用户没有按下任何按钮)

LED: [0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0]

但我不明白如何声明数组,以及编写正确的代码以正确设置位并执行 XOR 操作。

标签: c arrays xor


【解决方案1】:

以下是您可以如何设置和清除 uint16_t 中的位(对于任何无符号整数也是如此,只需相应地更改类型)

我已经很久没有做任何位操作了,所以你应该仔细检查一下 在你使用它之前,没有任何时间自己做。

/* 
   `set_bits`, `unset_bits` and `flip_bits` modifies multiple bits in v.

    The bits you want to modify are selected by setting the corresponding bit
    in `mask` to 1.
*/

uint16_t set_bits(uint16_t v, uint16_t mask)
{
   return v | mask;
}

uint16_t unset_bits(uint16_t v, uint16_t mask)
{
   return v & ~mask;
}

uint16_t flip_bits(uint16_t v, uint16_t mask)
{
   return v | ((~v) & mask)
}

/* 
 `set_bit`, `unset_bit`, `flip_bit`, `overwrite_bit` modifies a single bit in `v`.
 The bit to modify is given by the index `i`
*/

uint16_t set_bit(uint16_t v, int i)
{
   return set_bits(v, 1 << i);
}

uint16_t unset_bit(uint16_t v, int i)
{
   return unset_bits(v, 1 << i);
}

uint16_t flip_bit(uint16_t v, int i)
{
   return flip_bits(v, 1 << i);
}

uint16_t overwrite_bit(uint16_t v, int i, int new_val)
{
   /* ensure `new_val` is either 0 or 1 */
   new_val = new_val ? 1 : 0;

   uint16_t mask = 1 << i;
   uint16_t mask_x = ~mask; 

   uint16_t nv = new_val << i;

   return v & (mask_x | nv);
}

int read_bit(uint16_t v, int i)
{
   uint16_t mask = 1 << i;
   return (v & mask) ? 1 : 0;
}  


/* How to initialize all the bits in `selected_steps` to zero */
selected_steps = 0;

/* How to initialize all the bits in `selected_steps` to 1 */
selected_steps = 0xffff;  /* or  = 0b1111111111111111 */ 


/* How to read the value of bit 8 in `selected_step` */

int val = read_bit(selected_steps, 8);

/* How to set the value of bit 8 to 1 */
selected_steps = set_bit(selected_steps, 8);
/* or */
selected_steps = overwrite_bit(selected_steps, 8, 1);
/* or */
selected_steps = set_bits(selected_steps, 0b100000000);


/* How to set the value of bit 8 to 0 */
selected_steps = unset_bit(selected_steps, 8);
/* or */
selected_steps = overwrite_bit(selected_steps, 8, 0);
/* or */
selected_steps = unset_bits(selected_steps, 0b100000000);

/* Setting bits 1 and 4 to 1 */
selected_steps = set_bits(selected_steps, 0b10010);
/* or */
selected_steps = set_bits(selected_steps, (1<<4) | (1<<1));

/* Calculating xor of two bitsets */
uint16_t xor_a_b = a ^ b;

根据您的用例,您可以选择将这些函数定义为static inline。将step_number 转换为掩码而不是索引也可能有意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    相关资源
    最近更新 更多