一、项目概述
本项目使用51单片机(如STC89C52)控制8×8 LED点阵,实现汉字的显示和上下左右滚动效果。通过动态扫描技术和字模数据管理,实现"中"、"国"等汉字的平滑滚动显示。
二、系统硬件设计
1. 硬件连接
+------------+ +-----------------+
| 51单片机 | | 8×8 LED点阵 |
| (STC89C52) | | (共阳/共阴) |
| | | |
| P0.0~P0.7 |--------->| 列数据 (D0-D7) |
| | | |
| P2.0~P2.7 |--------->| 行控制 (R0-R7) |
| | | |
| GND |--------->| 公共端 (COM) |
+------------+ +-----------------+
2. 元件清单
| 元件名称 | 规格参数 | 数量 | 备注 |
|---|---|---|---|
| 51单片机 | STC89C52RC | 1 | 主控制器 |
| LED点阵 | 8×8 红色 | 1 | 共阳或共阴 |
| 排阻 | 10kΩ 9P4R | 1 | 上拉电阻 |
| 晶振 | 11.0592MHz | 1 | 系统时钟 |
| 电容 | 30pF | 2 | 晶振负载电容 |
| 电解电容 | 10μF/16V | 1 | 复位电容 |
| 电阻 | 10kΩ | 1 | 复位电阻 |
| 轻触开关 | 6×6×5mm | 2 | 控制按钮 |
| 电源 | 5V DC | 1 | 系统供电 |
三、软件设计
1. 字模数据
c
// 汉字字模数据 (8×8)
// 格式: 每行1字节, 1表示亮, 0表示灭
// 取模方式: 纵向取模, 字节倒序
// 中
unsigned char code hanzi_zhong[] = {
0x00, 0x00, 0x3E, 0x22, 0x22, 0x3E, 0x00, 0x00
};
// 国
unsigned char code hanzi_guo[] = {
0x00, 0x3E, 0x22, 0x22, 0x3E, 0x00, 0x3E, 0x00
};
// 欢
unsigned char code hanzi_huan[] = {
0x00, 0x3F, 0x15, 0x15, 0x15, 0x3F, 0x00, 0x00
};
// 迎
unsigned char code hanzi_ying[] = {
0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00
};
2. 主程序框架
c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 点阵引脚定义
sbit ROW0 = P2^0;
sbit ROW1 = P2^1;
sbit ROW2 = P2^2;
sbit ROW3 = P2^3;
sbit ROW4 = P2^4;
sbit ROW5 = P2^5;
sbit ROW6 = P2^6;
sbit ROW7 = P2^7;
// 函数声明
void delay_ms(uint ms);
void display_char(uchar *char_data, uchar pos);
void scroll_up(uchar *text, uchar len);
void scroll_down(uchar *text, uchar len);
void scroll_left(uchar *text, uchar len);
void scroll_right(uchar *text, uchar len);
void show_static(uchar *text, uchar len);
// 主函数
void main() {
uchar mode = 0; // 0:静态 1:上滚 2:下滚 3:左滚 4:右滚
while(1) {
if(P3^0 == 0) { // 模式切换按钮
delay_ms(10);
if(P3^0 == 0) {
mode = (mode + 1) % 5;
while(!P3^0); // 等待释放
}
}
switch(mode) {
case 0: // 静态显示
show_static(hanzi_zhong, 1);
break;
case 1: // 上滚
scroll_up(hanzi_guo, 1);
break;
case 2: // 下滚
scroll_down(hanzi_huan, 1);
break;
case 3: // 左滚
scroll_left(hanzi_ying, 1);
break;
case 4: // 右滚
scroll_right(hanzi_zhong, 1);
break;
}
}
}
3. 显示函数实现
c
// 显示单个字符
void display_char(uchar *char_data, uchar pos) {
uchar i, j;
uchar row_data;
for(i = 0; i < 8; i++) {
// 行选择
P2 = ~(0x01 << i);
// 列数据
row_data = char_data[i];
P0 = row_data;
// 短暂延时
delay_ms(2);
// 消隐
P0 = 0xFF;
}
}
// 静态显示多个字符
void show_static(uchar *text, uchar len) {
uchar i, j, k;
uchar display_data[8] = {0};
// 合并多个字符
for(k = 0; k < len; k++) {
for(i = 0; i < 8; i++) {
if(k == 0) {
display_data[i] = text[k*8 + i];
} else {
// 多字符显示需扩展为16×8点阵
}
}
}
// 显示
for(j = 0; j < 100; j++) { // 显示一段时间
for(i = 0; i < 8; i++) {
P2 = ~(0x01 << i);
P0 = display_data[i];
delay_ms(2);
P0 = 0xFF;
}
}
}
4. 滚动函数实现
c
// 向上滚动
void scroll_up(uchar *text, uchar len) {
uchar i, j, k;
uchar display_data[8] = {0};
for(k = 0; k < 8; k++) { // 滚动8行
for(i = 0; i < 8; i++) {
if(i + k < 8) {
display_data[i] = text[i + k];
} else {
display_data[i] = 0x00;
}
}
// 显示一帧
for(j = 0; j < 5; j++) { // 每帧显示5次
for(i = 0; i < 8; i++) {
P2 = ~(0x01 << i);
P0 = display_data[i];
delay_ms(2);
P0 = 0xFF;
}
}
}
}
// 向下滚动
void scroll_down(uchar *text, uchar len) {
uchar i, j, k;
uchar display_data[8] = {0};
for(k = 0; k < 8; k++) {
for(i = 0; i < 8; i++) {
if(i - k >= 0) {
display_data[i] = text[i - k];
} else {
display_data[i] = 0x00;
}
}
for(j = 0; j < 5; j++) {
for(i = 0; i < 8; i++) {
P2 = ~(0x01 << i);
P0 = display_data[i];
delay_ms(2);
P0 = 0xFF;
}
}
}
}
// 向左滚动
void scroll_left(uchar *text, uchar len) {
uchar i, j, k, m;
uchar display_data[8] = {0};
for(k = 0; k < 8; k++) { // 滚动8列
for(i = 0; i < 8; i++) {
display_data[i] = 0x00;
for(m = 0; m < 8; m++) {
if(m + k < 8) {
// 从字模中提取位
if(text[i] & (0x80 >> (m + k))) {
display_data[i] |= (0x01 << m);
}
}
}
}
for(j = 0; j < 5; j++) {
for(i = 0; i < 8; i++) {
P2 = ~(0x01 << i);
P0 = display_data[i];
delay_ms(2);
P0 = 0xFF;
}
}
}
}
// 向右滚动
void scroll_right(uchar *text, uchar len) {
uchar i, j, k, m;
uchar display_data[8] = {0};
for(k = 0; k < 8; k++) {
for(i = 0; i < 8; i++) {
display_data[i] = 0x00;
for(m = 0; m < 8; m++) {
if(m - k >= 0) {
if(text[i] & (0x80 >> (m - k))) {
display_data[i] |= (0x01 << m);
}
}
}
}
for(j = 0; j < 5; j++) {
for(i = 0; i < 8; i++) {
P2 = ~(0x01 << i);
P0 = display_data[i];
delay_ms(2);
P0 = 0xFF;
}
}
}
}
5. 延时函数
c
// 毫秒级延时
void delay_ms(uint ms) {
uint i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 114; j++);
}
四、多汉字显示扩展
1. 多汉字字模
c
// 多汉字字模 (16×8点阵)
unsigned char code multi_hanzi[][16] = {
// 中国
{0x00,0x00,0x3E,0x22,0x22,0x3E,0x00,0x00, // 中
0x00,0x3E,0x22,0x22,0x3E,0x00,0x3E,0x00}, // 国
// 欢迎
{0x00,0x3F,0x15,0x15,0x15,0x3F,0x00,0x00, // 欢
0x00,0x0C,0x0C,0x3F,0x0C,0x0C,0x00,0x00} // 迎
};
2. 多汉字显示函数
c
// 显示多汉字
void show_multi_hanzi(uchar index) {
uchar i, j, k;
uchar page;
for(page = 0; page < 2; page++) { // 分两页显示
for(i = 0; i < 8; i++) { // 每页8行
P2 = ~(0x01 << i);
for(k = 0; k < 2; k++) { // 两个汉字
uchar char_index = index * 2 + k;
uchar row_data = multi_hanzi[char_index][page*8 + i];
P0 = row_data;
}
delay_ms(2);
P0 = 0xFF;
}
}
}
五、Proteus仿真设计
1. 仿真电路图
c
+----------+ +-----------------+
| STC89C52| | 8×8 LED Matrix |
| | | (共阳) |
| P0.0-D0 |---->| D0 |
| P0.1-D1 |---->| D1 |
| ... | | ... |
| P0.7-D7 |---->| D7 |
| | | |
| P2.0-R0 |---->| R0 |
| P2.1-R1 |---->| R1 |
| ... | | ... |
| P2.7-R7 |---->| R7 |
+----------+ +-----------------+
2. 仿真效果
-
静态显示:汉字在8×8点阵上稳定显示
-
上滚效果:汉字从下向上滚动
-
下滚效果:汉字从上向下滚动
-
左滚效果:汉字从右向左滚动
-
右滚效果:汉字从左向右滚动
参考代码 51单片机控制8×8点阵 上下左右显示汉字 www.youwenfan.com/contentcss/182604.html
六、实际应用优化
1. 亮度控制
c
// PWM调光
void adjust_brightness(uchar level) {
uchar pwm_count = 0;
while(1) {
if(pwm_count < level) {
// 正常显示
} else {
// 关闭显示
}
pwm_count++;
if(pwm_count >= 10) pwm_count = 0;
}
}
2. 动画效果
c
// 闪烁效果
void blink_effect(uchar *text, uchar len) {
uchar i;
for(i = 0; i < 5; i++) {
show_static(text, len);
delay_ms(200);
clear_display();
delay_ms(200);
}
}
// 渐变效果
void fade_effect(uchar *text, uchar len) {
uchar i, j;
for(i = 0; i < 8; i++) {
for(j = 0; j < 8; j++) {
// 逐步增加亮度
}
show_static(text, len);
delay_ms(100);
}
}
七、项目扩展
1. 多方向组合滚动
c
// 对角线滚动
void diagonal_scroll(uchar *text, uchar len) {
uchar i, j, k, m;
uchar display_data[8] = {0};
for(k = 0; k < 16; k++) { // 滚动16步
for(i = 0; i < 8; i++) {
for(m = 0; m < 8; m++) {
uchar x = (i + k) % 8;
uchar y = (m + k) % 8;
if(y < 8) {
if(text[x] & (0x80 >> y)) {
display_data[i] |= (0x01 << m);
}
}
}
}
// 显示一帧
for(j = 0; j < 3; j++) {
for(i = 0; i < 8; i++) {
P2 = ~(0x01 << i);
P0 = display_data[i];
delay_ms(2);
P0 = 0xFF;
}
}
}
}
2. 点阵显示图形
c
// 心形图案
unsigned char code heart[] = {
0x00, 0x66, 0x99, 0x81, 0x81, 0x42, 0x24, 0x18
};
// 笑脸图案
unsigned char code smiley[] = {
0x3C, 0x42, 0xA5, 0x81, 0x81, 0xA5, 0x42, 0x3C
};
八、使用说明
-
硬件连接:
-
将51单片机的P0口连接到点阵的列数据线
-
将P2口连接到点阵的行控制线
-
共阳点阵:行接高电平,列接低电平时点亮
-
共阴点阵:行接低电平,列接高电平时点亮
-
-
功能选择:
-
通过按钮切换显示模式
-
模式0:静态显示
-
模式1:向上滚动
-
模式2:向下滚动
-
模式3:向左滚动
-
模式4:向右滚动
-
-
自定义字模:
-
使用字模软件生成所需汉字的点阵数据
-
替换程序中的字模数组
-
注意取模方式与程序一致(纵向取模,字节倒序)
-
九、项目总结
本设计实现了51单片机控制8×8点阵显示汉字及滚动效果,具有以下特点:
-
支持静态显示和上下左右四种滚动方式
-
可扩展为多汉字显示
-
提供多种动画效果(闪烁、渐变等)
-
代码结构清晰,易于扩展
-
资源占用少,适合51单片机