0

请帮我。我正在尝试通过 SPI 将 74HC165(8 位输入移位寄存器)连接到 Arduino UNO 以检查 8 个按钮的状态。响应将被处理以更改变量“控件”,但它无法正常工作。

这是代码:

#include <SPI.h>

/*  Latch contact */
enum { REG_LATCH = 8 };
int speed = 100;

/*  Variable to store the Controls state for further transfer */
static uint8_t controls = 0;

void setup()
{
  /*  Turn ON the UART  */
  Serial.begin(9600);
  /*  Turn On the SPI */
  SPI.begin();
  pinMode(REG_LATCH, OUTPUT);
  digitalWrite(REG_LATCH, HIGH);
}

void loop()
{
  /*  Storing the previous system state   */
  static uint8_t previous_input = 00000000;

  digitalWrite(REG_LATCH, LOW);
  digitalWrite(REG_LATCH, HIGH);

  /*  Read the inputs from shift register */  
  uint8_t input = SPI.transfer(0);

  /* If anything has ben changed - report to UART */

  if (input != previous_input)
    {  
      /*  Remebmer changed positions */
      uint8_t changed = input ^ previous_input;

      /*  Remember current state */
      previous_input = input;       

      Serial.println("Buttons State:\t\tControls State:");
      /* Run trough all inputs from shift register  */
      for (int i = 0; i < 8; i++)
        {   
          /* Print the state of currently checked input*/
          Serial.print(input & 1);
          /* If button is pressed and previously it was not, then  */
          if ((input & 1) & (changed & 1))
            {
              /* Highlight the current changes in system */
              Serial.print("_");                            
              /* Toggle controls in this position */
              controls = controls ^ (1 << i);
             }; /*Otherwise do nothing*/

          /*  Move to next bit of inputs. */
          input >>= 1;
          changed >>= 1;
        };

      Serial.print("\t\t");  
      for (int i = 0; i < 8; i++)
        {   
          /* Print current control  */
          Serial.print(controls);
          controls >>= 1;
        }
      Serial.println();       
  }
}

以及它写入串行的内容:

1) 按下按钮 1 后:

Buttons State:      Controls State:
1_0000000       10000000

2) 发布时:

Buttons State:      Controls State:
00000000        00000000

3) 按下按钮 7 后:

Buttons State:      Controls State:
0000001_0       64321684210

4) 发布后:

Buttons State:      Controls State:
00000000        00000000

5) 按下按钮 1 后:

Buttons State:      Controls State:
1_0000000       10000000

6) 发布时:

Buttons State:      Controls State:
00000000        00000000

它应该如何工作:

1) 按下按钮 1 后:

Buttons State:      Controls State:
    1_0000000       10000000

2) 发布后:

Buttons State:      Controls State:
    00000000        10000000

3) 按下按钮 7 后:

Buttons State:      Controls State:
0000001_0       10000010

4) 发布后

Buttons State:      Controls State:
00000000        10000010

5) 下一次按下按钮 1 后:

Buttons State:      Controls State:
    1_0000000       00000010

6) 发布后:

Buttons State:      Controls State:
    00000000        00000010

请帮帮我。我究竟做错了什么?

4

2 回答 2

0

我已经弄清楚了问题所在。我在描述“控制”状态时犯了一个错误。切换工作正常。

这是正确呈现的代码:

#include <SPI.h>

/*  -----------------------------------------------------------------------  */
/*  Global System variables                                                  */
/*  -----------------------------------------------------------------------  */

/*  Storing the previous system state */
static uint8_t previous_input = 0;
/*  Variable to store the Controls state for further transfer */
static uint8_t controls = 0;
/*  -----------------------------------------------------------------------  */
/*   Configuration of shift input register 74HC165  */
/*  Latch contact */
enum { REG_LATCH = 8 };
/*  -----------------------------------------------------------------------  */

void setup()
{
  /*  Turn ON the UART  */
  Serial.begin(9600);
  /*  Turn On the SPI */
  SPI.begin();
  pinMode(REG_LATCH, OUTPUT);
  digitalWrite(REG_LATCH, HIGH);
}

/*  -----------------------------------------------------------------------  */

void print_bin_to_serial(int digit){
/* Run trough all inputs from shift register  */
      for (int i = 0; i < 8; i++)
        {   
          /* Print the state of currently checked input*/
          Serial.print(((digit << i) >> 7) & 1);
        };
}

/*  -----------------------------------------------------------------------  */

void loop()
{     
  digitalWrite(REG_LATCH, LOW);
  digitalWrite(REG_LATCH, HIGH);
  /*  Read the inputs from shift register */  
  uint8_t input = SPI.transfer(0);  

  /* If anything has ben changed - report to UART */
  if (input != previous_input)
    {  
      /*  Remember changed positions */
      uint8_t changed = input ^ previous_input;
      /*  Remember current state */
      previous_input = input;       
      /*  Fixing, what positions had to be switched  */
      uint8_t items_to_change = (input & changed);
      controls ^= items_to_change;
      /* Code is just for printing */      
      Serial.println("Buttons State:\t\tChanged:\t\tItems to change:\tControls State:");
      print_bin_to_serial(input);
      Serial.print("\t\t");  
      print_bin_to_serial(changed);   
      Serial.print("\t\t");  
      print_bin_to_serial(items_to_change);   
      Serial.print("\t\t");  
      print_bin_to_serial(controls);
      Serial.println();    
  };
}

@Tom,感谢您的建议。这并没有解决问题,但有助于缩短代码。

于 2017-01-26T18:46:24.020 回答
0

首先检查您的移位寄存器是否连接正确。区分硬件问题和软件问题的最佳方法是将示波器插入移位寄存器的输出引脚。

您的 REG_LATCH 引脚必须插入移位寄存器的 pin1(假设我们正在谈论这个http://www.nxp.com/documents/data_sheet/74HC_HCT165.pdf)。

它的工作方式是您必须将此引脚拉下,传输数据然后将其拉起。因此,顺序是:

  digitalWrite(REG_LATCH, LOW);
  /*  Read the inputs from shift register */  
  uint8_t input = SPI.transfer(0);
  digitalWrite(REG_LATCH, HIGH);

然后,我不会在循环中移动索引并更改,而是使用它:

input & i
changed & i

或者

input & (7 - i)
changed & (7 - i)

取决于您想要处理您的位的顺序。

于 2017-01-26T08:39:02.003 回答