步驟1:晶體管背景
晶體管起著多種作用,但它們基本上是電子開關。這正是我們將如何使用它們進行多路復用的方法。
我實際上并不會研究它們的工作原理或其他任何東西,而只是將其視為電子開關。我將使用NPN晶體管,這是最常用的晶體管。有一個發(fā)射極,一個基極和一個集電極,確保將電路組合在一起時知道哪個引腳。電流從集電極流向發(fā)射極,而基極則啟用/禁用該電流。實際上,這就是使它成為開關的原因。如果您要使用兩個不同的電源或需要大量電流,這也很有用。由于底座與收集器和發(fā)射器是分開的,因此可以單獨供電。這有什么用?那么,所有微控制器都有一個數字引腳(GPIO)最大輸出電流,通常不會超過200mA。如果一次有多個LED亮起,則可能超過200mA,這對微控制器不利。因此,使用晶體管,微控制器無需向實際組件(例如LED)提供電流。與復用無關,但您也可以使用晶體管讓微控制器控制不同的電源以及繼電器的使用方法。上面的第二幅圖是使用晶體管的陽極和陰極原理圖的基本原理圖。 (注意:不需要陽極電路上的電容器)。該電路實際上不是陽極或陰極,但是我這樣稱呼它們是因為陽極電路的輸出連接到LED的陽極。而陰極電路連接到LED的陰極。 LED的陽極是電流進入組件的地方,陰極是電流離開組件的地方。因此,當然,陽極晶體管電路為VCC提供電源,陰極晶體管電路為地提供電源。
我正在使用的晶體管:http://www.taydaelectronics.com/2n3904-npn-general-propose-transistor.html
步驟2:多路復用
多路復用時,將其視為行和列,具體取決于您的處理方式(在本例中為LEDs)您總是會有行和列。在最后一步,您看到了陽極和陰極的示意圖,一個是行,另一個是列。
此步驟中的圖片顯示了一組9個LED,共有3行和3列。行和列無關緊要,它們的順序是什么,或者陽極/陰極是哪一個,但是硬件必須與軟件匹配!對于圖片,該行是該列上的“主要”。我的意思是,如果您查看這些步驟,則將一行設置為亮,而將某些列設置為為LED供電。怎么做?好吧,根據代碼的不同,您需要做一個“顯性的”,我這樣做是通過讓行函數每次行更改時都調用列函數來實現的。
由于有3個步驟,最終圖像顯示“您看到的內容” , 這是如何運作的?好吧,如果發(fā)生這種變化,每隔1毫秒說一次,那么人眼就無法分辨出差異,這與電視上的刷新率或每秒幀數非常相似。因此,實際上一次只能打開一排LED,但在眼睛上它們似乎一次都亮著。
當您添加更多的行和列時,多路復用率會進一步提高!假設您想要一個16 x 16的顯示屏,即256個LED。使用16行,16列的多路復用,因此32個引腳可控制256個LED! 32仍然是很多數字引腳(Arduino只有12 。..),但是您可以在其中使用移位寄存器使用更少的引腳。
現在,這確實帶來了一個問題,以便不斷查看此圖像。代碼必須每隔幾毫秒不斷更改行,以便所有行都處于打開狀態(tài)。因此,延遲等功能無法與多路復用一起使用。不幸的是,Arduino代碼似乎嚴重依賴于延遲。..解決方案?使用最后一個示例中的Atmega328s計時器/計數器,您可以看到實現計時器之一的代碼。
步驟3:制作多路復用原理圖
您需要確定要作為陽極或陰極的行/列,但實際上并不重要。在示意圖中,我選擇了行作為陽極,列選擇了陰極。
在示意圖中,由于行是陽極,所以LED陽極的每一行都連接到陽極彼此。列的情況相同,LED的所有陰極都已連接。
多路復用與將LED直接連接至引腳的真正不同之處在于控制接地的方式。如果僅將LED連接到引腳,則LED的陰極通常連接到公共接地。通過多路復用電路,微控制器控制接地的可用性。這使您可以禁用整個行或列,因為該電路由于沒有接地而無法完成。
在任何情況下,這都是理想的電路,但是對于陽極,您不一定需要一個晶體管。如果您想使用微控制器并從中汲取電流,則可以直接將引腳連接到LED的陽極。但是,這并不理想,因為您從微控制器汲取電流,就像我在步驟1中所說的那樣,微控制器具有最大的電流供應。陽極不一定需要一個晶體管,但陰極必須有一個。您仍然需要啟用/禁用地面才能使多路復用工作。
第二張圖片顯示的原理圖與我在示例中使用的物理電路幾乎相同。下一步將顯示如何編寫用于復用的程序。
步驟4:復用代碼
要實現復用,您將需要編寫代碼以某種方式。實際上并沒有那么復雜,可以說行在列上是“主要的”。這意味著單行晶體管導通,而該行的列運行一次。之后,您移至下一行并一次又一次地執(zhí)行相同操作,直到重復為止!
刷新LED的速度不夠快而無法注意到的問題是您無法擁有同步系統(tǒng)。這意味著您不能有長時間持續(xù)的延遲。因此,如果您有1秒的延遲,那么行和列所在的位置將只在整個整秒鐘顯示一次。
最簡單的方法是使用兩個函數,其中一個函數重復調用另一個函數。由于在這種情況下行是列的“主要”,我們將有兩個函數可以調用它們:
-Display_LED()
-Column_Load()
所以這是一些sudo代碼:
無效Display_LED(char a,char b,char c)
{
Column_Load(a);
digitalWrite(transistor_pin1,HIGH);
delay(1);
digitalWrite(transistor_pin1,LOW);
//根據行數重復
}
因此,上面的Display_LED函數是行的“顯性”函數。同樣,您可以使用行或列作為主導,這并不重要。首先,您調用列函數來設置這些晶體管的開或關。然后將某個行晶體管設置為高電平。我的延遲很短,所以LED亮了1ms。如果將其更改為1000毫秒,您實際上可以看到每個更改。這就是為什么您不能在程序的其余部分中使用延遲的原因。從那里關閉晶體管,并重復從a到b的代碼,然后切換到第二行。
void Column_Load(char LEDs)
{
如果(LEDs_on == 0x07)
{
digitalWrite(colum1_transistor,HIGH)
digitalWrite(colum2_transistor,HIGH)
digitalWrite(colum3_transistor,HIGH)
}
}
此函數非常簡單,具體取決于值參數是否已按照需要設置LED。如果您使用PORT_和DDR_,那么編寫代碼實際上比使用digitalWrites簡單。在大多數情況下,我將vale設置為十六進制值,因此,如果我輸入0x03,這意味著LED 1和3在2處于關閉狀態(tài)時都打開。
下一步是使用上述以下功能的3x3 LED陣列示例。唯一的區(qū)別是行和列是相反的。
步驟5:3 x 3 LED顯示示例
示例代碼:
您可以使用以下代碼查看帶有LED指示燈的圖片。該代碼也作為.ino文件附加。點亮的LED由0x02,0x05,0x02設置。這些十六進制值的十進制表示形式是00000010,00000101,00000010。您可以查看這些值如何與顯示匹配。
如果您想自己嘗試一下,下面提供了代碼,只需復制第3步中的電路即可!
/*晶體管多路復用3x3 LEDs
通過: Marty Peltz
日期:2013年7月19日
目的:使用多路復用以3x3模式控制9個LED。
用于Martin Peltz的Instructiable
*/
/****變量* ***/ char col1_cathode = 0;
char col2_cathode = 1; char col3_cathode = 2;
char row1_anode = 3;
char row2_anode = 4;
char row3_anode = 5;
void setup()
{
//將引腳設置為輸出
pinMode(col1_cathode,OUTPUT);
pinMode(col2_cathode,OUTPUT);
pinMode(col3_cathode,OUTPUT) );
pinMode(row1_anode,OUTPUT);
pinMode(row2_anode,OUTPUT);
pinMode(row3_anode,OUTPUT);
//關閉所有GPIO引腳
digitalWrite(col1_cathode,LOW) );
digitalWrite(col2_cathode,LOW);
digitalWrite(col3_cathode,LOW);
digitalWrite(row1_anode,LOW);
digitalWrite(row2_anode,LOW);
digitalW rite(row3_anode,LOW);
}
無效循環(huán)()
{
display_LED(0x02,0x05,0x02);
}
/****顯示LED功能* ***/
/*用途:使用要顯示的十六進制參數調用此函數
*注意:此函數控制陰極,在我的情況下控制列
*/
void display_LED (字符c1,字符c2,字符c3)
{
row_anode(c1);//用第一個十六進制值調用row_anode
digitalWrite(col1_cathode,HIGH);//顯示第一列
delay(1);//等待一小段延遲,以便LED亮起1ms
digitalWrite(col1_cathode,LOW);//禁用第一列,然后繼續(xù)
row_anode(c2);//用第二個十六進制值調用row_anode
digitalWrite(col2_cathode,HIGH);//顯示第二列
delay(1);//等待一小段延遲,以便LED點亮1ms。
digitalWrite(col2_cathode,LOW);//禁用第二列,然后繼續(xù)
row_anode(c3);//用第二個十六進制值調用row_anode
digitalWrite(col3_cathode,HIGH);//顯示第三列
delay(1);//等待一小段延遲,以便LED亮起1ms
digitalWrite(col3_cathode,LOW);//禁用第三列,然后繼續(xù)操作
//(請注意,嘗試將1ms更改為100ms-1s,您會看到不同)
}
/****陰極(列)功能** **/
/*目的:取參數值并打開相關的引腳
*注意:由于使用Arduinos digitalWrite,必須設置引腳,
*但是,如果使用DDRx/PORTx,則可以僅應用十六進制值,用于設置端口上的引腳。
*/ void row_anode(char LEDs_on)
{
if(LEDs_on == 0x00)
{
digitalWrite(row1_anode,LOW );
digitalWrite(row2_anode,LOW);
digitalWrite(row3_anode,LOW);
}
else if(LEDs_on == 0x01)
{
digitalWrite(row1_anode,HIGH) ;
digitalWrite(row2_anode,LOW);
digitalWrite(row3_anode,LOW);
}
否則if(LEDs_on == 0x02)
{
digitalWrite(row1_anode,LOW);
digitalWrite(row2_anode,HIGH);
digitalWrite(row3_anode,LOW);
}
否則if(LEDs_on == 0x03)
{
digitalWrite(row1_anode,HIGH);
digitalWrite(row2_anode,HIGH);
digitalWrite(row3 _anode,LOW);
}
否則if(LEDs_on == 0x04)
{
digitalWrite(row1_anode,LOW);
digitalWrite(row2_anode,LOW);
digitalWrite(row3_anode ,HIGH);
}
else if(LEDs_on == 0x05)
{
digitalWrite(row1_anode,HIGH);
digitalWrite(row2_anode,LOW);
digitalWrite(row3_anode, HIGH);
}
否則if(LEDs_on == 0x06)
{
digitalWrite(row1_anode,LOW);
digitalWrite(row2_anode,HIGH);
digitalWrite(row3_anode,HIGH );
}
否則if(LEDs_on == 0x07)
{
digitalWrite(row1_anode,HIGH);
digitalWrite(row2_anode,HIGH);
digitalWrite(row3_anode,HIGH) ;
}
}
步驟6:3 x 3 LED示例-多個顯示器
擴展示例代碼:
在此情況下,我通過設置Atmega328的寄存器實現了一個Timer。這允許1秒的計時器是異步的,因此不會造成顯示延遲。要設置寄存器,您確實需要查看Atmega328的數據表。
當定時器中斷每1秒關閉一次時,我將計數器增加3,以顯示數組中的下一組值。數組具有要用于顯示的值。
要查看示例,請查看附件。
步驟7:結論
我希望一旦您了解了復用的概念實際上非常簡單,該指令就很有幫助。
我計劃使另一個指令與移位寄存器進行復用。除了一些額外的編碼,電路之外,它的復雜程度也沒有太多,而且您可以使用更少的引腳!
責任編輯:wv
-
晶體管
+關注
關注
77文章
9685瀏覽量
138124
發(fā)布評論請先 登錄
相關推薦
評論