1. 用51單片機控制數碼管顯示
1. 接電源:VCC(PIN40)、GND(PIN20)。加接退耦電容0.1uF
2. 接晶體:X1(PIN18)、X2(PIN19)。注意標出晶體頻率(選用12MHz),還有輔助電容30pF
3. 接復位:RES(PIN9)。接上電復位電路,以及手動復位電路,分析復位工作原理
4. 接配置:EA(PIN31)。說明原因。
發光二極的控制:單片機I/O輸出
將一發光二極體LED的正極(陽極)接P1.1,LED的負極(陰極)接地GND。只要P1.1輸出高電平VCC,LED就正向導通(導通時LED上的壓降大於1V),有電流流過LED,至發LED發亮。實際上由於P1.1高電平輸出電阻為10K,起到輸出限流的作用,所以流過LED的電流小於(5V-1V)/10K = 0.4mA。只要P1.1輸出低電平GND,實際小於0.3V,LED就不能導通,結果LED不亮。
開關雙鍵的輸入:輸入先輸出高
一個按鍵KEY_ON接在P1.6與GND之間,另一個按鍵KEY_OFF接P1.7與GND之間,按KEY_ON後LED亮,按KEY_OFF後LED滅。同時按下LED半亮,LED保持後松開鍵的狀態,即ON亮OFF滅。
代碼
1. #include <at89x52.h>
2. #define LED P1^1 //用符號LED代替P1_1
3. #define KEY_ON P1^6 //用符號KEY_ON代替P1_6
4. #define KEY_OFF P1^7 //用符號KEY_OFF代替P1_7
5. void main( void ) //單片機復位後的執行入口,void表示空,無輸入參數,無返回值
6. {
7. KEY_ON = 1; //作為輸入,首先輸出高,接下KEY_ON,P1.6則接地為0,否則輸入為1
8. KEY_OFF = 1; //作為輸入,首先輸出高,接下KEY_OFF,P1.7則接地為0,否則輸入為1
9. While( 1 ) //永遠為真,所以永遠循環執行如下括弧內所有語句
10. {
11. if( KEY_ON==0 ) LED=1; //是KEY_ON接下,所示P1.1輸出高,LED亮
12. if( KEY_OFF==0 ) LED=0; //是KEY_OFF接下,所示P1.1輸出低,LED滅
13. } //松開鍵後,都不給LED賦值,所以LED保持最後按鍵狀態。
14. //同時按下時,LED不斷亮滅,各佔一半時間,交替頻率很快,由於人眼慣性,看上去為半亮態
15. }
數碼管的接法和驅動原理
一支七段數碼管實際由8個發光二極體構成,其中7個組形構成數字8的七段筆畫,所以稱為七段數碼管,而餘下的1個發光二極體作為小數點。作為習慣,分別給8個發光二極體標上記號:a,b,c,d,e,f,g,h。對應8的頂上一畫,按順時針方向排,中間一畫為g,小數點為h。
我們通常又將各二極與一個位元組的8位對應,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相應8個發光二極體正好與單片機一個埠Pn的8個引腳連接,這樣單片機就可以通過引腳輸出高低電平控制8個發光二極的亮與滅,從而顯示各種數字和符號;對應位元組,引腳接法為:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)。
如果將8個發光二極體的負極(陰極)內接在一起,作為數碼管的一個引腳,這種數碼管則被稱為共陰數碼管,共同的引腳則稱為共陰極,8個正極則為段極。否則,如果是將正極(陽極)內接在一起引出的,則稱為共陽數碼管,共同的引腳則稱為共陽極,8個負極則為段極。
以單支共陰數碼管為例,可將段極接到某埠Pn,共陰極接GND,則可編寫出對應十六進制碼的七段碼表位元組數據如右圖:
16鍵碼顯示的程序
我們在P1埠接一支共陰數碼管SLED,在P2、P3埠接16個按鍵,分別編號為KEY_0、KEY_1到KEY_F,操作時只能按一個鍵,按鍵後SLED顯示對應鍵編號。
代碼
1. #include <at89x52.h>
2. #define SLED P1
3. #define KEY_0 P2^0
4. #define KEY_1 P2^1
5. #define KEY_2 P2^2
6. #define KEY_3 P2^3
7. #define KEY_4 P2^4
8. #define KEY_5 P2^5
9. #define KEY_6 P2^6
10. #define KEY_7 P2^7
11. #define KEY_8 P3^0
12. #define KEY_9 P3^1
13. #define KEY_A P3^2
14. #define KEY_B P3^3
15. #define KEY_C P3^4
16. #define KEY_D P3^5
17. #define KEY_E P3^6
18. #define KEY_F P3^7
19. Code unsigned char Seg7Code[16]= //用十六進數作為數組下標,可直接取得對應的七段編碼位元組
20. // 0 1 2 3 4 5 6 7 8 9 A b C d E F
21. {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
22. void main( void )
23. {
24. unsigned char i=0; //作為數組下標
25. P2 = 0xff; //P2作為輸入,初始化輸出高
26. P3 = 0xff; //P3作為輸入,初始化輸出高
27. While( 1 )
28. {
29. if( KEY_0 == 0 ) i=0; if( KEY_1 == 0 ) i=1;
30. if( KEY_2 == 0 ) i=2; if( KEY_3 == 0 ) i=3;
31. if( KEY_4 == 0 ) i=4; if( KEY_5 == 0 ) i=5;
32. if( KEY_6 == 0 ) i=6; if( KEY_7 == 0 ) i=7;
33. if( KEY_8 == 0 ) i=8; if( KEY_9 == 0 ) i=9;
34. if( KEY_A == 0 ) i=0xA; if( KEY_B == 0 ) i=0xB;
35. if( KEY_C == 0 ) i=0xC; if( KEY_D == 0 ) i=0xD;
36. if( KEY_E == 0 ) i=0xE; if( KEY_F == 0 ) i=0xF;
37. SLED = Seg7Code[ i ]; //開始時顯示0,根據i取應七段編碼
38. }
39. }
2. 哪位大俠知道51單片機斷電後重新啟動保持原來狀態不變
很簡單啊……掉電保護,使用自帶電源的存儲器,單片機在運行時將數據保存在這存儲器中,掉電後數據還是存在於存儲器中,單片機上電後讀取存儲器中的數據繼續工作。
如果你想要做單片機時鍾,那就用DS1302或者DS12887,其中就有存儲器,並且有電源維持著,你把數據寫入保存,掉電後是不會丟失的,除非你拿掉了DS1302的電池。而DS12887的電池是和晶元封裝到一起的,除非電池沒電,就可以一直保存數據。
3. 51單片機如何讓一個數碼管閃爍而其他數碼管一直保持亮的狀態不受影響
假如有6 個數碼管,每個亮5ms,30ms是一輪,用一個變數a計數,40輪為一周期,如果a小於20,需閃爍的哪一位數碼管不亮,a大於20,該位正常顯示。就形成了亮0.6s滅0.6S的效果。
下面是4位數碼管閃爍程序:
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77};//七段碼表
modtable={ {0,0,0,0},{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} ,{1,1,1,1} }
//5種模式4個數碼管,所以表格為5*4
//4個0表示4個數碼管都可以正常亮
void display(uint m,uchar mode )//4位顯示子程序 帶某位閃爍功能
//mode=0,都不閃爍 mode=1 千位閃爍 mode=2 百位閃爍 mode=3 十位閃爍 mode=4 個位閃爍
//mode=5 全部閃爍
{
uchar a1,a2,a3,a4;
staic ia;
uchar modeaa;
a1=m/1000;
a2=m/100%10;
a3=m/10%10;
a4=m%10;
if(ia<20)
{
modeaa=mode;//前20次與閃爍模式有關
}
else
{
modeaa=0;//後20次只管正常掃描
}
dataport=~(table[a1]);
sm1=modtable[modeaa][0]; Delay1ms(2);sm1=1;//sm1=0,一號數碼管亮
//但它是否為0,由modeaa決定,modeaa又受ia控制,可以等於mode,也可以為0
dataport=~(table[a2]);
sm2=modtable[modeaa][1]; Delay1ms(2);sm2=1;
dataport=~(table[a3]);
sm3=modtable[modeaa][2]; Delay1ms(2);sm3=1;
dataport=~(table[a4]);
sm4=modtable[modeaa][3]; Delay1ms(2);sm4=1;
ia++;
if(ia==40) ia=0;
}