在Arduino + 74HC165 + SPI

时间:2017-01-26 08:15:48

标签: arduino bit-manipulation spi shift-register

请帮帮我。我试图通过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

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

2 个答案:

答案 0 :(得分: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)

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

答案 1 :(得分:0)

我已经找到了问题所在。 我在描绘&#34; Controls&#34;中犯了一个错误。州。 Togling正在工作,因为它应该工作。

这是正确呈现的代码:

#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,谢谢你的建议。这并没有解决问题,但有助于缩短代码。