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;
}