如何启动两个存储16位的数组,并在C的前两个上通过XOR创建第三个数组?

问题描述 投票:0回答:1

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

当用户对要播放的声音进行编程时,例如在步骤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]

步骤3: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个回答
0
投票

以下是如何设置和清除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变成掩码而不是索引也可能是有意义的。

© www.soinside.com 2019 - 2024. All rights reserved.