#include <reg51.h>
typedef unsigned char u8;
typedef unsigned int u16;
// 引脚定义
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
#define LEDDZ_COL_PORT P0
// 显示模式定义
#define MODE_STATIC 0
#define MODE_SLIDESHOW 1
#define MODE_SCROLLING 2
// 按键返回值定义
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
// 当前状态
u8 displayInfo = 0; // 0:个人信息, 1:Hello World!
u8 displayMode = MODE_STATIC;
u16 displaySpeed = 50; // 默认速度单位:毫秒
bit screenOn = 1;
bit speedChanged = 0; // 速度改变标志
// 个人信息字模
u8 code personalInfo[][8] = {
{0x00,0x7C,0x54,0xFF,0x55,0x7D,0x01,0x03},//电
{0x20,0x44,0xD4,0x54,0x54,0x46,0x01,0x01},//气
{0x00,0x00,0x6E,0x4A,0x4A,0x7A,0x00,0x00},// 2
{0x00,0x00,0x49,0x49,0x49,0x7F,0x00,0x00},// 3
{0x00,0x00,0x10,0x10,0x10,0x10,0x00,0x00},// -
{0x00,0x00,0x6E,0x4A,0x4A,0x7A,0x00,0x00},// 2
{0x00,0x64,0x92,0x92,0x92,0x4C,0x00,0x00},// S
{0x00,0x40,0x20,0x1E,0x20,0x40,0x00,0x00},// Y
{0x00,0x42,0x46,0x4A,0x52,0x62,0x42,0x00},// Z
{0x00,0x00,0x6E,0x4A,0x4A,0x7A,0x00,0x00},// 2
{0x00,0x00,0x6E,0x4A,0x4A,0x7A,0x00,0x00},// 2
};
// Hello World! 字模
u8 code helloWorld[][8] = {
{0x00,0x7E,0x10,0x10,0x10,0x10,0x7E,0x00},// H
{0x00,0x3C,0x52,0x52,0x52,0x34,0x00,0x00},// e
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00},// l
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00},// l
{0x00,0x3C,0x42,0x42,0x42,0x42,0x3C,0x00},// o
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// 空格
{0x7C,0x02,0x04,0x18,0x04,0x02,0x7C,0x00},// W
{0x00,0x3C,0x42,0x42,0x42,0x42,0x3C,0x00},// o
{0x00,0x00,0x3E,0x10,0x20,0x00,0x00,0x00},// r
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00},// l
{0x00,0x00,0x04,0x0A,0x0A,0x7E,0x00,0x00},// d
{0x00,0x00,0x00,0x74,0x00,0x00,0x00,0x00},// !
};
// 列选数据
u8 code gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
// 延时函数(约10us)
void delay_10us(u16 ten_us)
{
while (ten_us–);
}
// 定时器0初始化
void timer0_init()
{
TMOD |= 0x01; // 设置定时器0为模式1(16位定时器)
TH0 = 0xFC; // 定时1ms
TL0 = 0x66;
ET0 = 1; // 使能定时器0中断
EA = 1; // 开启总中断
TR0 = 1; // 启动定时器0
}
// 写入74HC595
void hc595_write_data(u8 dat)
{
u8 i;
for(i = 0; i < 8; i++) {
SER = dat >> 7;
dat <<= 1;
SRCLK = 0;
delay_10us(1);
SRCLK = 1;
delay_10us(1);
}
RCLK = 1;
delay_10us(1);
RCLK = 0;
}
// 按键扫描函数
u8 key_scan(u8 mode)
{
static u8 key=1;
if(mode) key=1;
if(key1&&(KEY10||KEY20||KEY30||KEY40))
{
delay_10us(1000); // 消抖
key=0;
if(KEY10) return KEY1_PRESS;
else if(KEY20) return KEY2_PRESS;
else if(KEY30) return KEY3_PRESS;
else if(KEY40) return KEY4_PRESS;
} else if(KEY11&&KEY21&&KEY31&&KEY4==1)
{
key=1;
}
return KEY_UNPRESS;
}
// 静止显示 - 显示单个字符
void staticDisplay(u8 code *charData)
{
u8 i;
for(i = 0; i < 8; i++)
{
LEDDZ_COL_PORT = gled_col[i];
hc595_write_data(charData[i]);
delay_10us(100);
hc595_write_data(0x00);
}
}
// 幻灯片切换显示
void slideshowMode(u8 code *displayData, u8 numChars)
{
static u8 currentChar = 0;
static u16 count = 0;
u8 i;
// 获取当前字符的指针 u8 code *currentCharData=&displayData[currentChar * 8]; for(i = 0; i < 8; i++) { LEDDZ_COL_PORT = gled_col[i]; hc595_write_data(currentCharData[i]); delay_10us(100); hc595_write_data(0x00); } if(count++ > displaySpeed * 10) { currentChar = (currentChar + 1) % numChars; count = 0; }
}
// 滚动显示
void scrollingMode(u8 code *displayData, u8 numChars)
{
static u16 position = 0;
static u8 buffer[8] = {0};
static u16 count = 0;
u8 i;
if(count++ > displaySpeed/2) { position++; if(position > numChars * 8) position = 0; count = 0; } for(i = 0; i < 8; i++) { u16 totalPos = position + i; u8 charIndex = totalPos/8; u8 pixelPos = totalPos%8; if(charIndex < numChars) { // 计算字符数据在数组中的位置 u8 code *charData=&displayData[charIndex * 8]; buffer[i] = charData[pixelPos]; } else { buffer[i] = 0x00; } } for(i=0; i<8; i++) { LEDDZ_COL_PORT = gled_col[i]; hc595_write_data(buffer[i]); delay_10us(100); hc595_write_data(0x00); }
}
// 定时器0中断服务程序
void timer0_isr() interrupt 1
{
static u16 time_counter = 0;
// 重新加载定时器初值 TH0=0xFC; TL0=0x66; // 更新全局计时器 time_counter++; // 处理速度切换标志 if(speedChanged) { // 根据displaySpeed设置不同的速度 // 实际应用中可能需要调整具体值 speedChanged = 0; }
}
void main()
{
u8 numPersonalInfo = sizeof(personalInfo) / sizeof(personalInfo[0]);
u8 numHelloWorld = sizeof(helloWorld) / sizeof(helloWorld[0]);
u8 currentChar = 0;
u16 charDelay = 0;
// 初始化定时器 timer0_init(); while(1) { u8 key = key_scan(0); // 处理按键事件 if(key == KEY1_PRESS) { displayInfo=!displayInfo; currentChar=0; // 切换显示内容时重置字符索引 } else if(key==KEY2_PRESS) { displayMode = (displayMode+1)%3; } else if(key == KEY3_PRESS) { // 使用定时器控制速度切换 if(displaySpeed == 20) displaySpeed = 50; else if(displaySpeed == 50) displaySpeed = 100; else if(displaySpeed == 100) displaySpeed = 200; else displaySpeed = 20; speedChanged = 1; } else if(key == KEY4_PRESS) { screenOn = !screenOn; } // 显示逻辑 if(screenOn) { if(displayInfo == 0) { switch(displayMode) { case MODE_STATIC: staticDisplay(personalInfo[currentChar]); if(charDelay++ > displaySpeed) { currentChar = (currentChar + 1) % numPersonalInfo; charDelay = 0; } break; case MODE_SLIDESHOW: slideshowMode((u8 code *)personalInfo, numPersonalInfo); break; case MODE_SCROLLING: scrollingMode((u8 code *)personalInfo, numPersonalInfo); break; } } else { switch(displayMode) { case MODE_STATIC: staticDisplay(helloWorld[currentChar]); if(charDelay++ > displaySpeed) { currentChar = (currentChar + 1) % numHelloWorld; charDelay = 0; } break; case MODE_SLIDESHOW: slideshowMode((u8 code *)helloWorld, numHelloWorld); break; case MODE_SCROLLING: scrollingMode((u8 code *)helloWorld, numHelloWorld); break; } } } else { // 屏幕关闭 LEDDZ_COL_PORT = 0xFF; // 关闭所有列 hc595_write_data(0x00); // 关闭所有行 } }
}
解释每一行代码的意思