一、8*8點(diǎn)陣結(jié)構(gòu)
下面圖片是8*8點(diǎn)陣內(nèi)部結(jié)構(gòu)原理圖,一共有16根引腳,如果直接用8位單片機(jī)進(jìn)行控制的話,需要占用單片機(jī)2個(gè)端口(如:P1,P2),實(shí)質(zhì)上就是控制64個(gè)LED燈的亮滅,比如我想讓左上角第一個(gè)LED燈亮起,其它燈全滅,那么需要讓h1輸出高電平,L1輸出低電平就可以了。注意要將L2-L8保持在高電平,否則第一行的其它燈也會(huì)亮。
二、串并轉(zhuǎn)換(74HC595)
上面這種控制方式雖然簡(jiǎn)單,但是占用單片機(jī)的IO口線過多,所以,我們經(jīng)常會(huì)利用74HC595這樣的串并轉(zhuǎn)換芯片作為驅(qū)動(dòng)芯片,一個(gè)595具有8個(gè)驅(qū)動(dòng)輸出端(QA-QH),那么我們這里需要2個(gè)595就夠用了。通過第一片595的SQH管腳進(jìn)行級(jí)聯(lián),將數(shù)據(jù)送至第二片595的數(shù)據(jù)輸入端,這樣單片機(jī)只需要3根線就可以實(shí)現(xiàn)對(duì)2片595的輸出控制。
三、控制時(shí)序
對(duì)于編寫595的驅(qū)動(dòng)程序來說,看時(shí)序圖是最直接了當(dāng)?shù)姆绞?,手?cè)上會(huì)說的比較多,簡(jiǎn)化來說,就是DATA_IN管腳用來輸入數(shù)據(jù)(實(shí)際上就是高低電平),然后SHIFT-CLK管腳提供時(shí)鐘,每當(dāng)SHIFT-CLK的上升沿到來,595會(huì)讀入DATA_IN管腳的電平狀態(tài),并存儲(chǔ)在內(nèi)部的鎖存器中,當(dāng)8個(gè)上升沿讀取結(jié)束后,第一片595的8個(gè)數(shù)據(jù)已經(jīng)全部讀完,但是我們這里是級(jí)聯(lián)的接法,所以還要繼續(xù)讀8個(gè)上升沿,然后數(shù)據(jù)從SQH管腳傳給第二片595的DATA_IN管腳,到這時(shí),16個(gè)上升沿的數(shù)據(jù)都讀進(jìn)595內(nèi)部并存儲(chǔ)起來了,注意此時(shí)還沒有放到QA-QH這16個(gè)輸出口線上,接下來需要LATCH-CLK給出一個(gè)下降沿,才將16個(gè)管腳的電平狀態(tài)進(jìn)行實(shí)際輸出。
看下時(shí)許圖,就可以一目了然:
四、程序編寫(靜態(tài)顯示)
//先做宏定義,目的是給單片機(jī)的管腳起個(gè)別名,便于我們能夠見名知義。共用到3個(gè)IO口。
//初始化時(shí)用到的端口
#define cBRDDOT_Port_Shift GPIO_P4
#define cBRDDOT_Pin_Shift GPIO_Pin_2
#define cBRDDOT_Port_DIn GPIO_P4
#define cBRDDOT_Pin_DIn GPIO_Pin_1
#define cBRDDOT_Port_Latch GPIO_P4
#define cBRDDOT_Pin_Latch GPIO_Pin_3
//定義讓端口輸出高低電平
#define cBRDDOT_Bit_Shift P42
#define cBRDDOT_Bit_DIn P41
#define cBRDDOT_Bit_Latch P43
//接下來做管腳的初始化,全部初始化為輸出。
//設(shè)置Shift的管腳,處于輸出模式
GPIO_SetMode(cBRDDOT_Port_Shift, cBRDDOT_Pin_Shift, GPIO_Mode_OUT_PP);
//設(shè)置DIn的管腳,處于輸出模式
GPIO_SetMode(cBRDDOT_Port_DIn, cBRDDOT_Pin_DIn, GPIO_Mode_OUT_PP);
//設(shè)置Latch的管腳,處于輸出模式
GPIO_SetMode(cBRDDOT_Port_Latch, cBRDDOT_Pin_Latch, GPIO_Mode_OUT_PP);
//接下來目標(biāo)是點(diǎn)亮左上角第一個(gè)LED,下面是實(shí)現(xiàn)時(shí)序的代碼
void DOT_ScanOut(void)
{
u8 V, i;
cBRDDOT_Bit_Latch = 1;//看時(shí)序圖,latch管腳一開始為高電平,這里輸出1
cBRDDOT_Bit_Shift = 0;//時(shí)鐘shift-clk一開始為低電平
{
V = 0xfe;//這里是進(jìn)行點(diǎn)陣的行選擇,為什么是FE,11111110,最低位為0,目的是要選中第一行的8個(gè)LED,
for (i=0;i< 8;i++)
{
if (V & 0x80)//每次都將最高位取出來,1000000 & 8位二進(jìn)制,只有最高位有效
cBRDDOT_Bit_DIn = 1;//如果最高位為高電平,則把DATA-IN輸出高電平,這時(shí)候我們就把數(shù)據(jù)放上去了。
else
cBRDDOT_Bit_DIn = 0;//否則輸出低電平
V < <= 1;//數(shù)據(jù)向左移一位,原來的次高位變?yōu)樽罡呶?,原來的最低為補(bǔ)0,直到8個(gè)位全部讀完。
cBRDDOT_Bit_Shift = 0;
cBRDDOT_Bit_Shift = 1;//將SHIFT-CLK管腳電平由0變?yōu)?,上升沿產(chǎn)生,這時(shí)595會(huì)讀入DATA-IN的電平狀態(tài)并保存
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 0;//恢復(fù)低電平
}
}
//上面的代碼執(zhí)行完,可以理解為我們已經(jīng)選中了一行(第一行0XFE)
//接下來就是要把這一行要亮的燈點(diǎn)亮。
{
V = 0x80;//這里的邏輯是正的,1就代表亮,0代表滅。最左面的燈處于最高位位置。
for (i=0;i< 8;i++)
{
if (V & 0x80)
cBRDDOT_Bit_DIn = 1;
else
cBRDDOT_Bit_DIn = 0;
V < <= 1;
cBRDDOT_Bit_Shift = 0;
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 0;
}
//8次循環(huán)結(jié)束,那么就將要這一行要顯示的數(shù)據(jù)(要點(diǎn)亮的LED燈)也存到595內(nèi)部了。
}
cBRDDOT_Bit_Latch = 0;//將LATCH-CLK拉成低電平,這時(shí)下降沿產(chǎn)生,595會(huì)把存儲(chǔ)的數(shù)據(jù)真正給到輸出口上,對(duì)應(yīng)的LED會(huì)亮起。
cBRDDOT_Bit_Shift = 0;
}
五 、程序編寫(動(dòng)態(tài)掃描)****
//但是現(xiàn)在有個(gè)問題是,我們剛才的代碼只能同時(shí)控制一行的LED亮滅,如果想同時(shí)控制8行來顯示圖案的話,就要用動(dòng)態(tài)掃描的方式,從第1行到第8行快速切換,然后放入數(shù)據(jù),形成視覺暫留的效果,讓人眼誤以為是同時(shí)在顯示。
//也就是說,我們需要一個(gè)定時(shí)中斷,每次中斷過來我都要更新一行的數(shù)據(jù)。那么我們就要把上面的程序放到中斷服務(wù)函數(shù)里面。
//先進(jìn)行初始化設(shè)置,這里用的是timer2
Timer2_Init_AsTimer(False,0, 252, 112);
Timer2_EnaInterrupt();
Timer2_StartWork();
//全局變量
u8 code cBRDDOT_Colomn_Sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//每一行的模值
u8 xdata vBRDDOT_Values[8]={0x24,0x7e,0xff,0xff,0x7e,0x3e,0x1b,0x00};//心形圖案
// 下面是中斷服務(wù)程序
void BRDDOT_ScanOut(void) interrupt IntNo_Timer2
{
u8 V, i;
//這2行代碼的目的是讓vBRDDOT_ColIndex在0-7之間不斷循環(huán),
//比如當(dāng)vBRDDOT_ColIndex為8時(shí),二進(jìn)制對(duì)應(yīng)0000 10000,和0000 0111進(jìn)行與運(yùn)算,8變?yōu)?.
vBRDDOT_ColIndex++;
vBRDDOT_ColIndex &= 7;
cBRDDOT_Bit_Latch = 1;
cBRDDOT_Bit_Shift = 0;
//輸出Col
{
//行選擇,這里的V就不能是固定值了,因?yàn)橐鹦酗@示,每一次進(jìn)來會(huì)更新一行。
//需要在第1到第8行不斷選擇,所以cBRDDOT_Colomn_Sel數(shù)組里面應(yīng)該放好進(jìn)行每一行選擇的IO模值
V = cBRDDOT_Colomn_Sel[vBRDDOT_ColIndex];
for (i=0;i< 8;i++)
{
if (V & 0x80)
cBRDDOT_Bit_DIn = 1;
else
cBRDDOT_Bit_DIn = 0;
V < <= 1;
cBRDDOT_Bit_Shift = 0;
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 0;
}
}
{
//這里面vBRDDOT_Values要存儲(chǔ)8行LED的顯示內(nèi)容,建議用取模軟件去生成。
//每次中斷進(jìn)來都會(huì)換一行顯示,因?yàn)関BRDDOT_ColIndex一直在變。
V = vBRDDOT_Values[vBRDDOT_ColIndex];
for (i=0;i< 8;i++)
{
if (V & 0x80)
cBRDDOT_Bit_DIn = 1;
else
cBRDDOT_Bit_DIn = 0;
V < <= 1;
cBRDDOT_Bit_Shift = 0;
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 1;
cBRDDOT_Bit_Shift = 0;
}
}
cBRDDOT_Bit_Latch = 0;
cBRDDOT_Bit_Shift = 0;
}
-
原理圖
+關(guān)注
關(guān)注
1308文章
6373瀏覽量
236464 -
單片機(jī)
+關(guān)注
關(guān)注
6050文章
44702瀏覽量
641299 -
led燈
+關(guān)注
關(guān)注
22文章
1593瀏覽量
108812 -
鎖存器
+關(guān)注
關(guān)注
8文章
918瀏覽量
41782 -
74HC595
+關(guān)注
關(guān)注
7文章
193瀏覽量
31127
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
挽救一下小蝦們脆弱的心吧,74HC595驅(qū)動(dòng)LED點(diǎn)陣方面
基于51的4塊8*8點(diǎn)陣拼成16*16點(diǎn)陣
51單片機(jī)學(xué)習(xí)總結(jié)(三)8*8點(diǎn)陣屏,串口通信(內(nèi)含模塊代碼) 精選資料推薦
74HC595驅(qū)動(dòng)LED點(diǎn)陣或數(shù)碼管的正確用法 精選資料推薦
74HC595驅(qū)動(dòng)LED點(diǎn)陣或數(shù)碼管的正確用法是什么?
如何使用三片74HC595對(duì)一個(gè)8X8雙色點(diǎn)陣進(jìn)行控制呢
如何去實(shí)現(xiàn)一種8x8點(diǎn)陣的設(shè)計(jì)
基于單片機(jī)74HC595去驅(qū)動(dòng)點(diǎn)陣
基于8051的Proteus仿真-74HC595與74LS154
一種用 74hc138 和 74hc595 驅(qū)動(dòng) 8x8 點(diǎn)陣顯示技術(shù)

評(píng)論