点阵屏与74Hc595模块
编辑
12
2024-11-26
1. 点阵屏
- LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。
- LED点阵屏广泛应用于各种公共场合,如汽车报站器、广告屏以及公告牌等。
- LED点阵屏分类
- 按颜色:单色、双色、全彩
- 按像素:8x8、16x16等(大规模的LED点阵通常由很多个小点阵拼接而成)
点阵屏由于接口很多,一般是采用扫描的方式来显示,逐行或者逐列快速显示,和数码管很像,也是位选然后段选
需要注意:段选 位选之后 先延时对位进行清零 然后在进行段选, 否则位选过去之后,段选还没过来,就会有残影出来
2. 74HC595芯片
因为点阵屏需要的引脚数量比较多,所以一般会采用串转并芯片来控制引脚扫描
74HC595是串行输入并行输出的移位寄存器,可用3根线输入串行数据,8根线输出并行数据,多片级联后,可输出16位、24位、32位等,常用于IO口扩展。
也就是可以用三根线,并行输出8位,后面还可以进行级联。
下面是一个简单示意图(取自江协)
简单来说传输一个字节的数据就是
- 先给SER最高位数据
- 给SERCLK置1,也就是把SER数据推进寄存器,然后在清空SERCLK
- 继续1-2操作把剩下的数据都推进去
- 最后所有数据都进去了,给RCLK置1,把这8位数据一次性推给输出
代码方面就是这样的操作
/// @brief 向74HC595写入一个字节的数据
/// @param byte 要写入的数据
void _74Hc595_writeByte(unsigned char byte)
{
unsigned char i;
RCK = 0;
SCK = 0;
for (i = 0; i < 8; i++)
{
SER = byte & (0X80 >> i);
SCK = 1;
SCK = 0;
}
RCK = 1;
RCK = 0;
}
3. 控制74HC595扫描显示点阵屏
刚才说到要显示,需要扫描进行,这里逐列扫描显示,因为74HC595是控制行显示
首先单独显示一列
/// @brief 显示某一列的数据
/// @param col 要显示的列,取值范围为1-8
/// @param dataValue 要显示的数据,低位有效,8位,每一位代表一个LED的亮灭
/// 注意:本函数只能显示一列的数据,且只显示一瞬间,需要循环调用,扫描使用
void matrixLED_showCol(unsigned char col, unsigned char dataValue)
{
if (col<1 || col>8)
{
return;
}
_74Hc595_writeByte(dataValue);
MATRIX_LED_PROT = ~(0x80 >> (col-1));
Delay(1);
MATRIX_LED_PROT = 0xff; // 位选清空
}
然后再进行扫描,可以用主循环扫描,也可以用时钟扫描
/// @brief 显示整个8*8点阵的数据
/// @param data 要显示的数据,8个字节,每个字节代表一列的数据
void matrixLED_show(unsigned char Font_data[])
{
unsigned char i;
for (i = 0; i < 8; i++)
{
matrixLED_showCol(i + 1, Font_data[i]);
Delay(1);
}
}
主循环扫描
unsigned char code Font_Data[] ={0x00, 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x00, /* H */};
int main()
{
while (1)
{
matrixLED_show(Font_Data);
}
}
逐帧显示或者滚动显示
实现逐帧显示或者滚动显示,只需要定义一个装有所有数据的数组,然后采取不同的跳跃策略就可以做到,但是这个跳跃就需要在时钟中断中做了
unsigned char code Font_Data[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
0x00, 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x00, /* H */
0x00, 0x7f, 0x49, 0x49, 0x49, 0x41, 0x02, 0x00, /* E */
0x00, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, /* L */
0x00, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, /* L */
0x00, 0x3e, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, /* O */
0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, /* ! */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
};
unsigned char i, offset;
int main()
{
Time0_Init();
// matrixLED_showCol(1, 0x55);
while (1)
{
// 每次显示8列数据
matrixLED_show(Font_Data + offset); // 流动显示
// matrixLED_show(Font_Data + i * 8); // 逐帧显示
}
}
void Time0_Rountine() interrupt 1 // 定时器0中断函数
{
static unsigned int T0count = 0;
// 由于是溢出计时,且没有自动重装,每次进入中断要重新赋值
TL0 = 0x66; // 设置定时初始值 低8位 当前为100us中断一次
TH0 = 0xFC; // 设置定时初始值 高8位
T0count++;
if (T0count >= 300) //
{
T0count = 0;
// i = (i + 1) % (sizeof(Font_Data)/8);
offset = (offset + 1) % (sizeof(Font_Data)-8);
}
}
- 0
- 0
-
分享