如图所示的一个16*16点阵显示左移的示例程序,这里是主函数部分,我知道怎么静态显示一个汉字,但是搞不懂他这个是怎么在左移。求告知!!v4.0资料链接如附件
- /*-----------------------------------------------
- 名称:16x16汉字屏流动显示
- 编写:shifang
- 日期:2009.5
- 修改:bob_write 2021.3
- 硬件:LY-51S V4.0 单片机开发板
- 内容:
- P1.0-P1.3分别连接A、B、C、D,用于控制16行,通过2路HC138控制
- SER接P1.4 通过2片HC595控制
- CLK时钟连接P1.5
- LAT锁存连接P1.6
- OE接P1.7
- 现象:使用普通速度51系列单片机。1个汉字显示屏,向左流动显示多个汉字,重复循环显示。
- ------------------------------------------------*/
- #include<reg52.h>
- #include <intrins.h>
- sbit J32_LAT = P1^6; //锁存引脚
- sbit J32_SER = P1^4; //数据引脚
- sbit J32_CLK = P1^5; //时钟引脚
- sbit J32_OE = P1^7; //使能引脚
- sbit KEY = P0^5; //独立按键
- unsigned char MoveBitNum,MoveBitNumtemp,IncNum;//移动位数,临时移动位数,大于一个字节增加字节数
- unsigned int HzNum;//汉字个数
- unsigned char buff[10];
- /*-----------------------------------------------
- 16x16汉字取模数据
- ------------------------------------------------*/
- unsigned char code hztest[][32]= //取模选择字节正序n行32列的数组,长度是固定的
- {
-
- 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, //前面一屏大小的空字符,不显示,这里根据屏的大小修改,这个是1个汉字屏
- //所以写入1个汉字
- /*-- 文字: 电 --*/
- /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,
- 0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x0A,0x01,0x02,0x01,0x02,0x00,0xFE,
- /*-- 文字: 子 --*/
- /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0x00,0x00,0x7F,0xF8,0x00,0x10,0x00,0x20,0x00,0x40,0x01,0x80,0x01,0x00,0xFF,0xFE,
- 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,
- /*-- 文字: 信 --*/
- /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0x08,0x40,0x08,0x20,0x0B,0xFE,0x10,0x00,0x10,0x00,0x31,0xFC,0x30,0x00,0x50,0x00,
- 0x91,0xFC,0x10,0x00,0x10,0x00,0x11,0xFC,0x11,0x04,0x11,0x04,0x11,0xFC,0x11,0x04,
- /*-- 文字: 息 --*/
- /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0x01,0x00,0x02,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10,
- 0x1F,0xF0,0x10,0x10,0x01,0x00,0x08,0x84,0x48,0x92,0x48,0x12,0x87,0xF0,0x00,0x00,
- /*-- 文字: 工 --*/
- /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0x00,0x00,0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
- 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,
- /*-- 文字: 程 --*/
- /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0x08,0x00,0x1D,0xFC,0xF1,0x04,0x11,0x04,0x11,0x04,0xFD,0xFC,0x10,0x00,0x30,0x00,
- 0x39,0xFE,0x54,0x20,0x54,0x20,0x91,0xFC,0x10,0x20,0x10,0x20,0x13,0xFE,0x10,0x00,
- };
- /*-----------------------------------------------
- 向595写入一个字节 单红色
- ------------------------------------------------*/
- void InputByte( unsigned char DataR1) //写一个字节用串行八位所以8次循环
- {
- unsigned char i;
- for(i=8; i>0; i--)
- {
- J32_SER = (DataR1&0x01);//分离最低位,即0000 0001和data相与取最低位
- J32_CLK = 0;
- J32_CLK = 1;
- DataR1 = DataR1 >> 1;//
- }
- }
- /*-----------------------------------------------
- 延时程序
- ------------------------------------------------*/
- void Delay(unsigned int t)
- {
- while(--t);
- }
- void Delay10ms() //@12.000MHz
- {
- unsigned char i, j;
- i = 117;
- j = 184;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay15ms() //@12.000MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 1;
- j = 176;
- k = 19;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /*-----------------------------------------------
- 主程序
- ------------------------------------------------*/
- main()
- {
- unsigned char count;//16行扫描数据,范围0-15
- unsigned int i, j;
- unsigned char temp;
- //计算数组的元素个数,最终需要的是汉字的个数
- int lenTotal = sizeof(hztest) / sizeof(int); //所有,整个数组的大小
- int lenLow = sizeof(hztest[0]) / sizeof(int); //低位,单个数组的大小
- int lenHigh = lenTotal / lenLow; //高位,相除相当于字的个数
- while(1)
- {
- /*MoveBitNum,移动位数,
- MoveBitNumtemp,临时移动位数,
- IncNum,大于一个字节增加字节数*/
-
- i++;
- if(i==60)//更改流动速度,1T单片机和12T单片机速度大约5-8倍,注意更改参数
- {
- i=0;
- MoveBitNum++;
- if(MoveBitNum==16)//每次移动完一个汉字大小后循环
- {
- MoveBitNum=0;
- HzNum+=1; //调用下一个汉字
- if(HzNum>=lenHigh-1)//需要显示的汉字个数,包括前面的一屏空字符的个数,后面清屏的空字符不包含在内,这里是(汉字个数+1)
- //如果已经是最后一个了,则令汉字个数为0,即hznum指针归零
- HzNum=0; //完全显示完后循环调用
- }
- }
- Delay(1);//控制扫描频率
- //读取汉字对应屏幕缓冲区的数据,不同大小的屏幕不一样
- for(j=0; j<2; j++) //取每个汉字的前2个字节,即32位,2/32
- {
- //汉字个数+1
- buff[j+j+1]=hztest[HzNum+j][count+count+1]; //每次移动完一个汉字后,选择下一个汉字
- buff[j+j]=hztest[HzNum+j][count+count];
- }
- //判断移动的位数
- if(MoveBitNum<8) // 判读移动距离是大于一个字节还是小于一个字节,因为一个字节左移右移最大只能8位
- {
- IncNum=0;
- MoveBitNumtemp=MoveBitNum;
- }
- else
- {
- IncNum=1; //大于8就减去8得到的数值还是小于8
- MoveBitNumtemp=MoveBitNum-8;
- }
- J32_LAT=0; //锁存无效
- for(j=2; j>0; j--) //按bit的方式移动缓冲区的内容,然后输出到595,即取出的数值每个字节左移一定的位数,
- {
- //后面左移出的数据整合到前面的字节中,保持数据的连续性
- temp=(buff[j-1+IncNum]<<MoveBitNumtemp)|(buff[j+IncNum]>>(8-MoveBitNumtemp));//这句比较重要,需要自行拿出2个字节的数据模拟分析
- InputByte(temp);//输出到595
- }//8个字节传输完锁存输出
- //控制使能端
- J32_OE = 1;
- P1=count;//用P0口的前4位控制16行,屏内部通过4-16译码器工作,循环扫描16行
- J32_LAT=1; //锁存有效,此时一行的数据显示到屏上
- J32_OE = 0;
- count++;
- if(count==16)
- count=0;
- }
- }
复制代码
|