CD74HC4067 作用是通過選擇達成 1 對 16 組接腳信號的讀取與寫入。更詳細的說,根據晶片上 S0-S3 四個不同接腳的組合,讓 SIG 管腳和 C0-C15 導通。因此,最常見的用法是用來測試類比信號。比如,Arduino Uno 上面只有 6 個類比輸入,用一個 CD74HC4067 可以多擴展出來 16 個,於是可以支援 6+16-1=21 個類比接腳。
這個晶片的使用方法非常簡單,例如:S0-S3 分別是 0、0、0、0 時,SIG 就和 C0 是導通的。因此,依照個個原則,我們快速地寫出這段程式碼:
//-----Mux control pins int s0=6; int s1=5; int s2=4; int s3=3; //-----Mux in "SIG" pin int SIG_pin=0; void setup() { pinMode(s0,OUTPUT); pinMode(s1,OUTPUT); pinMode(s2,OUTPUT); pinMode(s3,OUTPUT); digitalWrite(s0,LOW); digitalWrite(s1,LOW); digitalWrite(s2,LOW); digitalWrite(s3,LOW); Serial.begin(9600); } void loop() { int v; //-----Loop through and read all 16 values for(int i=0; i<16; i++) { Serial.print("Value at channel "); Serial.print(i); Serial.print(" is : "); v = readMux(i); Serial.println(v * 5.0 / 1024); } Serial.println(" "); delay(3000); } int readMux(int channel) { int controlPin[] = {s0,s1,s2,s3}; int muxChannel[16][4] = { {0, 0, 0, 0}, //-----channel 0 {1, 0, 0, 0}, //-----channel 1 {0, 1, 0, 0}, //-----channel 2 {1, 1, 0, 0}, //-----channel 3 {0, 0, 1, 0}, //-----channel 4 {1, 0, 1, 0}, //-----channel 5 {0, 1, 1, 0}, //-----channel 6 {1, 1, 1, 0}, //-----channel 7 {0, 0, 0, 1}, //-----channel 8 {1, 0, 0, 1}, //-----channel 9 {0, 1, 0, 1}, //-----channel 10 {1, 1, 0, 1}, //-----channel 11 {0, 0, 1, 1}, //-----channel 12 {1, 0, 1, 1}, //-----channel 13 {0, 1, 1, 1}, //-----channel 14 {1, 1, 1, 1} //-----channel 15 }; //-----loop through the 4 sig for(int i=0; i<4; i++) { digitalWrite(controlPin[i], muxChannel[channel][i]); } //-----read the value at the SIG pin int val = analogRead(SIG_pin); //-----return the value return val; }
發展過程中犯過的失誤或可以改進的部分
- 可支援 digital 與 analog 的讀與寫,但必須接對接腳。例如:如果需要讀取類比訊號,那 SIG 接腳就必須要接到 A0~A5 等類比接腳。
- 是否覺得這段程式太冗長了?
int muxChannel[16][4] = { {0, 0, 0, 0}, //-----channel 0 {1, 0, 0, 0}, //-----channel 1 {0, 1, 0, 0}, //-----channel 2 {1, 1, 0, 0}, //-----channel 3 {0, 0, 1, 0}, //-----channel 4 {1, 0, 1, 0}, //-----channel 5 {0, 1, 1, 0}, //-----channel 6 {1, 1, 1, 0}, //-----channel 7 {0, 0, 0, 1}, //-----channel 8 {1, 0, 0, 1}, //-----channel 9 {0, 1, 0, 1}, //-----channel 10 {1, 1, 0, 1}, //-----channel 11 {0, 0, 1, 1}, //-----channel 12 {1, 0, 1, 1}, //-----channel 13 {0, 1, 1, 1}, //-----channel 14 {1, 1, 1, 1} //-----channel 15 }; //-----loop through the 4 sig for(int i=0; i<4; i++) { digitalWrite(controlPin[i], muxChannel[channel][i]); }
如果利用 bitRead() 我們就可以簡化程式碼。digitalWrite(s0,bitRead(c,0)); digitalWrite(s1,bitRead(c,1)); digitalWrite(s2,bitRea(c,2)); digitalWrite(s3,bitRead(c,3));
所以改寫後就成了這樣int channelSelect(int c) { //----- here is select what channel that we want to digitalWrite(s0,bitRead(c,0)); digitalWrite(s1,bitRead(c,1)); digitalWrite(s2,bitRead(c,2)); digitalWrite(s3,bitRead(c,3)); return c; }