本實(shí)驗(yàn)實(shí)現(xiàn)的功能是使用74HC595芯片實(shí)在LED點(diǎn)陣中顯示數(shù)字字符0。
要點(diǎn)亮多個(gè)LED燈,需要用到動(dòng)態(tài)數(shù)碼管的動(dòng)態(tài)掃描原理。
首先如何點(diǎn)亮一行上面的多個(gè)燈或一列上面的多個(gè)燈,明顯就是需要某行或某列有效,同時(shí)使多列或多行有效。比如在第一行有效的情況下,有效列與這一行交點(diǎn)上的LED燈就會(huì)被點(diǎn)亮。
要實(shí)現(xiàn)行列不同位置亮燈,需要使用到動(dòng)態(tài)顯示的方法,也要結(jié)合掃描的方法。
在第一行亮燈一段時(shí)間以后滅掉,點(diǎn)亮第二行一段時(shí)間以后滅掉,點(diǎn)亮第三行一段時(shí)間后滅掉,如此點(diǎn)亮,直到行全部點(diǎn)亮一次,在第一行點(diǎn)亮到最后一行滅掉的總時(shí)間不能超過人肉眼可識(shí)別的時(shí)間,即24毫秒。在每一行點(diǎn)亮的時(shí)候,給列一個(gè)新的數(shù)據(jù),此時(shí)對(duì)應(yīng)列在該行上要點(diǎn)亮的燈的數(shù)據(jù)。這種方式類似數(shù)碼管的動(dòng)態(tài)顯示一樣,不同的是數(shù)碼管的LED燈是段值,LED點(diǎn)陣是多個(gè)LED點(diǎn)亮。
要想在點(diǎn)陣上顯示數(shù)字等字符,首先要獲取在LED點(diǎn)陣上顯示數(shù)字字符所需的數(shù)據(jù),即一個(gè)數(shù)字字符在LED點(diǎn)陣上顯示,對(duì)應(yīng)的每行每列都會(huì)有一些燈點(diǎn)亮或者熄滅,這樣就會(huì)構(gòu)成一組數(shù)據(jù),亦即數(shù)字字符的顯示數(shù)據(jù),將這些數(shù)據(jù)通過74HC595發(fā)送到點(diǎn)陣對(duì)應(yīng)的行或列就能顯示數(shù)字字符。
數(shù)字字符的獲取可以使用相關(guān)軟件獲取。這里提供一種文字取模軟件,如下:

比如顯示數(shù)字0,如下:

取模數(shù)據(jù)為:
u8 ledduan[] = {0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00}; // 類似于數(shù)碼管的段選
在proteus中,紅色的LED點(diǎn)陣模塊采用上列下行的方式,電流通過方向?yàn)榱?>行,所以如果要點(diǎn)亮的話,行設(shè)置為0,列設(shè)置為1。如下,如果要點(diǎn)亮第一個(gè)LED,那么需要P0=0x01,D7-D0 = ~0x01。

顯示如下數(shù)字0,軟件實(shí)現(xiàn)如下:

/*
實(shí)現(xiàn)功能:74HC595芯片控制LED點(diǎn)陣顯示數(shù)字0
[2023-12-11] zoya
*/
#include "reg52.h"
#include "intrins.h"
#include "HC595.h"
u8 ledduan = B11111110;
u8 ledwei0[] = {
B00111000, // 0x38
B01000100, // 0x44
B01000100, // 0x44
B01000100, // 0x44
B01000100, // 0x44
B01000100, // 0x44
B00111000, // 0x38
B00000000}; // 列1
// 延時(shí)函數(shù),i=1時(shí)延時(shí)10us
void Delay(u16 i)
{
while(i--);
}
void main()
{
u8 i;
while(1)
{
for(i=0;i<8;i++)
{
HC595SendByte(ledduan); // 發(fā)送段選數(shù)據(jù)
P0 = ledwei0[i];
Delay(100);
ledduan = _crol_(ledduan,1);
}
}
}
其中函數(shù)HC595SendByte實(shí)現(xiàn)如下:
/*************************************************************************
* 函數(shù)名: HC595SendByte
* 函數(shù)功能: 74HC595芯片將輸入的一個(gè)字節(jié)的串行數(shù)據(jù)轉(zhuǎn)換為并行數(shù)據(jù)輸出
* 輸入: dat:74HC595要輸出的一個(gè)字節(jié)的數(shù)據(jù)
* 輸出: void
**************************************************************************/
void HC595SendByte(u8 dat)
{
u8 i;
STCP = 1; // 高電平時(shí)存儲(chǔ)寄存器數(shù)據(jù)保持不變
SHCP = 1; // 高電平時(shí)移位寄存器數(shù)據(jù)保持不變
for(i=0;i<8;i++)
{
DS = dat >> 7; // 每次輸入最高位數(shù)據(jù)
dat <<= 1; // 移位后將dat數(shù)據(jù)左移一位,保證下一次移入的數(shù)據(jù)在最高位
// 實(shí)現(xiàn)移位寄存器的時(shí)序,需要SHCP有一個(gè)上升沿,所以先將SHCP置0,然后置1
SHCP = 0;
_nop_(); // 空指令,不做任何操作,當(dāng)做延時(shí)使用
_nop_();
SHCP = 1;
}
// 數(shù)據(jù)已經(jīng)在移位寄存器了,現(xiàn)在將移位寄存器的數(shù)據(jù)輸出到存儲(chǔ)寄存器
// STCP上升沿時(shí)將數(shù)據(jù)從移位寄存器輸出到存儲(chǔ)寄存器
STCP = 0;
_nop_();
_nop_();
STCP = 1;
}
仿真結(jié)果:

如果要顯示1,如下

軟件設(shè)計(jì)如下:
/*
實(shí)現(xiàn)功能:74HC595芯片控制LED點(diǎn)陣顯示數(shù)字1
[2023-12-11] zoya
*/
#include "reg52.h"
#include "intrins.h"
#include "HC595.h"
u8 ledduan = B11111110;
u8 ledwei[] = {0x10,0x18,0x10,0x10,0x10,0x10,0x7C,0x00};
// 延時(shí)函數(shù),i=1時(shí)延時(shí)10us
void Delay(u16 i)
{
while(i--);
}
void main()
{
u8 i;
while(1)
{
for(i=0;i<8;i++)
{
HC595SendByte(ledduan); // 發(fā)送段選數(shù)據(jù)
P0 = ledwei[i];
Delay(200);
ledduan = _crol_(ledduan,1);
}
}
}
仿真結(jié)果:
