基于51单片机的LED点阵设计

1.设计任务

利用AT89C51单片机为核心控制元件,设计一个LED点阵显示屏,设计的系统实用性强、操作简单,实现了智能化、数字化。

(1)本设计的理论基础是单片机原理与应用,模电和数电。比如AT89C51芯片的一些工作原理是在MCS—51的基础上通过改进完成的。

(2)本设计完成了16*16LED点阵动态显示两个以上汉字,并可以利用按键控制其移动、切换。

2. 设计要求

2.1系统方案论证

根据设计任务,分析设计系统的组成,给出实现设计任务的几种方案,分析比较几种设计方案的优略,本着尽量以软件代替硬件,同时力求电路简单,工作可靠的原则,确定总体设计方案。

2.2系统硬件电路设计

根据系统设计方案进行软、硬件的分配,软、硬件设计分别进行。硬件设计包括单片机最小系统和扩展接口及配置,硬件结构在设计时要选择合适的元器件,硬件电路要简洁、工作可靠,需用Proteus绘制整个系统的电路仿真原理图。

2.3软件设计

根据该系统要求的功能进行软件设计,简述软件的功能,并根据每个模块的功能绘制软件流程图,根据流程图编写程序并汇编调试通过;列出软件清单,软件清单要求加以注释。



uchar code table1[][32*10]={   //阴码  逐行  逆向
{
		
0x08,0x00,0x08,0x3F,0x08,0x20,0x08,0x10,0x3F,0x08,0x24,0x04,0x24,0x04,0xA4,0x7F,
0x24,0x04,0x12,0x04,0x14,0x04,0x08,0x04,0x14,0x04,0x22,0x04,0x21,0x05,0x00,0x02,/*"好",0*/

0x08,0x00,0x08,0x3F,0x08,0x20,0x08,0x10,0x3F,0x08,0x24,0x04,0x24,0x04,0xA4,0x7F,
0x24,0x04,0x12,0x04,0x14,0x04,0x08,0x04,0x14,0x04,0x22,0x04,0x21,0x05,0x00,0x02,/*"好",1*/

0x44,0x10,0x88,0x10,0x88,0x08,0x00,0x04,0xFE,0x7F,0x02,0x40,0x01,0x20,0xF8,0x07,
0x00,0x02,0x80,0x01,0xFF,0x7F,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x00,0x40,0x00,/*"学",2*/

0x00,0x00,0xFE,0x1F,0x00,0x10,0x00,0x10,0x10,0x10,0x20,0x10,0x40,0x10,0x40,0x10,
0x00,0x16,0x80,0x11,0x70,0x10,0x0E,0x10,0x04,0x10,0x00,0x10,0x00,0x0A,0x00,0x04,/*"习",3*/

0x00,0x00,0xFC,0x1F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x80,0x00,
0x40,0x01,0x40,0x01,0x20,0x02,0x20,0x02,0x10,0x04,0x08,0x08,0x04,0x10,0x03,0x60,/*"天",4*/

0x00,0x00,0xFC,0x1F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x80,0x00,
0x40,0x01,0x40,0x01,0x20,0x02,0x20,0x02,0x10,0x04,0x08,0x08,0x04,0x10,0x03,0x60,/*"天",5*/

0x40,0x00,0x20,0x00,0x10,0x00,0xFE,0x3F,0x02,0x20,0x02,0x20,0xE2,0x23,0x22,0x22,
0x22,0x22,0x22,0x22,0x22,0x22,0xE2,0x23,0x22,0x22,0x02,0x20,0x02,0x28,0x02,0x10,/*"向",6*/

0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xC0,0x1F,0x40,0x00,
0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xFF,0x7F,0x00,0x00,/*"上",7*/

	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //尾部的一屏的空字符,用于清屏,参数和屏大小有关。
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
},

{
	0x00,0x00,0x08,0x1C,0x0E,0x22,0x08,0x20,
	0x08,0x10,0x08,0x08,0x08,0x04,0x3E,0x3E,
	0x00,0x00,0x1C,0x18,0x22,0x14,0x20,0x14,
	0x18,0x12,0x20,0x3E,0x22,0x10,0x1C,0x10,/*"1234",0*/
	
	0x00,0x00,0x3E,0x1C,0x02,0x02,0x02,0x02,
	0x1C,0x1E,0x20,0x22,0x20,0x22,0x1E,0x1C,
	0x00,0x00,0x3E,0x1C,0x20,0x22,0x10,0x22,
	0x10,0x3E,0x08,0x22,0x04,0x22,0x04,0x1C,/*"5678",0*/
	
 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,
	0x38,0x07,0xFC,0x0F,0xFC,0x0F,0xFC,0x0F,
 0xFC,0x0F,0xF8,0x07,0xF8,0x07,0xF0,0x03,
	0xE0,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,/*"爱心",0*/
	
	0x00,0x00,0x22,0x1C,0x22,0x08,0x22,0x08,
	0x3E,0x08,0x22,0x08,0x22,0x08,0x22,0x1C,
	0x00,0x00,0x3C,0x22,0x10,0x12,0x10,0x0A,
	0x10,0x06,0x10,0x0A,0x12,0x12,0x0C,0x22,/*"hijlk",0*/
	
 0x00,0x00,0xFC,0x1F,0x02,0x10,0x02,0x10,
	0x02,0x10,0x32,0x33,0x32,0x23,0x02,0x20,
 0x02,0x20,0x12,0x22,0xB2,0x23,0xF2,0x23,
 0x02,0x10,0x02,0x10,0xFE,0x1F,0x00,0x00,/*"笑脸",0*/

	0x22,0x7C,0x12,0x10,0x0A,0x10,0x06,0x10,
	0x06,0x10,0x0A,0x10,0x12,0x10,0x22,0x1E,
	0x00,0x00,0x82,0x7E,0x44,0x20,0x28,0x10,
	0x10,0x08,0x28,0x04,0x44,0x02,0x82,0x7E,/*"KJXZ",0*/
	
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //尾部的一屏的空字符,用于清屏,参数和屏大小有关。
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
}
};	

