在Arduino + 74HC165 + SPI上切换一位



请帮帮我。我正在尝试通过 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:ttControls 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("tt");  
      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

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

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

您的REG_LATCH引脚必须插入移位寄存器的引脚 1(假设我们正在谈论这个 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)

根据您想要处理位的顺序。

我已经找到了问题所在。我在描述"控件"状态时犯了一个错误。切换正在按预期工作。

这是正确呈现的代码:

#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:ttChanged:ttItems to change:tControls State:");
      print_bin_to_serial(input);
      Serial.print("tt");  
      print_bin_to_serial(changed);   
      Serial.print("tt");  
      print_bin_to_serial(items_to_change);   
      Serial.print("tt");  
      print_bin_to_serial(controls);
      Serial.println();    
  };
}

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

最新更新