找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2105|回复: 0
打印 上一主题 下一主题
收起左侧

德飞莱ly-51s单片机程序求解读

[复制链接]
跳转到指定楼层
楼主
ID:562262 发表于 2021-3-19 22:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如图所示的一个16*16点阵显示左移的示例程序,这里是主函数部分,我知道怎么静态显示一个汉字,但是搞不懂他这个是怎么在左移。求告知!!v4.0资料链接如附件
  1. /*-----------------------------------------------
  2.   名称:16x16汉字屏流动显示
  3.   编写:shifang
  4.   日期:2009.5
  5.   修改:bob_write 2021.3
  6.   硬件:LY-51S V4.0 单片机开发板
  7.   内容:
  8.         P1.0-P1.3分别连接A、B、C、D,用于控制16行,通过2路HC138控制
  9.                                 SER接P1.4 通过2片HC595控制
  10.                                 CLK时钟连接P1.5
  11.                                 LAT锁存连接P1.6
  12.                                 OE接P1.7

  13.   现象:使用普通速度51系列单片机。1个汉字显示屏,向左流动显示多个汉字,重复循环显示。
  14. ------------------------------------------------*/
  15. #include<reg52.h>
  16. #include <intrins.h>

  17. sbit J32_LAT = P1^6;                //锁存引脚
  18. sbit J32_SER = P1^4;                //数据引脚
  19. sbit J32_CLK = P1^5;          //时钟引脚
  20. sbit J32_OE  = P1^7;          //使能引脚
  21. sbit KEY = P0^5;                                                  //独立按键

  22. unsigned char MoveBitNum,MoveBitNumtemp,IncNum;//移动位数,临时移动位数,大于一个字节增加字节数
  23. unsigned int HzNum;//汉字个数
  24. unsigned char buff[10];

  25. /*-----------------------------------------------
  26.              16x16汉字取模数据
  27. ------------------------------------------------*/
  28. unsigned char code hztest[][32]=    //取模选择字节正序n行32列的数组,长度是固定的
  29. {
  30.         
  31.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  32.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //前面一屏大小的空字符,不显示,这里根据屏的大小修改,这个是1个汉字屏
  33.         //所以写入1个汉字

  34. /*--  文字:  电  --*/
  35. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  36. 0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,
  37. 0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x0A,0x01,0x02,0x01,0x02,0x00,0xFE,

  38. /*--  文字:  子  --*/
  39. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  40. 0x00,0x00,0x7F,0xF8,0x00,0x10,0x00,0x20,0x00,0x40,0x01,0x80,0x01,0x00,0xFF,0xFE,
  41. 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,

  42. /*--  文字:  信  --*/
  43. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  44. 0x08,0x40,0x08,0x20,0x0B,0xFE,0x10,0x00,0x10,0x00,0x31,0xFC,0x30,0x00,0x50,0x00,
  45. 0x91,0xFC,0x10,0x00,0x10,0x00,0x11,0xFC,0x11,0x04,0x11,0x04,0x11,0xFC,0x11,0x04,

  46. /*--  文字:  息  --*/
  47. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  48. 0x01,0x00,0x02,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,
  49. 0x1F,0xF0,0x10,0x10,0x01,0x00,0x08,0x84,0x48,0x92,0x48,0x12,0x87,0xF0,0x00,0x00,

  50. /*--  文字:  工  --*/
  51. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  52. 0x00,0x00,0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
  53. 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,

  54. /*--  文字:  程  --*/
  55. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  56. 0x08,0x00,0x1D,0xFC,0xF1,0x04,0x11,0x04,0x11,0x04,0xFD,0xFC,0x10,0x00,0x30,0x00,
  57. 0x39,0xFE,0x54,0x20,0x54,0x20,0x91,0xFC,0x10,0x20,0x10,0x20,0x13,0xFE,0x10,0x00,

  58. };



  59. /*-----------------------------------------------
  60.              向595写入一个字节 单红色
  61. ------------------------------------------------*/
  62. void InputByte( unsigned  char DataR1) //写一个字节用串行八位所以8次循环
  63. {
  64.         unsigned  char i;
  65.         for(i=8; i>0; i--)
  66.         {
  67.                 J32_SER = (DataR1&0x01);//分离最低位,即0000 0001和data相与取最低位
  68.                 J32_CLK = 0;
  69.                 J32_CLK = 1;
  70.                 DataR1 = DataR1 >> 1;//
  71.         }
  72. }


  73. /*-----------------------------------------------
  74.                     延时程序
  75. ------------------------------------------------*/
  76. void Delay(unsigned int t)
  77. {
  78.         while(--t);
  79. }

  80. void Delay10ms()                //@12.000MHz
  81. {
  82.         unsigned char i, j;

  83.         i = 117;
  84.         j = 184;
  85.         do
  86.         {
  87.                 while (--j);
  88.         } while (--i);
  89. }

  90. void Delay15ms()                //@12.000MHz
  91. {
  92.         unsigned char i, j, k;

  93.         _nop_();
  94.         _nop_();
  95.         i = 1;
  96.         j = 176;
  97.         k = 19;
  98.         do
  99.         {
  100.                 do
  101.                 {
  102.                         while (--k);
  103.                 } while (--j);
  104.         } while (--i);
  105. }





  106. /*-----------------------------------------------
  107.                       主程序
  108. ------------------------------------------------*/
  109. main()
  110. {
  111.         unsigned char count;//16行扫描数据,范围0-15
  112.         unsigned int i, j;
  113.         unsigned char temp;
  114.         //计算数组的元素个数,最终需要的是汉字的个数
  115.         int lenTotal = sizeof(hztest) / sizeof(int);  //所有,整个数组的大小
  116.         int lenLow = sizeof(hztest[0]) / sizeof(int);  //低位,单个数组的大小
  117.         int lenHigh = lenTotal / lenLow;  //高位,相除相当于字的个数


  118. while(1)
  119.         {
  120.                 /*MoveBitNum,移动位数,
  121.                 MoveBitNumtemp,临时移动位数,
  122.                 IncNum,大于一个字节增加字节数*/
  123.                
  124.                 i++;
  125.                 if(i==60)//更改流动速度,1T单片机和12T单片机速度大约5-8倍,注意更改参数
  126.                 {
  127.                         i=0;
  128.                         MoveBitNum++;
  129.                         if(MoveBitNum==16)//每次移动完一个汉字大小后循环
  130.                         {
  131.                                 MoveBitNum=0;
  132.                                 HzNum+=1;    //调用下一个汉字
  133.                                 if(HzNum>=lenHigh-1)//需要显示的汉字个数,包括前面的一屏空字符的个数,后面清屏的空字符不包含在内,这里是(汉字个数+1)
  134.                                                                                                                 //如果已经是最后一个了,则令汉字个数为0,即hznum指针归零
  135.                                         HzNum=0;   //完全显示完后循环调用
  136.                         }
  137.                 }

  138.                 Delay(1);//控制扫描频率
  139.                 //读取汉字对应屏幕缓冲区的数据,不同大小的屏幕不一样
  140.                 for(j=0; j<2; j++) //取每个汉字的前2个字节,即32位,2/32
  141.                 {
  142.                         //汉字个数+1
  143.                         buff[j+j+1]=hztest[HzNum+j][count+count+1];  //每次移动完一个汉字后,选择下一个汉字
  144.                         buff[j+j]=hztest[HzNum+j][count+count];

  145.                 }
  146.                 //判断移动的位数
  147.                 if(MoveBitNum<8)                   //  判读移动距离是大于一个字节还是小于一个字节,因为一个字节左移右移最大只能8位
  148.                 {
  149.                         IncNum=0;
  150.                         MoveBitNumtemp=MoveBitNum;
  151.                 }
  152.                 else
  153.                 {
  154.                         IncNum=1;    //大于8就减去8得到的数值还是小于8
  155.                         MoveBitNumtemp=MoveBitNum-8;
  156.                 }

  157.                 J32_LAT=0;       //锁存无效

  158.                 for(j=2; j>0; j--)        //按bit的方式移动缓冲区的内容,然后输出到595,即取出的数值每个字节左移一定的位数,
  159.                 {
  160.                         //后面左移出的数据整合到前面的字节中,保持数据的连续性
  161.                         temp=(buff[j-1+IncNum]<<MoveBitNumtemp)|(buff[j+IncNum]>>(8-MoveBitNumtemp));//这句比较重要,需要自行拿出2个字节的数据模拟分析
  162.                         InputByte(temp);//输出到595
  163.                 }//8个字节传输完锁存输出
  164.                 //控制使能端
  165.                 J32_OE  = 1;
  166.                 P1=count;//用P0口的前4位控制16行,屏内部通过4-16译码器工作,循环扫描16行
  167.                 J32_LAT=1;      //锁存有效,此时一行的数据显示到屏上
  168.                 J32_OE = 0;


  169.                 count++;
  170.                 if(count==16)
  171.                         count=0;


  172.         }
  173. }
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表