1.什么是數(shù)碼管
1.1梳码、幾方面看數(shù)碼管
(1)外觀
(2)作用:數(shù)碼管是顯示器件,用來顯示數(shù)字的望几。
(3)分類:單個(gè)(1位)绩脆、聯(lián)排(2位、4位橄抹、8位)
1.2靴迫、工作原理
(1)亮滅原理:其實(shí)就是內(nèi)部的照明LED
(2)顯示數(shù)字(甚至文字)原理:利用內(nèi)部的LED的亮和滅讓外部的組成數(shù)字的筆畫顯示或者不顯示,人看到的就是不同的數(shù)字楼誓。
1.3玉锌、共陽極和共陰極數(shù)碼管
(1)驅(qū)動(dòng)方法的差異。必須清楚一個(gè)數(shù)碼管內(nèi)部的8顆LED是獨(dú)立驅(qū)動(dòng)的疟羹。如果8顆LED的正極接在一起接到VCC上(負(fù)極分別接到單片機(jī)的不同引腳)主守,這種接法就叫做共陽極。反之如果8顆LED負(fù)極接在一起然后接到GND(正極就分別接到單片機(jī)的不同引腳)就叫做共陰極榄融。兩種接法都可以驅(qū)動(dòng)數(shù)碼管顯示参淫,但是用來顯示的單片機(jī)程序不同(共陽極時(shí)單片機(jī)0是亮,共陰極時(shí)單片機(jī)1是亮)
(2)驅(qū)動(dòng)電流需求差異愧杯。數(shù)碼管(其實(shí)就是LED)如果按照共陽極接法則單片機(jī)可以直接驅(qū)動(dòng)顯示涎才,如果按照共陰極接法則單片機(jī)不能直接驅(qū)動(dòng)顯示,因?yàn)閱纹瑱C(jī)的IO提供的電流大小不夠驅(qū)動(dòng)數(shù)碼管內(nèi)部的LED顯示力九,需要外部電路來提供一個(gè)大電流驅(qū)動(dòng)的芯片來解決(74HC573芯片就是起的這個(gè)作用)耍铜。
1.4、靜態(tài)和動(dòng)態(tài)數(shù)碼管
(1)用途差異:買數(shù)碼管的時(shí)候是沒有分動(dòng)態(tài)還是靜態(tài)的畏邢,因?yàn)閯?dòng)靜只是接法,一般單個(gè)的使用靜態(tài)數(shù)碼管检吆,聯(lián)排的使用動(dòng)態(tài)數(shù)碼管舒萎。
(2)電路接法差異
2.靜態(tài)數(shù)碼管的初步驅(qū)動(dòng)
2.1、原理圖分析
2.2、接線
結(jié)論:單片機(jī)的P0端口直接接到共陽極數(shù)碼管的陰極臂寝,因此單片機(jī)輸出0則數(shù)碼管亮章鲤,輸出1數(shù)碼管滅。
2.3咆贬、編程點(diǎn)亮
(1)P0 = 0x0; // 8段全亮
(2)P0 = 0xff; // 8段全滅
(3)P0 = 0x0f; // 4段亮4段滅
#include <reg51.h>
void main(void)
{
// 8段全亮
P0 = 0x0;
// 8段全滅
P0 = 0xff;
// 4段亮4段滅
P0 = 0x0f;
}
2.4败徊、驗(yàn)證原理圖中數(shù)碼管段號是否正確
(1)數(shù)碼管的8段實(shí)際是8個(gè)LED,分別對應(yīng)IO端口P0的8個(gè)引腳(P0.0掏缎、P0.1……P0.7)皱蹦,那么誰對誰呢?
(2)理論上可以分析原理圖和接線方法去推測這個(gè)對應(yīng)關(guān)系(數(shù)碼管的段碼)眷蜈,但是實(shí)際上理論分析的經(jīng)常不對沪哺。
(3)實(shí)戰(zhàn)中一般都是自己寫代碼去測試的
#include <reg51.h>
void main(void)
{
P0 = 0xfe; //11111 110 P0.0輸出0 實(shí)測對應(yīng)a
P0 = 0xfd; //11111101 P0.1輸出0 實(shí)測對應(yīng)b
P0 = 0xfb; //11111011 P0.2輸出0 實(shí)測對應(yīng)c
P0 = 0xf7; //11110111 P0.3輸出0 實(shí)測對應(yīng)d
P0 = 0xef; //11101111 P0.4輸出0 實(shí)測對應(yīng)e
P0 = 0xdf; //11011111 P0.5輸出0 實(shí)測對應(yīng)f
P0 = 0xbf; //10111111 P0.6輸出0 實(shí)測對應(yīng)g
P0 = 0x7f; //01111111 P0.7輸出0 實(shí)測對應(yīng)dp
}
注意:P0端口的8個(gè)二進(jìn)制位中,高位對應(yīng)P0.7酌儒,低位對應(yīng)P0.0辜妓。
2.5、思考:數(shù)碼管如何顯示數(shù)字忌怎?
(1)數(shù)碼管顯示數(shù)字籍滴,其實(shí)就是讓數(shù)碼管亮相應(yīng)的幾個(gè)段。其實(shí)就是讓IO端口的相應(yīng)引腳輸出0(其余引腳輸出1)榴啸,其實(shí)就對應(yīng)一個(gè)8位的二進(jìn)制數(shù)孽惰。
(2)結(jié)論就是:P0端口輸出一個(gè)合適的字節(jié)數(shù)(二進(jìn)制數(shù)),數(shù)碼管就會顯示相應(yīng)的數(shù)字插掂,每個(gè)數(shù)字都會有一個(gè)對應(yīng)的8位二進(jìn)制數(shù)灰瞻,關(guān)鍵就是要得到這8位二進(jìn)制數(shù)。
3.靜態(tài)數(shù)碼管顯示數(shù)字
3.1辅甥、數(shù)字編碼(段碼)的獲取
數(shù)字 | 數(shù)碼管亮的LED | 段碼 | 十六進(jìn)制 |
---|---|---|---|
0 | abcdef | 11000000 | 0xc0 |
1 | bc | 11111001 | 0xf9 |
2 | abdeg | 10100100 | 0xA4 |
3 | abcdgh | 10110000 | 0xb0 |
4 | bcfg | 10011001 | 0x99 |
5 | acdfg | 10010010 | 0x92 |
6 | acdefg | 10000010 | 0x82 |
7 | abc | 11111000 | 0xf8 |
8 | abcdefg | 10000000 | 0x80 |
9 | abcdfg | 10010000 | 0x90 |
A | abcefg | 10001000 | 0x88 |
B | cdefg | 10000011 | 0x83 |
C | adef | 11000110 | 0xc6 |
D | bcdeg | 10100001 | 0xA1 |
E | adefg | 10000110 | 0x86 |
F | aefg | 10001110 | 0x8e |
3.2酝润、結(jié)論
(1)不同的數(shù)碼管數(shù)字編碼表完全可能不同
(2)同一個(gè)數(shù)碼管接線方式不同編碼表可能完全不同
(3)硬件確定后可通過調(diào)試的方法來實(shí)驗(yàn)確定編碼表
4.讓數(shù)碼管依次顯示0到f
4.1、笨辦法:分狀態(tài)
#include <reg51.h>
void delay(void)
{
unsigned char i, j, k;
for (i=0; i<100; i++)
for (j=0; j<100; j++)
for (k=0; k<30; k++);
}
void main(void)
{
while (1)
{
P0 = 0xc0; // 0
delay();
P0 = 0xf9; // 1
delay();
P0 = 0xA4; // 2
delay();
P0 = 0xb0; // 3
delay();
P0 = 0x99; // 4
delay();
P0 = 0x92; // 5
delay();
P0 = 0x82; // 6
delay();
P0 = 0xf8; // 7
delay();
P0 = 0x80; // 8
delay();
P0 = 0x90; // 9
delay();
P0 = 0x88; // A
delay();
P0 = 0x83; // B
delay();
P0 = 0xc6; // C
delay();
P0 = 0xA1; // D
delay();
P0 = 0x86; // E
delay();
P0 = 0x8e; // F
delay();
}
}
4.2璃弄、好方法:利用數(shù)組
#include <reg51.h>
void delay(void)
{
unsigned char i, j, k;
for (i=0; i<100; i++)
for (j=0; j<100; j++)
for (k=0; k<30; k++);
}
void main(void)
{
unsigned char val[16] = {0xc0, 0xf9, 0xA4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
0x80, 0x90, 0x88, 0x83, 0xc6, 0xA1, 0x86, 0x8e};
unsigned char i = 0;
while (1)
{
for (i=0; i<16; i++)
{
P0 = val[i];
delay();
}
}
}
5.動(dòng)態(tài)數(shù)碼管
5.1要销、靜態(tài)數(shù)碼管驅(qū)動(dòng)方式的缺陷
(1)優(yōu)勢是驅(qū)動(dòng)簡單直接,好編程
(2)缺陷是每個(gè)數(shù)碼管需要1個(gè)端口夏块,單片機(jī)的端口不夠用
解決辦法:使用動(dòng)態(tài)方式驅(qū)動(dòng)多個(gè)數(shù)碼管
5.2疏咐、什么是動(dòng)態(tài)數(shù)碼管
(1)數(shù)碼管還是原來的數(shù)碼管(共陽極或共陰極均可)
(2)段碼一側(cè)還是接一個(gè)單片機(jī)端口
(3)COM(共極)接單片機(jī)一個(gè)IO口(8對8),多個(gè)聯(lián)排數(shù)碼管的COM共同接一個(gè)IO端口(8對1)
5.3脐供、動(dòng)態(tài)數(shù)碼管如何工作
(1)在某一特定時(shí)間段中浑塞,聯(lián)排數(shù)碼管中只有一個(gè)數(shù)碼管在工作,其他均在休息(不工作)
(2)COM端選擇哪個(gè)數(shù)碼管工作政己,段碼端輸出這個(gè)數(shù)碼管要顯示的數(shù)字的段碼酌壕,延時(shí);COM端選擇下一個(gè)數(shù)碼管工作,同時(shí)段碼端改輸出這個(gè)數(shù)碼管要顯示的數(shù)字的段碼卵牍,延時(shí)果港;COM端選擇下一個(gè)數(shù)碼管工作……
(3)快速切換工作的數(shù)碼管,則人看到的效果是所有的數(shù)碼管都在亮(其實(shí)亮是比靜態(tài)驅(qū)動(dòng)低的)糊昙。
(4)動(dòng)態(tài)數(shù)碼管利用了人眼的視覺暫留
(5)搞清楚2點(diǎn):
①第一辛掠,宏觀上所有的數(shù)碼管都是同時(shí)亮的,所以人以為所有數(shù)碼管同時(shí)工作释牺,所以多個(gè)數(shù)碼管可以合在一起來顯示(比如:顯示12345678)
②第二萝衩,微觀上數(shù)碼管是依次亮的,我們可以給不同的數(shù)碼管送不同的段碼船侧,所以不同的數(shù)碼管可以顯示不同的數(shù)字欠气。
6.動(dòng)態(tài)數(shù)碼管顯示編程實(shí)戰(zhàn)1
目標(biāo):先實(shí)驗(yàn)得出數(shù)碼管的段碼表
(1)接線確定:段碼端接P0,COM端接P1端口
(2)COM端選擇一個(gè)數(shù)碼管亮:P1.0~P1.7隨便選1個(gè)輸出0镜撩,其余輸出1
(3)段碼端給不同的值來測試得到段碼表
第一步:先測試P0.0~P0.7和abcdefg.怎么對應(yīng)的预柒?
實(shí)驗(yàn)測試結(jié)論:P1.0對應(yīng)最左邊一個(gè)數(shù)碼管、P0.0對應(yīng)a
數(shù)字 | 數(shù)碼管亮的LED | 段碼 | P1十六進(jìn)制 |
---|---|---|---|
0 | abcdef | 00111111 | 0x3f |
1 | bc | 00000110 | 0x06 |
2 | abdeg | 01011011 | 0x5b |
3 | abcdgh | 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 |
第二步:編程實(shí)踐
#include <reg51.h>
void main(void)
{
// P0端口是段碼袁梗,P1端口是COM
P1 = 0xfe; // 11111110 P2.0是低電平宜鸯,其余都是高電平
// 共陰極數(shù)碼管是COM端給0,段碼端給1亮
P0 = 0x3f;
}
7.動(dòng)態(tài)數(shù)碼管顯示編程實(shí)戰(zhàn)2
目標(biāo):8個(gè)聯(lián)數(shù)碼管一起顯示12345678
(1)編程思路:先選中第1個(gè)數(shù)碼管遮怜,然后段碼端發(fā)送1的段碼淋袖,然后延時(shí)一會兒,然后切換選中第2數(shù)碼管锯梁,然后段碼端發(fā)送2的段碼即碗,然后延時(shí)一會兒;直到第8個(gè)數(shù)碼管顯示完為一個(gè)周期陌凳,死循環(huán)這個(gè)周期剥懒。
(2)實(shí)現(xiàn)結(jié)論:
①延時(shí)時(shí)間太長,數(shù)字會動(dòng)
②把時(shí)間改短后發(fā)現(xiàn)有3個(gè)問題:第一個(gè)是亮的不夠亮合敦,第二個(gè)是暗的不夠暗初橘,第三個(gè)是其中一個(gè)數(shù)字(1)顯示明顯有問題。解決方案就是在每個(gè)數(shù)碼管亮完要切換下一個(gè)數(shù)碼管時(shí)消隱充岛。數(shù)碼管顯示消隱原理:http://c.biancheng.net/cpp/html/1887.html
#include <reg51.h>
void delay(void)
{
unsigned char i, j;
for (i=0; i<10; i++)
for (j=0; j<10; j++);
}
void main(void)
{
while (1)
{
P2 = 0xfe; // 11111110
P0 = 0x06; // 1的段碼
delay();
P0 = 0x0; // 消隱作用
P2 = 0xfd; // 11111101
P0 = 0x5b; // 2的段碼
delay();
P0 = 0x0;
P2 = 0xfb; // 11111011
P0 = 0x4f; // 3的段碼
delay();
P0 = 0x0;
P2 = 0xf7; // 11110111
P0 = 0x66; // 4的段碼
delay();
P0 = 0x0;
P2 = 0xef; // 11101111
P0 = 0x6d; // 5的段碼
delay();
P0 = 0x0;
P2 = 0xdf; // 11011111
P0 = 0x7d; // 6的段碼
delay();
P0 = 0x0;
P2 = 0xbf; // 10111111
P0 = 0x07; // 7的段碼
delay();
P0 = 0x0;
P2 = 0x7f; // 01111111
P0 = 0x7f; // 8的段碼
delay();
P0 = 0x0;
}
}
③代碼改良:數(shù)組管理
#include <reg51.h>
void delay(void)
{
unsigned char i, j;
for (i=0; i<10; i++)
for (j=0; j<10; j++);
}
void main(void)
{
unsigned char duanma[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,
0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
unsigned char weima[8] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
while (1)
{
unsigned char i = 0;
for (i=0; i<8; i++)
{
P2 = weima[i]; // 依次選擇數(shù)碼管1-8
P0 = duanma[i+1]; // 依次顯示1-8
delay();
P0 = 0x0; // 消隱作用
}
}
}
8.38譯碼器介紹
8.1保檐、為什么引入38譯碼器
(1)38譯碼器的作用:用3個(gè)IO口來控制8路輸出。
(2)用38譯碼器驅(qū)動(dòng)數(shù)碼管的意義:原來不用38譯碼器時(shí)崔梗,8個(gè)動(dòng)態(tài)數(shù)碼管一共使用2個(gè)IO端口(16個(gè)引腳)夜只,現(xiàn)在使用了38譯碼器后,我們可以用38譯碼器的3路輸入來控制數(shù)碼管的8路位碼蒜魄,這樣總共只需要3+8=11個(gè)IO引腳就可以來驅(qū)動(dòng)8個(gè)動(dòng)態(tài)數(shù)碼管了扔亥,省了5個(gè)IO口爪膊。
8.2、74LS138的數(shù)據(jù)手冊
(1)重點(diǎn)看懂真值表
L看做是0砸王,H看做是1
(2)G1和G2A G2B三個(gè)是使能引腳
(3)ABC是編碼端,Y0-Y7是輸出端
9.使用38譯碼器驅(qū)動(dòng)動(dòng)態(tài)數(shù)碼管
9.1峦阁、接線方式確定
(1)J51和J16連接起來
(2)ABC分別接P1.0谦铃、P1.1、P1.2三個(gè)
9.2榔昔、實(shí)驗(yàn)測定編碼表
(1)按照接線圖分析驹闰,P1.0=0且P1.1=0且P1.2=0時(shí)Y0為低,對應(yīng)第1個(gè)數(shù)碼管亮撒会;P1.0=1且P1.1=0且P1.2=0時(shí)Y0為低嘹朗,對應(yīng)第2個(gè)數(shù)碼管亮。
#include <reg51.h>
void delay(void)
{
unsigned char i, j;
for (i=0; i<10; i++)
for (j=0; j<10; j++);
}
void mian(void)
{
// 測試
/*
P1 = 0x0; // ABC=000 → Y0 → 第1個(gè)數(shù)碼管
P1 = 0x1; // ABC=100 → Y1 → 第2個(gè)數(shù)碼管
P1 = 0x7; // ABC=111 → Y7 → 第7個(gè)數(shù)碼管
*/
unsigned char duanma[16] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,
0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
unsigned char weima[8] = {0, 1, 2, 3, 4, 5, 6, 7};
while (1)
{
unsigned char i = 0;
for (i=0; i<8; i++)
{
P1 = weima[i]; // 依次選擇數(shù)碼管1-8
P0 = duanma[i+3]; // 依次顯示3-a
delay();
P0 = 0x0;
}
}
}