第一:數碼管基本介紹
1、單個數碼管
一個數碼管是由a、b、c、d、e、f、g、dp八個二極管組成,八個LED一端接在一起,另一端引腳引出來。二極管如果陽極連在一起,就是共陽極數碼管,陰極連在一起,就是共陰極數碼管。
如上圖,是一個共陰極數碼管,要使數碼管顯示不同的數字,只需點亮對應LED即可。如:數碼管顯示“0”,則a、b、c、d、e、f六個LED亮,g、dp這倆個LED滅,即可顯示“0”。
2、多個數碼管
上圖所示的六個數碼管,在使用時,需要程序選定使用哪幾個數碼管,這就是“位選”,選定數碼管后再對選定的數碼管進行操作,其操作與單個數碼管的操作一致(接下來還會進一步詳解),這就是“段選”。
3、數碼管與芯片的連接
3.1 為什么要使用鎖存器?
二極管正常工作時需要5mA以上的電流,若數碼管引腳和芯片引腳直接相連,芯片的I/O口無法輸出這么大的電流,對于共陰極的數碼管,可以在陽極處接上拉電阻,對于共陽極的數碼管,可以在陰極處接下拉電阻,但是也使得“位選”需做另外的處理。
引入鎖存器,利用其輸出電流大的特點,有效的解決了LED工作電流問題,而且還可以利用鎖存器進行“位選”、“段選”。
3.2 鎖存器的電路連接
上圖所示,連接倆塊鎖存器,U1控制段選,U2控制位選,鎖存器現再回顧一下
根據電路圖,OE始終接地,所以鎖存器工作狀態只有前三種,當LE軟件置1時,鎖存器的輸入端D與輸出端Q同高電平,同低電平,當LE軟件置0時,鎖存器輸出為Q0。
由電路圖可得,電路連接為:
單片機的芯片引腳P00—>P07分別接U1鎖存器的D0——>D7,單片機的芯片引腳P00—>P07分別接U2鎖存器的D0——>D7,也就是說U1、U2倆鎖存器都與P0相連,所以在數碼管工作狀態下,倆個鎖存器不能同時處于打開狀態,即倆個鎖存器的LE不能同時為高電平。鎖存器U1的輸出接數碼管的LED陽極,鎖存器U2的輸出接數碼管的WE,控制“數碼管選擇”。
鎖存器U2控制位選,U2打開時,U1關閉,此時U2的輸入和輸出同高、同低電平。如下圖,若使用數碼管1,則只需D0置0,其他引腳置1,即芯片P00輸出為0,P01——>P07輸出為1,即P0寄存器的狀態值為0xfe(上面低位,從下往上讀)
鎖存器U1控制段選,如剛剛位選了數碼管1,則接下來段選是對數碼管1的操作。此時關閉U2,打開U1,即U2的LE軟件置0,U1的LE軟件置1,而U2的LE與芯片的P27相連,U1的LE與芯片的P26相連(下圖所示),所以只需使芯片的P27輸出低電平來關閉U2鎖存器,P26輸出高電平來打開U1鎖存器。
打開U1鎖存器后,使數碼管顯示某個數字,我們在第一節中總結過了,比如顯示一個數字“6”,需要a、c、d、e、f、g六個LED亮,所以鎖存器輸出01111101(共陰極數碼管。輸出1時點亮),即P0寄存器輸出01111101,P0寄存器的狀態值為0x7d。
第二:數碼管具體實現
第一個數碼管顯示數字“6”的程序如下:
#include
sbit dula=P2^6;
sbit wela=P2^7;
void main()
{
wela=1;
P0=0xfe;//位選第一個數碼管
wela=0;
dula=1;
P0=0x7d;
dula=0;
while(1);
}
分析上面程序:
首先對連接U1、U2鎖存器LE的芯片引腳P26與P27進行位操作,重命名為“dula”與“wela”,表示“段選”和“位選”。主函數里,先打開位選:wela=1,選擇第一個數碼管,則U2鎖存器輸入和輸出均為11111110(從下往上),P0的輸出也為11111110,即0xfe,位選結束后關閉位選:wela=0。
接下來打開段選:dula=1,對第一個數碼管操作,顯示數字“6”,U1鎖存器輸入輸出均為01111101,即P0輸出為01111101,即P0的狀態值為0x7d。最后關閉段選。
注:
正因為鎖存器U1與U2同時接在芯片的P0引腳上,所以倆個鎖存器不能同時打開,否則芯片引腳P0輸出的狀態值會在U1和U2上同時發生響應,造成紊亂。
第三:數碼管顯示數字時芯片引腳的狀態值
顯示數字“0”,abcdef亮,狀態值00111111——>0x3f
顯示數字“1”,bc亮,狀態值00000110——>0x06
顯示數字“2”,abdeg亮,狀態值01011011——>0x5b
顯示數字“3”,abcdg亮,狀態值01001111——>0x4f
顯示數字“4”,bcfg亮,狀態值01100110——>0x66
顯示數字“5”,acdfg亮,狀態值01101101——>0x6d
顯示數字“6”,acdefg亮,狀態值01111101——>0x7d
顯示數字“7”,abc亮,狀態值00000111——>0x07
顯示數字“8”,abcdefg亮,狀態值01111111——>0x7f
顯示數字“9”,abcdfg亮,狀態值01101111——>0x6f
顯示字母“A”,abcefg亮,狀態值01110111——>0x77
顯示字母“B”,cdefg亮,狀態值01111100——>0x7c
顯示字母“C”,adef亮,狀態值00111001——>0x39
顯示字母“D”,bcdeg亮,狀態值01011110——>0x5e
顯示字母“E”,adefg亮,狀態值01111001——>0x79
顯示字母“F”,aefg亮,狀態值01110001——>0x71
在編寫程序時將上述狀態值放入數組中,通過數組來實現數碼管的動態顯示。
放在如下數組中:
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
}
在table數組名前加了code,表示編碼的意思,單片機程序把不需要更改的東西通過code關鍵字定義為編碼,單片機執行程序時,table只占用程序存儲空間,可以理解為占用flash,而不占用RAM。
第四:數碼管實現動態顯示
一個數碼管從0到F動態顯示
#include
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar num;
sbit dula=P2^6;
sbit wela=P2^7;
void delay_ms(uint );
void main()
{
wela=1;
P0=0xfe;
wela=0;
while(1)
{
for(num=0;num16;num++)
{
dula=1;
P0=table[num];
dula=0;
delay_ms(500);
}
}
}
void delay_ms(uint ms)
{
uint i,j;
for(i=ms;i?>0;i--)
for(j=110;j>0;j--);
}
此時第一個數碼管從0變化到F,之后停止不動。
若使數碼管從0到F反復變化,只需在while()語句里添加如下代碼:
if(num==16)
num=0;
完整程序:
#include
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar num;
sbit dula=P2^6;
sbit wela=P2^7;
void delay_ms(uint );
void main()
{
wela=1;
P0=0xfe;
wela=0;
while(1)
{
for(num=0;num16;num++)
{
dula=1;
P0=table[num];
dula=0;
delay_ms(500);
}
//------------新加
if(num==16)
num=0;
//----------------
}
}
void delay_ms(uint ms)
{
uint i,j;
for(i=ms;i?>0;i--)
for(j=110;j>0;j--);
}
第五:數碼管經典實例
六個數碼管,第一個數碼管顯示數字“1”,間隔1秒后再在第二個數碼管上顯示數字“2”,間隔1s后在第三個數碼管上顯示數字“3”,以此類推…在第六個數碼管上顯示數字“6”
分析:
六個數碼管輪流顯示,所以位選時依次選擇數碼管1、2…6,每次位選后,再段選輸出需要顯示的數字。
第一個數碼管位選:
wela=1;
P0=0xfe;//第一個數碼管
wela=0;
第一個數碼管段選輸出數字“1”:
dula=1;
P0=table[1];
dula=0;
delay_ms(1000);
位選時P0的輸出之前已經總結過了,再回憶一下,如下圖,從左到右分別為數碼管1、2、3、4…從下往上讀,得到8位二進制碼,變為16進制即可。
完整程序:
#include
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar num;
sbit dula=P2^6;
sbit wela=P2^7;
void delay_ms(uint );
void main()
{
while(1)
{
wela=1;
P0=0xfe;//第一個數碼管
wela=0;
dula=1;
P0=table[1];
dula=0;
delay_ms(1000);
wela=1;
P0=0xfd;//第二個數碼管
wela=0;
dula=1;
P0=table[2];
dula=0;
delay_ms(1000);
wela=1;
P0=0xfb;//第三個數碼管
wela=0;
dula=1;
P0=table[3];
dula=0;
delay_ms(1000);
wela=1;
P0=0xf7;//第四個數碼管
wela=0;
dula=1;
P0=table[4];
dula=0;
delay_ms(1000);
wela=1;
P0=0xef;//第五個數碼管
wela=0;
dula=1;
P0=table[5];
dula=0;
delay_ms(1000);
wela=1;
P0=0xdf;//第六個數碼管
wela=0;
dula=1;
P0=table[6];
dula=0;
delay_ms(1000);
}
}
void delay_ms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
總結:數碼管是常用器件,掌握其中的控制方法,才能走的更遠。
-
嵌入式
+關注
關注
5071文章
19026瀏覽量
303500
發布評論請先 登錄
相關推薦
評論