uchar show_temp[32];    //用于显示的缓存

uchar zuoyou_temp[16];   //用于左右移动的显示之外的缓存

char code Hang[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};  //用于行码  ,选择行用的 595

void delay(int z)				//延时程序
{
	int x,y;
	for(x=55;x>0;x--)
		for(y=z;y>0;y--);
}

void wordByt(char b)			//写(拆分)一个字节数据  传给595芯片
{
	char i;
	for(i=0;i<8;i++)
	{
		b=b>>1;			//右移一位,暂存近CY
		R=CY;		    //取出最低位
		CLK=0;			//上升沿	
		CLK=1;
	}
}

int i=0;
void main()
{
  int num, speed;         //num用于显示   speed用于显示的速度的
  uint temp;              //缓存 一字节数据  
  uchar hanzi_witch = 1;  //显示汉字那组数据   还是显示ASCII那组数据

  hanzi_num = 8;        /*当前组数据 汉字的个数 更改第2处*/

  key_u = 1;       //按键高电平
  key_d = 1;
  key_r = 1;
  key_l = 1;
  key_m = 1;
  key_change = 1;
  order = 'm';    //开机默认逐字切换功能
  move = 0;      //移动变量为0  从头开始
  while (1)
  {

    if (key_u == 0) /*向上移动的按键   让模式为 ‘u’  ,从头开始*/
	{    
      order = 'u';
      move = 0;
    }
    if (key_d == 0) /*向下移动的按键按下  从头开始*/
	{   
      order = 'd';
      move = 0;
      for (i = 0; i < 16; i++)  //初始化要显示的缓存数组(复制过来)
	  {  
        show_temp[i * 2] = table1[hanzi_table_num - 1][i * 2];
        show_temp[i * 2 + 1] = table1[hanzi_table_num - 1][i * 2 + 1];
      }
    }
    if (key_r == 0)  /*向右移动的按键按下  从头开始*/
	{  
      order = 'r';
      move = 0;
      for (i = 0; i < 16; i++)  //初始化要显示的缓存数组(复制过来) 
	  {   
        show_temp[i * 2] = table1[hanzi_table_num - 1][i * 2];
        show_temp[i * 2 + 1] = table1[hanzi_table_num - 1][i * 2 + 1];
        zuoyou_temp[i] = table1[hanzi_table_num - 1][i * 2 + 32 + 1];   //以及关系到下一个汉字的后一半内容,也缓存过来   用于衔接上一个文字
      }
    }
    if (key_l == 0) /*向左移动的按键按下  从头开始*/
	{ 
      order = 'l';
      move = 0;
      for (i = 0; i < 16; i++)  //初始化要显示的缓存数组(复制过来)
	  {  
        show_temp[i * 2] = table1[hanzi_table_num - 1][i * 2];
        show_temp[i * 2 + 1] = table1[hanzi_table_num - 1][i * 2 + 1];
        zuoyou_temp[i] = table1[hanzi_table_num - 1][i * 2 + 32];    //以及关系到下一个汉字的前一半内容,也缓存过来   用于衔接上一个文字
      }
    }
    if (key_m == 0) /*逐个字切换的按键按下  从头开始*/
	{  
      order = 'm';
      move = 0;
    }
	
/*--------------------------------------------------------------------------------------------*/	
    if (key_change == 0) /*显示内容数组变化  按键按下   切换内容序号*/
	{   
      move = 0;
      hanzi_witch++;
      if (hanzi_witch >= 3) hanzi_witch = 1;

      if (hanzi_witch == 1)    //1  是汉字数组   汉字3个   索引为1
	  {  
        hanzi_num = 8;        /*汉字更改第3处*/
        hanzi_table_num = 1;
      }
      if (hanzi_witch == 2)    //2  是字符数组  页面4个   索引为2
	  { 
        hanzi_num = 6;        /*特定数字更改第1处*/
        hanzi_table_num = 2;
      }
      order = 'm';                 //默认为 逐页变化的   
      while (key_change == 0);    //等待按键松开

    }
/*-------------------------------------------------------------------------------------------*/

    for (num = 0; num < 16; num++) //显示处理  16*16图像    逐行显示  ,共显示16行
    {
      if (num < 8) 				//前8行
	  {          	
        wordByt(Hang[num]);	
        wordByt(0xff);
      }
      else 						//后8行
	  {         			
        wordByt(0xff);
        wordByt(Hang[num - 8]);
      }
      if ((order == 'u') || (order == 'm'))  //向上移动  和 逐字变化   时,直接计算从原始数据获取显示
	  {   
        wordByt(table1[hanzi_table_num - 1][2 * num + move * 2]);
        wordByt(table1[hanzi_table_num - 1][2 * num + 1 + move * 2]);
      }
      if ((order == 'd') || (order == 'l') || (order == 'r')) //向下 向左 右 模式,显示处理后的缓存数组内容
	  {  
        wordByt(show_temp[2 * num]);
        wordByt(show_temp[2 * num + 1]);
      }
      STB = 1;  //输出锁存中的数据,下降沿    显示一行
      STB = 0;
      delay(2);   //  延时一下
    }


    if (order == 'l')  /*向左移动*/
	{     
      if (++speed > 6) //速度控制(数字小速度快)
      {
        speed = 0;
        move++;   //移位  移动1列

        for (i = 0; i < 16; i++)  //数据处理
		{  
          if (show_temp[i * 2 + 1] & 0x01 == 0x01)  show_temp[i * 2] = ((show_temp[i * 2]) >> 1) | 0x80; //先向左移动一列    数组内容
          else show_temp[i * 2] = ((show_temp[i * 2]) >> 1) & 0x7f;
          if (zuoyou_temp[i] & 0x01 == 0x01)  show_temp[i * 2 + 1] = ((show_temp[i * 2 + 1]) >> 1) | 0x80;  //判断下一图像的一列,根据0或1插入上面移动1列后的数组里
          else show_temp[i * 2 + 1] = ((show_temp[i * 2 + 1]) >> 1) & 0x7f;
          zuoyou_temp[i] = zuoyou_temp[i] >> 1;    //下一图像跟着移动1列
        }
        if (move % 8 == 0) //移动当前图像的8步之内   更新下一个图像的前一半内容到缓存数组里 
		{   
          if (move / 8 % 2 == 0) //上一边
          for (i = 0; i < 16; i++) 
		  {
             zuoyou_temp[i] = table1[hanzi_table_num - 1][(move / 16 + 1) * 32 + i * 2];
          }

          if (move / 8 % 2 == 1) //下一边   //移动当前图像的8-15步   更新下一个图像的后一半内容到缓存数组里 
          for (i = 0; i < 16; i++) 
		  {
             zuoyou_temp[i] = table1[hanzi_table_num - 1][(move / 16 + 1) * 32 + i * 2 + 1];
          }
        }

        if (move > 16 * hanzi_num) //判断是否完成一个数组数据
		{ 
          move = 0;                //从头开始
          for (i = 0; i < 16; i++) //复制数据到缓存数组中
		  {    
            show_temp[i * 2] = table1[hanzi_table_num - 1][i * 2];
            show_temp[i * 2 + 1] = table1[hanzi_table_num - 1][i * 2 + 1];
            zuoyou_temp[i] = table1[hanzi_table_num - 1][i * 2 + 32];    //以及关系到下一个汉字的前一半内容,也缓存过来   用于衔接上一个文字
          }
        }
      }
    }
    if (order == 'r') /*向右移动*/
	{      
      if (++speed > 6) //速度控制(数字小速度快)
      {
        speed = 0;
        move++;   //移位

        for (i = 0; i < 16; i++) //先向右移动一个   显示数据的处理
	    { 
          temp = show_temp[i * 2] >> 7; //   移动根据后一半图像的1列数据,转换添加到右移1列后的前一半图像
          if (temp & 0x01 == 0x01)  show_temp[i * 2 + 1] = ((show_temp[i * 2 + 1]) << 1) | 0x01;
          else show_temp[i * 2 + 1] = ((show_temp[i * 2 + 1]) << 1) & 0xfe;

          temp = zuoyou_temp[i] >> 7;   //根据下1个图像的前半部分的1列数据,判断添加到上1个图像的1列中
          if (temp & 0x01 == 0x01)  show_temp[i * 2] = ((show_temp[i * 2]) << 1) | 0x01;
          else show_temp[i * 2] = ((show_temp[i * 2]) << 1) & 0xfe;
          zuoyou_temp[i] = zuoyou_temp[i] << 1;  //缓存也移动1列
        }

        if (move % 8 == 0) 
		{    
          if (move / 8 % 2 == 0) //上一边//移动当前图像的8步之内   更新下一个图像的上一半内容到缓存数组里 
          for (i = 0; i < 16; i++) 
		  {
             zuoyou_temp[i] = table1[hanzi_table_num - 1][(move / 16 + 1) * 32 + i * 2 + 1];
          }
          if (move / 8 % 2 == 1) //下一边//移动当前图像的8步之内   更新下一个图像的下一半内容到缓存数组里 
          for (i = 0; i < 16; i++) 
		  {
             zuoyou_temp[i] = table1[hanzi_table_num - 1][(move / 16 + 1) * 32 + i * 2];
          }
        }

        if (move > 16 * hanzi_num) //判断是否完成一个汉字
		{ 
          move = 0;          		//从头开始
          for (i = 0; i < 16; i++)  //复制数据  从新开始
		  {  
            show_temp[i * 2] = table1[hanzi_table_num - 1][i * 2];
            show_temp[i * 2 + 1] = table1[hanzi_table_num - 1][i * 2 + 1];
						zuoyou_temp[i] = table1[hanzi_table_num - 1][i * 2 + 32 + 1];   //以及关系到下一个汉字的后一半内容,也缓存过来   用于衔接上一个文字
          }
        }
      }
    }


    if (order == 'd')  /*向下移动*/
	{     
      if (++speed > 5) //速度控制(数字小速度快)
      {
        speed = 0;
        move++;   //移位

        for (i = 14; i >= 0; i--)  //缓存数据先向下移动一个
		{      
          show_temp[(i + 1) * 2] = show_temp[i * 2];
          show_temp[(i + 1) * 2 + 1] = show_temp[i * 2 + 1];
        }
				       
		//第一行数据由下一个图像的最后一行数据填充
        show_temp[0] = table1[hanzi_table_num - 1][(move / 16 + 2) * 32 - (move * 2) % 32];
        show_temp[1] = table1[hanzi_table_num - 1][(move / 16 + 2) * 32 + 1 - (move * 2) % 32];

        if (move > 16 * hanzi_num) //判断是否完成一个汉字
		{ 
          move = 0;            		//从头开始
          for (i = 0; i < 16; i++)  //复制数据,重新开始
		  {  
            show_temp[i * 2] = table1[hanzi_table_num - 1][i * 2];
            show_temp[i * 2 + 1] = table1[hanzi_table_num - 1][i * 2 + 1];
          }

        }
      }
    }

    if (order == 'u')  /*向上移动    它的数组数据顺序符合向上的,所以数据不必处理*/
	{     
      if (++speed > 5) //速度控制(数字小速度快)
      {
        speed = 0;
        move++;   //移位
        if (move > 16 * hanzi_num) //判断是否完成一个汉字
          move = 0; //从头开始
      }
    }
    if (order == 'm')  /*逐个字显示*/
	{       
      if (++speed > 25) //速度控制(数字小速度快)
      {
        speed = 0;
        move += 16; //移位   下一个图像
    
    }
  }
}

完整代码点开链接私信  免费  获取。

【iBot机器人工作室的个人空间-哔哩哔哩】 https://b23.tv/ryUWVKa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K11mvp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值