51单片机LED滚动屏幕程序代码解析
51单片机LED滚动屏幕程序代码解析
这是一个基于51单片机的LED滚动屏幕程序。以下是代码的详细分析:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define data1 P0
#define data2 P2
sbit s1=P3^6;
sbit s2=P3^7;
bit fangxiang;
uint alt=0,net=0,sl=600;
bit mode;
uchar code tab[] = {
//
0x00,0x88,0x20,0x88,0x20,0x91,0x20,0xA1,0xFF,0xC9,0x2A,0x89,0x2A,0x89,0x2A,0xBF,
0x2A,0x89,0x2A,0x89,0xFF,0xC9,0x20,0xA1,0x20,0x91,0x20,0x88,0x00,0x88,0x00,0x00,/*'?',0*/
0x02,0x00,0x02,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x02,0x42,0x01,0x7F,0xFE,
0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x02,0x00,0x02,0x00,0x00,0x00,/*'?',1*/
0x00,0x08,0x00,0x08,0x1F,0xC8,0x92,0x48,0x52,0x48,0x32,0x48,0x12,0x48,0x1F,0xFF,
0x12,0x48,0x32,0x48,0x52,0x48,0x92,0x48,0x1F,0xC8,0x00,0x08,0x00,0x08,0x00,0x00,/*'?',2*/
0x00,0x00,0x00,0x01,0x00,0x06,0x7F,0xF8,0x04,0x40,0x04,0x40,0x04,0x40,0x04,0x40,
0x04,0x40,0xFC,0x40,0x04,0x7F,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,/*'?',3*/
0x08,0x20,0x08,0xC0,0x0B,0x00,0xFF,0xFF,0x09,0x00,0x08,0xC1,0x00,0x06,0x7F,0xF8,
0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0xFC,0x00,0x02,0x00,0x02,0x00,0x1E,0x00,0x00,/*'?',4*/
0x00,0x00,0x1F,0xFE,0x30,0x84,0xD0,0x84,0x10,0x84,0x10,0x84,0x1F,0xFE,0x02,0x00,
0x0C,0x00,0xF1,0x00,0x10,0xC2,0x10,0x01,0x10,0x02,0x1F,0xFC,0x00,0x00,0x00,0x00,/*'?',5*/
0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00,/*'L',6*/
0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00,/*'E',7*/
0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00,/*'D',8*/
0x00,0x01,0x00,0x02,0x03,0xEC,0x02,0x20,0x02,0x20,0x02,0x28,0xFE,0x26,0x12,0x20,
0x12,0x28,0x12,0x26,0x12,0x20,0x13,0xE0,0x10,0x08,0x10,0x07,0x00,0x00,0x00,0x00,/*'?',9*/
0x00,0x00,0x7F,0xFF,0x40,0x10,0x44,0x08,0x5B,0x10,0x60,0xE0,0x10,0x10,0x13,0x10,
0x1D,0x10,0xF1,0x10,0x17,0xFF,0x11,0x10,0x11,0x10,0x11,0x10,0x10,0x10,0x00,0x00,/*'?',10*/
0x00,0x02,0x00,0x0C,0x7F,0xF0,0x48,0x20,0x49,0x21,0x4D,0x26,0x4B,0xF8,0x49,0x20,
0x49,0x20,0x49,0x20,0x4B,0xFF,0x4D,0x20,0x79,0x20,0x00,0x20,0x00,0x00,0x00,0x00,/*'?',11*/
0x00,0x02,0x00,0x42,0x00,0x22,0x7F,0x1A,0x49,0x02,0x49,0xFE,0x49,0x02,0x49,0x02,
0x49,0x02,0x49,0xFE,0x49,0x02,0x7F,0x0A,0x00,0x12,0x00,0x62,0x00,0x02,0x00,0x00,/*'?',12*/
0x02,0x04,0x02,0x08,0x42,0x10,0x42,0x60,0x42,0x00,0x42,0x02,0x42,0x01,0x43,0xFE,
0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x40,0x42,0x20,0x02,0x10,0x02,0x0C,0x00,0x00,/*'?',13*/
0x00,0x00,0x00,0x42,0x44,0x44,0x4C,0xC8,0x54,0xD0,0x65,0x42,0x45,0x41,0x46,0x7E,
0x84,0x40,0x88,0x40,0x90,0x50,0x81,0x48,0x80,0xC4,0x00,0x62,0x00,0x00,0x00,0x00,/*'?',14*/
0x04,0x44,0x0C,0xE6,0x35,0x44,0xC6,0x48,0x0C,0x48,0x00,0x01,0x11,0x02,0x13,0x0C,
0x15,0xF0,0x99,0x00,0x71,0x00,0x11,0xFC,0x15,0x02,0x13,0x02,0x11,0x8E,0x00,0x00,/*'?',15*/
};
void delay(uint z)
{
uchar x;
for(;z>0;z--)
for(x=30;x>0;x--);
}
void xianshi()
{
uchar aa,i;
for(i=0;i<16;i++)
{
P1=i; //P1为控制列的端口
data1=tab[net+aa]; //将对应的点阵信息输出到data1和data2端口控制的LED点阵上
aa++;
data2=tab[net+aa];
aa++;
delay(5); //延时
data1=0; //清空data1和data2端口
data2=0;
P1=0x00; //清空P1端口
if(aa>30) aa=0; //当aa大于30时,重新开始循环
}
}
void main()
{
ET1=1; //打开定时器1中断
EA=1; //打开总中断
TR1=1; //启动定时器1
while(1)
{
xianshi(); //调用xianshi函数,进行LED点阵的滚动显示
if(s1==0) //判断是否按下s1
{
delay(10); //延时
TR1=~TR1; //改变定时器1的运行状态
while(!s1)xianshi(); //等待s1松开后再次进行LED点阵的滚动显示
delay(10);
}
if(s2==0) //判断是否按下s2
{
delay(10);
fangxiang=~fangxiang; //改变字符滚动的方向
while(!s2)xianshi(); //等待s2松开后再次进行LED点阵的滚动显示
delay(10);
}
}
}
void timer1() interrupt 3
{
alt++; //计数器加1
if(alt==30) //当计数器满30时
{
alt=0; //计数器清零
if(fangxiang==0) //当字符滚动方向为正向时
{
net=net+2; //字符位置加2
if(net>sl) //当字符位置超过末尾位置时,重新回到起始位置
net=0;
}
else //当字符滚动方向为反向时
{
net=net-2; //字符位置减2
if(net<2) //当字符位置小于2时,重新回到末尾位置
net=sl;
}
}
}
代码分析
-
宏定义和全局变量定义:
#define uchar unsigned char: 将uchar定义为unsigned char的别名,用于简化代码。#define uint unsigned int: 将uint定义为unsigned int的别名,用于简化代码。#define data1 P0: 将data1定义为P0端口的别名,用于简化代码。#define data2 P2: 将data2定义为P2端口的别名,用于简化代码。sbit s1=P3^6: 定义s1为P3端口的第 6 位,用于控制按键。sbit s2=P3^7: 定义s2为P3端口的第 7 位,用于控制按键。bit fangxiang: 定义fangxiang为一个位变量,用于控制字符滚动方向。uint alt=0,net=0,sl=600: 定义alt、net和sl为无符号整型变量,分别用于存储定时器计数值、当前显示字符的位置和字符滚动到末尾时的位置。bit mode: 定义mode为一个位变量,用于存储模式信息,但该变量未被使用。uchar code tab[] = {...};: 定义tab为一个只读常量数组,存储了显示字符的点阵信息。
-
delay 函数:
void delay(uint z) { ... }: 该函数是一个延时函数,用于实现程序的延时功能。
-
xianshi 函数:
void xianshi() { ... }: 该函数用于实现 LED 点阵的滚动显示。它通过循环遍历 16 列 LED 点阵,并根据net和tab数组中的数据,控制data1和data2端口输出对应的点阵信息,从而实现滚动效果。
-
主函数:
void main() { ... }: 该函数为主函数,负责程序的初始化和执行。- 初始化部分:
ET1=1;: 打开定时器 1 中断。EA=1;: 打开总中断。TR1=1;: 启动定时器 1。
- 循环部分:
xianshi();: 调用xianshi函数,进行 LED 点阵的滚动显示。if(s1==0) { ... }: 判断是否按下s1按键,若按下,则改变定时器 1 的运行状态,并等待s1松开后继续滚动显示。if(s2==0) { ... }: 判断是否按下s2按键,若按下,则改变字符滚动的方向,并等待s2松开后继续滚动显示。
-
timer1 中断函数:
void timer1() interrupt 3 { ... }: 该函数为定时器 1 中断函数,每当定时器 1 超时时,该函数就会被调用。alt++;: 计数器alt加 1。if(alt==30) { ... }: 当计数器alt满 30 时,更新字符显示的位置。net=net+2;: 当字符滚动方向为正向时,字符位置加 2。net=net-2;: 当字符滚动方向为反向时,字符位置减 2。- 当字符位置超过末尾位置或小于 2 时,重新回到起始位置或末尾位置。
代码功能
该程序实现了 51 单片机控制 LED 点阵的滚动显示功能。用户可以通过按键 s1 控制定时器 1 的运行状态,从而实现暂停或恢复滚动显示;可以通过按键 s2 改变字符滚动的方向。程序使用定时器 1 中断来控制字符的滚动速度。
总结
该程序通过使用 51 单片机的定时器中断和端口控制,实现了 LED 点阵的滚动显示功能,并支持暂停、恢复和方向控制。代码结构清晰,易于理解和修改。
原文地址: https://www.cveoy.top/t/topic/oe0F 著作权归作者所有。请勿转载和采集!