标题:
德飞莱ly-51s单片机程序求解读
[打印本页]
作者:
2550684804
时间:
2021-3-19 22:20
标题:
德飞莱ly-51s单片机程序求解读
如图所示的一个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;
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1