LED點(diǎn)陣介紹:
? ? ? ?LED點(diǎn)陣是由發(fā)光二極管排列組成的顯示器件,在我們生活中的電器中隨處可見,被廣泛用于汽車報站器,廣告屏等。
????????通常用用較多的是8*8點(diǎn)陣,然后使用多個8*8點(diǎn)陣組成不同分辨率的LED點(diǎn)陣顯示屏,比如16*16點(diǎn)陣可以使用4個8*8點(diǎn)陣構(gòu)成。因此理解了8*8LED點(diǎn)陣的工作原理,器他分辨率的LED點(diǎn)陣顯示屏都一樣的。
????????8*8點(diǎn)陣共有64個發(fā)光二極管組成,且每個發(fā)光二極管是放置在行線和列線的交叉點(diǎn)上,當(dāng)對應(yīng)的某一行置1電平,某一列置0電平,則相應(yīng)的二極管就亮;如果將要左上角第一個點(diǎn)點(diǎn)亮亮,則1腳高電平a腳低電平,則第一個點(diǎn)就亮了;如果將要第一行點(diǎn)亮,則第 1 腳要接高電平,而(a、b、c、d、e、f、g、h )這些 引腳接低電平,那么第一行就會點(diǎn)亮;如要將第一列點(diǎn)亮,則第 a 腳接低電平, 而(1、2、3、4、5、6、7、8)接高電平,那么第一列就會點(diǎn)亮。
LED硬件設(shè)計
使用的的資源有:①8*8LED點(diǎn)陣模塊,②74HC595 模塊
????????從上圖中可以看出,74HC595需要用到的控制管腳是,SER、RCLK、SRCLK直接連接到51單片機(jī)的P3.4-P3.6 IO 口上,輸出端則是直接連接到LED點(diǎn)陣模塊的行端口上,即為LED發(fā)光二極管的陽極,LED點(diǎn)陣的列則為發(fā)光二極管的陰極。
????????想要 控制LED點(diǎn)陣,可以以將單片機(jī)管腳按照74HC595 芯片的通信時序要求來 傳輸數(shù)據(jù),這樣即可控制LED點(diǎn)陣的行的數(shù)據(jù),根據(jù)LED發(fā)光二極管的導(dǎo)通原理,當(dāng)陽極為高電平,陰極為低電平則點(diǎn)亮,否則熄滅。因此通過單片機(jī)P0端口控制點(diǎn)陣列,74HC595可控制點(diǎn)陣行。
? ? ? ? 如果要點(diǎn)亮左上角的一個點(diǎn),那就需要P07這一列為低電平,其余列是高電平,DPh這一行為高電平,其余行為低電平。那P07--P00口輸出就是 0111 1111(ox7f),DPh-DPa輸出就是1000 0000(0x80)
軟件設(shè)計如下:(74HC595部分和ID拓展的代碼一樣,但是RCLK時序有所改變,要讓RCLK下降有效,之前是(rCLK=0,rCLK=1)更改成(rCLK=0,rCLK=1,rCLK=0)或者(rCLK=1,rCLK=0)這里為啥要更換,之前為啥不用,我也沒有搞明白哦,知道的同學(xué)告訴我,謝謝!
/********************************************************************
****************** 實(shí)驗(yàn)名稱:IO 擴(kuò)展(串轉(zhuǎn)并)實(shí)驗(yàn)-74HC595
接線說明
實(shí)驗(yàn)現(xiàn)象:下載程序后,8*8LED 點(diǎn)陣以一行循環(huán)滾動顯示
注意事項(xiàng):LED 點(diǎn)陣旁的 J24 黃色跳線帽短接到 GND 一端
*********************************************************************
******************/
#include "reg52.h"
typedef unsigned int u16; //對系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
typedef unsigned char u8;
//定義 74HC595 控制管腳
sbit SRCLK=P3^6; //移位寄存器時鐘輸入
sbit rCLK=P3^5; //存儲寄存器時鐘輸入
sbit SER=P3^4; //串行數(shù)據(jù)輸入
#define LEDDZ_COL_PORT P0 //宏定義LED點(diǎn)陣列控制端口
/********************************************************************
***********
* 函 數(shù) 名 : delay_10us
* 函數(shù)功能 : 延時函數(shù),ten_us=1 時,大約延時 10us
* 輸 入 : ten_us
* 輸 出 : 無
*********************************************************************
**********/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/********************************************************************
***********
* 函 數(shù) 名 : delay_ms
* 函數(shù)功能 : ms 延時函數(shù),ms=1 時,大約延時 1ms
* 輸 入 : ten_us
* 輸 出 : 無
* for(j=110;j>0;j--)在for(i=ms;i>0;i--)嵌套這,delay_ms(500),
* 時候ms=500,i=ms 所以i=500,進(jìn)入for(i=ms;i>0;i--),
* 然后在執(zhí)行for(j=110;j>0;j--),進(jìn)行循環(huán)110次一直到j(luò)=0,
* 在退出for(j=110;j>0;j--),
* 在重新執(zhí)行for(i=ms;i>0;i--),一直到到i=0時候,退出for(i=ms;i>0;i--)
*********************************************************************
**********/
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
/********************************************************************
***********
* 函 數(shù) 名 : hc595_write_data(u8 dat)
* 函數(shù)功能 : 向 74HC595 寫入一個字節(jié)的數(shù)據(jù)
* 輸 入 : dat:數(shù)據(jù)
* 輸 出 : 無
*********************************************************************
**********/
/********************************************************************
*******************SER=dat>>7(dat向右移7位后賦值給SER)詳解*************
dat是后面要輸入的一個字節(jié)的數(shù)據(jù),hc595_write_data(0x00)如后面的
hc595_write_data(0x01),這時候dat就是(0x01)當(dāng)dat=00000001(0x01)時候,
高位是0,低位是1 ,對應(yīng)按照QH-QA,就是QH低電平,QA高電平,但是74HC595的傳輸
規(guī)律是先從高位在到低位的傳輸,左移1就傳給了QH,這樣QH高電平,QA為低電平,我們
想要QH輸入低電平怎么辦呢?就用把dat>>7,按照右移的規(guī)則(對于不帶字符的數(shù)值,
向右移位時,會在左邊的空位填充0。)那(0x01)就變成0(0X00)一個字節(jié)八位都是0
這樣傳輸給QH就是低電平,
*********************************************************************
**********/
/********************************************************************
*******************dat<<=1(dat向左移一位后在賦值給dat)詳解*************
但是for(i=0;i<8;i++)循環(huán)8次,八位就都是0,QH-QA都是低電平,這樣是不對的,
我們是要QA輸入高電平,這時候就需要每次循環(huán)的時候dat<<=1,每次SER=dat>>7;
執(zhí)行完dat<<=1,例如開始dat=(0x01),執(zhí)行完SER=dat>>7后,在把dat<<=1(dat向
左移一位后在賦值給dat),這樣下次在進(jìn)入SER=dat>>7時候,dat就是dat<<=1(0X02)
一直倒循環(huán)到第7次時候dat也左移了7位,dat變成了10000000(0x80),這時候在進(jìn)入
SER=dat>>7時候,SER就等于1,對應(yīng)QA傳輸,就按照hc595_write_data(0x01)的一樣
低位1,其余都是0的輸入。
*********************************************************************
**********/
/********************************************************************
*******************SRCLK=0,SRCLK=1詳解*******************************
74HC595芯片的傳輸規(guī)則,SER寫入數(shù)據(jù)后,要移位寄存器(SRCLK)時鐘上升沿,才能把
數(shù)據(jù)送到存儲寄存器進(jìn)行輸出,所有我們要先給SRCLK一個低電平,在給一個高電平,就產(chǎn)
生了上升沿,那我們就先SRCLK=0送入低電平;中間延時下,在SRCLK=1送入高電平,
一低一高,這樣就產(chǎn)生時鐘上升沿,就把數(shù)據(jù)送入到存儲寄存器,每次循環(huán)都送入存儲寄存器,
循環(huán)8次,就把8位的數(shù)據(jù)都送到存儲寄存器中了。
中間的delay_10us(1);這里的延時,不要也可以,但是以防出錯這里延時下
*********************************************************************
**********/
/********************************************************************
*******************rCLK=1,rCLK=0詳解*******************************
74HC595芯片的傳輸規(guī)則,如果將前面寫入存儲寄存器數(shù)據(jù)輸出,那存儲寄存器時鐘要
上升沿才能輸出,那我們就先rCLK=0送入低電平;中間延時下,在rCLK=1送入高電平,
一低一高,這樣產(chǎn)生時鐘上升沿,就將前面寫入到寄存器的數(shù)據(jù)輸出了。這里和74HC595DE
IO拓展代碼有所不一樣,RCLK時序有所改變,要讓RCLK下降有效,之前是
(rCLK=0,rCLK=1)更改成(rCLK=0,rCLK=1,rCLK=0)或者(rCLK=1,rCLK=0)
中間的delay_10us(1);這里的延時,不要也可以,但是以防出錯這里延時下
*********************************************************************
**********/
void hc595_write_data(u8 dat)
{
u8 i=0;
for(i=0;i<8;i++)//循環(huán) 8 次即可將一個字節(jié)寫入寄存器中
{
SER=dat>>7;//優(yōu)先傳輸一個字節(jié)中的高位
dat<<=1;//將低位移動到高位
SRCLK=0;
delay_10us(1);
SRCLK=1;
delay_10us(1);//移位寄存器時鐘上升沿將端口數(shù)據(jù)送入寄存器中
}
/********************************************************************
rCLK=0;
delay_10us(1);
rCLK=1;//存儲寄存器時鐘上升沿將前面寫入到寄存器的數(shù)據(jù)輸出
rCLK=0;
********************************************************************/
rCLK=1;
delay_10us(1);
rCLK=0;//存儲寄存器時鐘上升沿將前面寫入到寄存器的數(shù)據(jù)輸出
}
/********************************************************************
***********
* 函 數(shù) 名 : main
* 函數(shù)功能 : 主函數(shù)
* 輸 入 : 無
* 輸 出 : 無
*********************************************************************
**********/
/********************************************************************
*******************LEDDZ_COL_PORT=0x00詳解*******************************
我們在DPa---DPh輸入的是高電平,如果我們要將LED燈點(diǎn)亮,我們要把P0端口全部設(shè)為低電
平,即 LED 陰極為低電平,前面我們宏定義了P0端口,所以這里L(fēng)EDDZ_COL_PORT=0x00就可以
*********************************************************************
**********/
/********************************************************************
*******************hc595_write_data(ghc595_buf[i])詳解***************
我們定義了,數(shù)組ghc595_buf[],把每次輸出的數(shù)據(jù)儲存在里面,通過for循環(huán),依次
輸出,每次寫入新數(shù)據(jù)之前,要先消除前面輸出數(shù)據(jù)點(diǎn)亮LED進(jìn)行消影,所以每次在輸入
數(shù)據(jù)之前,我們先把所有DPa---DPh輸入低電平,來消除前面寄存器緩存數(shù)據(jù),之后在
在寫入新的數(shù)據(jù):這樣就產(chǎn)生了,LED點(diǎn)陣,從下到上,每行依次點(diǎn)亮
*********************************************************************
**********/
void main()
{
u8 i=0;
LEDDZ_COL_PORT=0x7f;//將 LED 點(diǎn)陣左邊第一列設(shè)置為 0,即 LED 陰極為低電平,其
余列為 1,即高電平
while(1)
{
for(i=0;i<8;i++)
{
//將 LED 點(diǎn)陣上邊第一行設(shè)置為 1,即 LED 陽極為高電平,其余行為 0,即低電平
hc595_write_data(0x80);
}
}
}
????????代碼很簡單,與上一章核心代碼是一樣的,這里主要是理解如何讓 LED 點(diǎn)陣 的左上角第一個點(diǎn)點(diǎn)亮,實(shí)際上就是將第一個點(diǎn)對應(yīng)的行為高電平,列為低電平 即可。也就是讓 74HC595 輸出 0X80(1000 0000),這樣點(diǎn)陣第一行就是高電平, 而 P0 口輸出 0X7F(0111 1111),這樣點(diǎn)陣第一列就是低電平,從而讓 LED 點(diǎn)陣第一個點(diǎn)點(diǎn)亮。?
顯示數(shù)字,顯示數(shù)字0:
數(shù)字取模和點(diǎn)亮一個燈類似,但是我們?yōu)榱烁奖愕牟僮?,我們借助一個“文字取模軟件”,來獲取行的值,取模軟件的使用方法就不在具體介紹了。在文字取模軟件中,獲取要顯示數(shù)字0,然后將生成的數(shù)據(jù)復(fù)制到我們程序定義的數(shù)組中,如下:
u8 gled_row[8]={0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38};//LED 點(diǎn)陣 顯示數(shù)字 0 的行數(shù)據(jù)
這些數(shù)據(jù)就是上述描繪的數(shù)字0從左到右依次每列對應(yīng)的行數(shù)據(jù)。至于其他數(shù)字或字符及簡單圖形的顯示取模方法與上述類似。文章來源:http://www.zghlxwxcb.cn/news/detail-486445.html
既然是動態(tài)掃描,就需要不斷的掃描每列,因此可以把LED點(diǎn)陣的列控制也用數(shù)組存儲起來,為了后面循環(huán)調(diào)用提供方面。根據(jù)數(shù)字 0 取模的數(shù)據(jù)特點(diǎn)是從左至右每列對應(yīng)的行數(shù)據(jù),因此掃描時也應(yīng)該從左至右的順序,如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-486445.html
u8 gled_col [ 8 ]={ 0x7f , 0xbf , 0xdf , 0xef , 0xf7 , 0xfb , 0xfd , 0xfe }; //LED 點(diǎn)陣 顯示數(shù)字 0 的列數(shù)據(jù)列的的數(shù)據(jù)基本上都是固定的,都是從左到右,每列依次進(jìn)行掃描,只用改變行的數(shù)據(jù)就可以生成不同的圖案
/********************************************************************
****************** 實(shí)驗(yàn)名稱:IO 擴(kuò)展(串轉(zhuǎn)并)實(shí)驗(yàn)-74HC595
接線說明
實(shí)驗(yàn)現(xiàn)象:下載程序后,8*8LED 點(diǎn)陣以一行循環(huán)滾動顯示
注意事項(xiàng):LED 點(diǎn)陣旁的 J24 黃色跳線帽短接到 GND 一端
*********************************************************************
******************/
#include "reg52.h"
typedef unsigned int u16; //對系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
typedef unsigned char u8;
//定義 74HC595 控制管腳
sbit SRCLK=P3^6; //移位寄存器時鐘輸入
sbit rCLK=P3^5; //存儲寄存器時鐘輸入
sbit SER=P3^4; //串行數(shù)據(jù)輸入
#define LEDDZ_COL_PORT P0 //宏定義LED點(diǎn)陣列控制端口
u8 gled_row[8]={0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0x00};//LED 點(diǎn)陣顯示數(shù)字 0 的行數(shù)據(jù)
u8 gled_col[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED 點(diǎn)陣顯示數(shù)字 0 的列數(shù)據(jù)
/********************************************************************
***********
* 函 數(shù) 名 : delay_10us
* 函數(shù)功能 : 延時函數(shù),ten_us=1 時,大約延時 10us
* 輸 入 : ten_us
* 輸 出 : 無
*********************************************************************
**********/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/********************************************************************
***********
* 函 數(shù) 名 : delay_ms
* 函數(shù)功能 : ms 延時函數(shù),ms=1 時,大約延時 1ms
* 輸 入 : ten_us
* 輸 出 : 無
* for(j=110;j>0;j--)在for(i=ms;i>0;i--)嵌套這,delay_ms(500),
* 時候ms=500,i=ms 所以i=500,進(jìn)入for(i=ms;i>0;i--),
* 然后在執(zhí)行for(j=110;j>0;j--),進(jìn)行循環(huán)110次一直到j(luò)=0,
* 在退出for(j=110;j>0;j--),
* 在重新執(zhí)行for(i=ms;i>0;i--),一直到到i=0時候,退出for(i=ms;i>0;i--)
*********************************************************************
**********/
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
/********************************************************************
***********
* 函 數(shù) 名 : hc595_write_data(u8 dat)
* 函數(shù)功能 : 向 74HC595 寫入一個字節(jié)的數(shù)據(jù)
* 輸 入 : dat:數(shù)據(jù)
* 輸 出 : 無
*********************************************************************
**********/
/********************************************************************
*******************SER=dat>>7(dat向右移7位后賦值給SER)詳解*************
dat是后面要輸入的一個字節(jié)的數(shù)據(jù),hc595_write_data(0x00)如后面的
hc595_write_data(0x01),這時候dat就是(0x01)當(dāng)dat=00000001(0x01)時候,
高位是0,低位是1 ,對應(yīng)按照QH-QA,就是QH低電平,QA高電平,但是74HC595的傳輸
規(guī)律是先從高位在到低位的傳輸,左移1就傳給了QH,這樣QH高電平,QA為低電平,我們
想要QH輸入低電平怎么辦呢?就用把dat>>7,按照右移的規(guī)則(對于不帶字符的數(shù)值,
向右移位時,會在左邊的空位填充0。)那(0x01)就變成0(0X00)一個字節(jié)八位都是0
這樣傳輸給QH就是低電平,
*********************************************************************
**********/
/********************************************************************
*******************dat<<=1(dat向左移一位后在賦值給dat)詳解*************
但是for(i=0;i<8;i++)循環(huán)8次,八位就都是0,QH-QA都是低電平,這樣是不對的,
我們是要QA輸入高電平,這時候就需要每次循環(huán)的時候dat<<=1,每次SER=dat>>7;
執(zhí)行完dat<<=1,例如開始dat=(0x01),執(zhí)行完SER=dat>>7后,在把dat<<=1(dat向
左移一位后在賦值給dat),這樣下次在進(jìn)入SER=dat>>7時候,dat就是dat<<=1(0X02)
一直倒循環(huán)到第7次時候dat也左移了7位,dat變成了10000000(0x80),這時候在進(jìn)入
SER=dat>>7時候,SER就等于1,對應(yīng)QA傳輸,就按照hc595_write_data(0x01)的一樣
低位1,其余都是0的輸入。
*********************************************************************
**********/
/********************************************************************
*******************SRCLK=0,SRCLK=1詳解*******************************
74HC595芯片的傳輸規(guī)則,SER寫入數(shù)據(jù)后,要移位寄存器(SRCLK)時鐘上升沿,才能把
數(shù)據(jù)送到存儲寄存器進(jìn)行輸出,所有我們要先給SRCLK一個低電平,在給一個高電平,就產(chǎn)
生了上升沿,那我們就先SRCLK=0送入低電平;中間延時下,在SRCLK=1送入高電平,
一低一高,這樣就產(chǎn)生時鐘上升沿,就把數(shù)據(jù)送入到存儲寄存器,每次循環(huán)都送入存儲寄存器,
循環(huán)8次,就把8位的數(shù)據(jù)都送到存儲寄存器中了。
中間的delay_10us(1);這里的延時,不要也可以,但是以防出錯這里延時下
*********************************************************************
**********/
/********************************************************************
*******************rCLK=1,rCLK=0詳解*******************************
74HC595芯片的傳輸規(guī)則,如果將前面寫入存儲寄存器數(shù)據(jù)輸出,那存儲寄存器時鐘要
上升沿才能輸出,那我們就先rCLK=0送入低電平;中間延時下,在rCLK=1送入高電平,
一低一高,這樣產(chǎn)生時鐘上升沿,就將前面寫入到寄存器的數(shù)據(jù)輸出了。這里和74HC595DE IO拓展代碼有所不一樣,RCLK時序有所改變,要讓RCLK下降有效,之前是(rCLK=0,rCLK=1)更改成(rCLK=0,rCLK=1,rCLK=0)或者(rCLK=1,rCLK=0)
中間的delay_10us(1);這里的延時,不要也可以,但是以防出錯這里延時下
*********************************************************************
**********/
void hc595_write_data(u8 dat)
{
u8 i=0;
for(i=0;i<8;i++)//循環(huán) 8 次即可將一個字節(jié)寫入寄存器中
{
SER=dat>>7;//優(yōu)先傳輸一個字節(jié)中的高位
dat<<=1;//將低位移動到高位
SRCLK=0;
delay_10us(1);
SRCLK=1;
delay_10us(1);//移位寄存器時鐘上升沿將端口數(shù)據(jù)送入寄存器中
}
/********************************************************************
rCLK=0;
delay_10us(1);
rCLK=1;//存儲寄存器時鐘上升沿將前面寫入到寄存器的數(shù)據(jù)輸出
rCLK=0;
********************************************************************/
rCLK=1;
delay_10us(1);
rCLK=0;//存儲寄存器時鐘上升沿將前面寫入到寄存器的數(shù)據(jù)輸出
}
/********************************************************************
***********
* 函 數(shù) 名 : main
* 函數(shù)功能 : 主函數(shù)
* 輸 入 : 無
* 輸 出 : 無
*********************************************************************
**********/
/********************************************************************
*******************LEDDZ_COL_PORT=0x00詳解*******************************
我們在DPa---DPh輸入的是高電平,如果我們要將LED燈點(diǎn)亮,我們要把P0端口全部設(shè)為低電
平,即 LED 陰極為低電平,前面我們宏定義了P0端口,所以這里L(fēng)EDDZ_COL_PORT=0x00就可以
*********************************************************************
**********/
/********************************************************************
*******************hc595_write_data(ghc595_buf[i])詳解***************
我們定義了,數(shù)組ghc595_buf[],把每次輸出的數(shù)據(jù)儲存在里面,通過for循環(huán),依次
輸出,每次寫入新數(shù)據(jù)之前,要先消除前面輸出數(shù)據(jù)點(diǎn)亮LED進(jìn)行消影,所以每次在輸入
數(shù)據(jù)之前,我們先把所有DPa---DPh輸入低電平,來消除前面寄存器緩存數(shù)據(jù),之后在
在寫入新的數(shù)據(jù):這樣就產(chǎn)生了,LED點(diǎn)陣,從下到上,每行依次點(diǎn)亮
*********************************************************************
**********/
void main()
{
u8 i=0;
LEDDZ_COL_PORT=0x7f;//將 LED 點(diǎn)陣左邊第一列設(shè)置為 0,即 LED 陰極為低電平,其
余列為 1,即高電平
while(1)
{
for(i=0;i<8;i++)
{
LEDDZ_COL_PORT=gled_col[i];//傳送列選數(shù)據(jù)
hc595_write_data(gled_row[i]);//傳送行選數(shù)據(jù)
delay_10us(100);//延時一段時間,等待顯示穩(wěn)定
hc595_write_data(0x00);//消影
}
}
}
到了這里,關(guān)于51單片機(jī)——LED 點(diǎn)陣點(diǎn)亮一個點(diǎn),小白詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!