2020年1月8日 星期三

【單晶片】arduino控制74595擴充LED數量



使用arduino UNO時常常會遇到一個問題就是LED太多接腳不夠用。
為了解決這個鳥問題,如果財力夠可以直接買一個Arduino Mega2560,很貴就是了。

今天介紹這顆74595是一顆8位元 串列輸入-並列輸出 帶閂鎖移位暫存器,照字面翻就是那麼長。


動作原理


74595裡面最重要的結構就是八個D型正反器組成的移位暫存器(SRA~SRH)、八個輸出暫存器(LRA~LRH)。

  • SHIFT CLOCK:控制移位暫存器,屬於正緣觸發,當電位從0變1時會被觸發,所有SRA~SRH都會往下移,但輸出不會只因SHIFT CLOCK而改變。
  • LATCH CLOCK:輸出暫存器,屬於正緣觸發,唯有觸發LATCH CLOCK才能使輸出改變狀態。當被觸發時,SRA~SRH會將資料送入LRA~LRH,所以LRA(n+1)=SRA(n)。
  • SERIAL DATA INPUT A:輸入的串列資料,必須和SHIFT CLOCK搭配,當SHIFT CLOCK被觸發時,SERIAL DATA INPUT A會被送入SRA,所有SRA~SRH都會往下移,所以SRB(n+1)=SRA(n);SRC(n+1)=SRB(n)。
  • OUTPUT ENABLE:為0時才會輸出LRA~LRH的值,為1時會使QA~QH變為高阻抗狀態。雖然會使輸出失去作用但是並不影響串列輸入的資料,輸入的資料仍會送入SRA~SRH、LRA~LRH,串列輸出SQH也不會受影響
  • RESET:顧名思義,在正常動作的情況下必須為1,如果為0時會使SRA~SRH全部為0,但LRA~LRH仍然會保持上一個狀態,所以如果要完整的清除74595的資料必須RESET並且輸入一個脈波到LATCH CLOCK才能使輸出全部為0
  • SERIAL DATA OUTPUT SQH:如果一顆74595輸出接腳還是不夠,可以再串接很多顆74595,只要將SQH接到下一極74595再接上一樣的SHIFT CLOCK、LATCH CLOCK即可達成串接功能。





Datasheet

實驗


因為手邊的LED只有4顆,所以只有接到QA~QD,剩下的原理其實一樣。

電路



arduino程式碼

開啟序列接控視窗,輸入八個0或1,為1時LED就會亮。

void transfer_data(bool[])
送出資料。

shift_data(bool[])
會依序將data從data[0]~data[7],依照data[x]裡的位元改變74595的輸入值,並送出一個SHIFT CLOCK使的data[x]進入SRA。
當迴圈跑完時,data[0]會在QH,data[7]會在QA

to_latch()
觸發LATCH CLOCK

reset()
清除移位暫存器資料

output_enable(bool)
當en為1時74595輸出正常運作
當en為0時74595輸出高阻抗



#define PIN_RESET 2
#define PIN_SHIFT 3
#define PIN_LATCH 4
#define PIN_OUTPUT_EN 5
#define PIN_SERIAL_DATA 6


bool data[] = {0, 1, 0, 1, 1, 0, 0, 1};//QH~QA
unsigned long timer = 0;
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  output_enable(1);
  digitalWrite(PIN_RESET, HIGH);


}

void loop() {
  if (Serial.available() == 8) {
    for (int i = 0; i < 8; i++) {
      while (Serial.available() <= 0);
      int read=Serial.read();
      data[i] =(bool) (read - 0x30);
      
    }
    Serial.println("SHIFT DONE!");
  }
  transfer_data(data);

}

void transfer_data(bool data[]) {
  shift_data(data);
  to_latch();
}

void shift_data(bool data[]) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(PIN_SERIAL_DATA, data[i]);
    digitalWrite(PIN_SHIFT, HIGH);
    delay(1);
    digitalWrite(PIN_SHIFT, LOW);
  }
}

void to_latch() {
  digitalWrite(PIN_LATCH, HIGH);
  delay(1);
  digitalWrite(PIN_LATCH, LOW);
}

void output_enable(bool en) {
  digitalWrite(PIN_OUTPUT_EN, en ? LOW : HIGH);
}

void reset() {
  digitalWrite(PIN_RESET, HIGH);
  delay(1);
  digitalWrite(PIN_RESET, LOW);
}








沒有留言:

張貼留言