内容
点亮一个点;
显示数字;
显示图像;
LED点阵简介
LED 点阵是由发光二极管排列组成的显示器件
通常应用较多的是8 * 8点阵,然后使用多个8 * 8点阵可组成不同分辨率的LED点阵显示屏,比如16 * 16点阵可以使用4个8 * 8点阵构成;因此理解了8 * 8LED点阵的工作原理,其他分辨率的LED点阵显示屏都是一样的;
8 * 8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮;
原理图
由图可知,点亮一个点,只需让对应行输出高电平,对应列输出低电平即可;
点亮一个点
思路
第一列置低电平,第一行置高电平;
编码
main.c
/*
* @Description: 点亮一个点
*/
#include "reg52.h"
typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;
// 定义74HC595控制管脚
sbit SCK = P3 ^ 6; // 移位寄存器时钟输入
sbit RCK = P3 ^ 5; // 存储寄存器时钟输入
sbit SER = P3 ^ 4; // 串行数据输入
#define LEDDZ_COL_PORT P0 // 点阵列控制端口
/**
* @description: 延时函数(循环一次大约10us)
* @param {u16} ten_us
* @return {*}
*/
void delay_10us(u16 ten_us)
{
while (ten_us--)
;
}
/**
* @description: 延时函数(循环一次大约1ms)
* @param {u16} ms
* @return {*}
*/
void delay_ms(u16 ms)
{
u16 i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--)
;
}
/**
* @description: 向74HC595写入一个字节的数据
* @param {u8} dat 要写入的数据
* @return {*}
*/
void hc595_write_data(u8 dat)
{
u8 i = 0;
for (i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中
{
SER = dat >> 7; // 优先传输一个字节中的高位
dat <<= 1; // 将低位移动到高位
SCK = 0;
delay_10us(1);
SCK = 1; // 移位寄存器SCK时钟上升沿将端口数据送入存储寄存器RCK中
delay_10us(1);
}
RCK = 1; // 存储寄存器RCK时钟上升沿将前面写入到寄存器的数据输出
delay_10us(1);
RCK = 0;
}
void main()
{
u8 i = 0;
LEDDZ_COL_PORT = 0x7f; // 将LED点阵左边第一列设置为0,即LED阴极为低电平,其余列为1,即高电平
while (1)
{
hc595_write_data(0x80); // 将LED点阵上边第一行设置为1,即LED阳极为高电平,其余行为0,即低电平
}
}
编译和结果
按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机
(注意把LED点阵旁的J24黄色跳线帽短接到GND一端)
结果:led点阵第一个点被点亮
显示数字
思路
利用动态扫描的思想,只要使两个点被点亮间隔不超过24ms,那么点看起来就像连续点亮一样;
把我们想要显示的数字在8 * 8点阵里用每个点表示出来(推荐使用文字取模软件)
循环扫描8行(每次让一行为1,其余行为0),显示每行需要点亮的点(行扫描法)
编码
main.c
/*
* @Description: 显示数字
*/
#include "reg52.h"
typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;
// 定义74HC595控制管脚
sbit SCK = P3 ^ 6; // 移位寄存器时钟输入
sbit RCK = P3 ^ 5; // 存储寄存器时钟输入
sbit SER = P3 ^ 4; // 串行数据输入
#define LEDDZ_COL_PORT P0 // 点阵列控制端口
u8 gled_row[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; // LED点阵显示数字6的行数据
u8 gled_col[8] = {0xff, 0x83, 0xbf, 0xbf, 0x83, 0xbb, 0xbb, 0x83}; // LED点阵显示数字6的列数据
/**
* @description: 延时函数(循环一次大约10us)
* @param {u16} ten_us
* @return {*}
*/
void delay_10us(u16 ten_us)
{
while (ten_us--)
;
}
/**
* @description: 延时函数(循环一次大约1ms)
* @param {u16} ms
* @return {*}
*/
void delay_ms(u16 ms)
{
u16 i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--)
;
}
/**
* @description: 向74HC595写入一个字节的数据
* @param {u8} dat 要写入的数据
* @return {*}
*/
void hc595_write_data(u8 dat)
{
u8 i = 0;
for (i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中
{
SER = dat >> 7; // 优先传输一个字节中的高位
dat <<= 1; // 将低位移动到高位
SCK = 0;
delay_10us(1);
SCK = 1; // 移位寄存器SCK时钟上升沿将端口数据送入存储寄存器RCK中
delay_10us(1);
}
RCK = 1; // 存储寄存器RCK时钟上升沿将前面写入到寄存器的数据输出
delay_10us(1);
RCK = 0;
}
void main()
{
u8 i = 0;
while (1)
{
for (i = 0; i < 8; i++) // 循环8次扫描8行、列
{
hc595_write_data(gled_row[i]); // 传送行选数据
LEDDZ_COL_PORT = gled_col[i]; // 传送列选数据
delay_10us(100); // 延时一段时间,等待显示稳定
hc595_write_data(0x00); // 消影
}
}
}
编译和结果
按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机
结果:显示数字6
显示图像
思路
与显示数字相同,但是我们这里用列扫描法;
编码
main.c
/*
* @Description: 显示图像
*/
#include "reg52.h"
typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;
// 定义74HC595控制管脚
sbit SCK = P3 ^ 6; // 移位寄存器时钟输入
sbit RCK = P3 ^ 5; // 存储寄存器时钟输入
sbit SER = P3 ^ 4; // 串行数据输入
#define LEDDZ_COL_PORT P0 // 点阵列控制端口
u8 gled_row[8] = {0x38, 0x7C, 0x7E, 0x3F, 0x3F, 0x7E, 0x7C, 0x38}; // LED点阵显示数字6的行数据
u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; // LED点阵显示数字6的列数据
/**
* @description: 延时函数(循环一次大约10us)
* @param {u16} ten_us
* @return {*}
*/
void delay_10us(u16 ten_us)
{
while (ten_us--)
;
}
/**
* @description: 延时函数(循环一次大约1ms)
* @param {u16} ms
* @return {*}
*/
void delay_ms(u16 ms)
{
u16 i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--)
;
}
/**
* @description: 向74HC595写入一个字节的数据
* @param {u8} dat 要写入的数据
* @return {*}
*/
void hc595_write_data(u8 dat)
{
u8 i = 0;
for (i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中
{
SER = dat >> 7; // 优先传输一个字节中的高位
dat <<= 1; // 将低位移动到高位
SCK = 0;
delay_10us(1);
SCK = 1; // 移位寄存器SCK时钟上升沿将端口数据送入存储寄存器RCK中
delay_10us(1);
}
RCK = 1; // 存储寄存器RCK时钟上升沿将前面写入到寄存器的数据输出
delay_10us(1);
RCK = 0;
}
void main()
{
u8 i = 0;
while (1)
{
for (i = 0; i < 8; i++) // 循环8次扫描8行、列
{
LEDDZ_COL_PORT = gled_col[i]; // 传送列选数据
hc595_write_data(gled_row[i]); // 传送行选数据
delay_10us(100); // 延时一段时间,等待显示稳定
hc595_write_data(0x00); // 消影
}
}
}
编译和结果
按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机
结果:显示一个爱心