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; 
     }
   }
}

代码分析

  1. 宏定义和全局变量定义:

    • #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: 定义 s1P3 端口的第 6 位,用于控制按键。
    • sbit s2=P3^7: 定义 s2P3 端口的第 7 位,用于控制按键。
    • bit fangxiang: 定义 fangxiang 为一个位变量,用于控制字符滚动方向。
    • uint alt=0,net=0,sl=600: 定义 altnetsl 为无符号整型变量,分别用于存储定时器计数值、当前显示字符的位置和字符滚动到末尾时的位置。
    • bit mode: 定义 mode 为一个位变量,用于存储模式信息,但该变量未被使用。
    • uchar code tab[] = {...};: 定义 tab 为一个只读常量数组,存储了显示字符的点阵信息。
  2. delay 函数:

    • void delay(uint z) { ... }: 该函数是一个延时函数,用于实现程序的延时功能。
  3. xianshi 函数:

    • void xianshi() { ... }: 该函数用于实现 LED 点阵的滚动显示。它通过循环遍历 16 列 LED 点阵,并根据 nettab 数组中的数据,控制 data1data2 端口输出对应的点阵信息,从而实现滚动效果。
  4. 主函数:

    • void main() { ... }: 该函数为主函数,负责程序的初始化和执行。
    • 初始化部分:
      • ET1=1;: 打开定时器 1 中断。
      • EA=1;: 打开总中断。
      • TR1=1;: 启动定时器 1。
    • 循环部分:
      • xianshi();: 调用 xianshi 函数,进行 LED 点阵的滚动显示。
      • if(s1==0) { ... }: 判断是否按下 s1 按键,若按下,则改变定时器 1 的运行状态,并等待 s1 松开后继续滚动显示。
      • if(s2==0) { ... }: 判断是否按下 s2 按键,若按下,则改变字符滚动的方向,并等待 s2 松开后继续滚动显示。
  5. 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 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录