使用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);
}



沒有留言:
張貼留言