/*-----------------------------------------------
名称:16x16汉字屏流动显示
修改:无
硬件: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>
sbit J32_LAT = P1^6; //锁存引脚
sbit J32_SER = P1^4; //数据引脚
sbit J32_CLK = P1^5; //时钟引脚
sbit J32_OE = P1^7; //使能引脚
unsigned char MoveBitNum,MoveBitNumtemp,IncNum;//移动位数,临时移动位数,大于一个字节增加字节数
unsigned int HzNum;//汉字个数
unsigned char buff[10];
/*-----------------------------------------------
16x16汉字取模数据
------------------------------------------------*/
unsigned char code hztest[][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,0x21,0x1E,0x11,0x12,0x17,0xD2,0x81,0x12,0x41,0x1E,0x41,0x12,0x17,0xD2,
0x14,0x52,0x24,0x5E,0xE4,0x52,0x27,0xD2,0x24,0x52,0x20,0x22,0x20,0x2A,0x00,0x44,
/*-- 文字: 北 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x04,0x40,0x04,0x40,0x04,0x40,0x04,0x44,0x04,0x48,0x7C,0x50,0x04,0x60,0x04,0x40,
0x04,0x40,0x04,0x40,0x04,0x40,0x04,0x42,0x1C,0x42,0xE4,0x42,0x44,0x3E,0x04,0x00,
/*-- 文字: 汽 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x01,0x00,0x21,0x00,0x11,0xFC,0x12,0x00,0x84,0x00,0x41,0xF8,0x48,0x00,0x08,0x00,
0x13,0xF8,0x10,0x08,0xE0,0x08,0x20,0x08,0x20,0x0A,0x20,0x0A,0x20,0x06,0x00,0x02,
/*-- 文字: 车 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x02,0x00,0x02,0x00,0x02,0x00,0x7F,0xFC,0x04,0x00,0x09,0x00,0x11,0x00,0x21,0x00,
0x3F,0xF8,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,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 --*/
0x04,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x44,0x44,0x24,0x44,0x24,0x48,0x14,0x48,
0x14,0x50,0x14,0x60,0x04,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0xFF,0xFE,0x00,0x00,
/*-- 文字: 学 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x22,0x08,0x11,0x08,0x11,0x10,0x00,0x20,0x7F,0xFE,0x40,0x02,0x80,0x04,0x1F,0xE0,
0x00,0x40,0x01,0x80,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,
/*-- 文字: 院 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x40,0x78,0x20,0x4B,0xFE,0x52,0x02,0x54,0x04,0x61,0xF8,0x50,0x00,0x48,0x00,
0x4B,0xFE,0x48,0x90,0x68,0x90,0x50,0x90,0x41,0x12,0x41,0x12,0x42,0x0E,0x44,0x00,
/*-- 文字: 科 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x08,0x10,0x1D,0x10,0xF0,0x90,0x10,0x90,0x10,0x10,0xFD,0x10,0x10,0x90,0x38,0x90,
0x34,0x10,0x50,0x1E,0x53,0xF0,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
/*-- 文字: 技 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x10,0x20,0x10,0x20,0x10,0x20,0x13,0xFE,0xFC,0x20,0x10,0x20,0x10,0x20,0x15,0xFC,
0x18,0x84,0x30,0x88,0xD0,0x48,0x10,0x50,0x10,0x20,0x10,0x50,0x51,0x88,0x26,0x06,
/*-- 文字: 学 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x22,0x08,0x11,0x08,0x11,0x10,0x00,0x20,0x7F,0xFE,0x40,0x02,0x80,0x04,0x1F,0xE0,
0x00,0x40,0x01,0x80,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00,
/*-- 文字: 院 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x40,0x78,0x20,0x4B,0xFE,0x52,0x02,0x54,0x04,0x61,0xF8,0x50,0x00,0x48,0x00,
0x4B,0xFE,0x48,0x90,0x68,0x90,0x50,0x90,0x41,0x12,0x41,0x12,0x42,0x0E,0x44,0x00,
/*-- 文字: K --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x70,0x00,
0x50,0x00,0x48,0x00,0x48,0x00,0x44,0x00,0x44,0x00,0xEE,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 电 --*/
/*-- 宋体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 --*/
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,
/*-- 文字: 1 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x38,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 5 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x78,0x00,
0x44,0x00,0x02,0x00,0x02,0x00,0x42,0x00,0x44,0x00,0x38,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 1 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x38,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 龚 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x04,0x20,0x04,0x10,0x7F,0xFC,0x09,0x20,0x09,0xC4,0x17,0x04,0x20,0xFC,0xC4,0x40,
0x04,0x40,0x3F,0xF8,0x04,0x40,0x04,0x40,0xFF,0xFE,0x08,0x20,0x10,0x10,0x20,0x08,
/*-- 文字: 俊 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x08,0x40,0x08,0x40,0x08,0x88,0x11,0x04,0x13,0xFE,0x30,0x02,0x30,0x88,0x51,0x44,
0x92,0x42,0x10,0xF8,0x11,0x88,0x12,0x50,0x10,0x20,0x10,0x50,0x11,0x88,0x16,0x06,
/*-- 文字: 宇 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x80,0x04,0x3F,0xF8,0x01,0x00,0x01,0x00,
0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,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,
};
/*-----------------------------------------------
向595写入一个字节 单红色
------------------------------------------------*/
void InputByte( unsigned char DataR1) //写一个字节
{
unsigned char i;
for(i=8; i>0; i--)
{
J32_SER = (DataR1&0x01);
J32_CLK = 0;
J32_CLK = 1;
DataR1 = DataR1 >> 1;
}
}
/*-----------------------------------------------
延时程序
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
/*-----------------------------------------------
主程序
------------------------------------------------*/
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)
{
i++;
if(i==240)//更改流动速度,1T单片机和12T单片机速度大约5-8倍,注意更改参数
{
i=0;
MoveBitNum++;
if(MoveBitNum==16)//每次移动完一个汉字大小后循环
{
MoveBitNum=0;
HzNum+=1; //调用下一个汉字
if(HzNum>=lenHigh-1)//需要显示的汉字个数,包括前面的一屏空字符的个数,后面清屏的空字符不包含在内,这里是(汉字个数+1)
HzNum=0; //完全显示完后循环调用
}
}
Delay(1);//控制扫描频率
//读取汉字对应屏幕缓冲区的数据,不同大小的屏幕不一样
for(j=0; j<2; j++) //取每个汉字的前2个字节,
{
//汉字个数+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;
}
}
|