/*--------16*16点阵屏的移动显示------------*/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned char
#define DATE_OUT P1 //指定P1口做为输出
sbit DATA=DATE_OUT^0; //列数据输出位
sbit SCLH=DATE_OUT^1; //列扫描时钟位
sbit SCLT=DATE_OUT^2; //列数据锁存位
sbit AB =DATE_OUT^3; //行数据输出位
sbit SCK =DATE_OUT^4; //行扫描时钟位
sbit kong=DATE_OUT^5;
unsigned char xxx=0,upcount=0;
unsigned char ccc,time1time=0,s=0;
//段前缀{
//段后缀};
//注释前缀、/*"
//注释后缀",
//数据前缀 0x
//数据后缀,
//行前缀
//行后缀},
//行尾缀*/
code unsigned char dong[16][32]={
{0x00,0x80,0x00,0x80,0xFC,0x80,0x04,0xFC,0x05,0x04,0x49,0x08,0x2A,0x40,0x14,0x40,
0x10,0x40,0x28,0xA0,0x24,0xA0,0x45,0x10,0x81,0x10,0x02,0x08,0x04,0x04,0x08,0x02},/*"欢",0*/
{0x00,0x00,0x20,0x80,0x13,0x3C,0x12,0x24,0x02,0x24,0x02,0x24,0xF2,0x24,0x12,0x24,
0x12,0x24,0x12,0xB4,0x13,0x28,0x12,0x20,0x10,0x20,0x28,0x20,0x47,0xFE,0x00,0x00},/*"迎",1*/
{0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x01,0x00,0x11,0x10,0x09,0x10,0x09,0x20,
0xFF,0xFE,0x03,0x80,0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,0x01,0x00,0x01,0x00},/*"来",2*/
{0x00,0x04,0xFF,0x84,0x08,0x04,0x10,0x24,0x22,0x24,0x41,0x24,0xFF,0xA4,0x08,0xA4,
0x08,0x24,0x08,0x24,0x7F,0x24,0x08,0x24,0x08,0x04,0x0F,0x84,0xF8,0x14,0x40,0x08},/*"到",3*/
{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},/*"电",4*/
{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},/*"子",5*/
{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},/*"工",6*/
{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},/*"程",7*/
{0x00,0xF8,0x3F,0x00,0x04,0x00,0x08,0x20,0x10,0x40,0x3F,0x80,0x01,0x00,0x06,0x10,
0x18,0x08,0x7F,0xFC,0x01,0x04,0x09,0x20,0x11,0x10,0x21,0x08,0x45,0x04,0x02,0x00},/*"系",8*/
{0x00,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00},/*"三",9*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"一",10*/
{0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,
0x04,0x40,0x04,0x20,0x08,0x10,0x08,0x08,0x10,0x08,0x20,0x04,0x40,0x04,0x00,0x00},/*"六",11*/
{0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x88,0x84,0x04,0x80,0x04,0x80,0x10,0x80,
0x08,0x80,0x08,0x80,0xFF,0xFE,0x01,0x40,0x02,0x20,0x04,0x10,0x18,0x08,0x60,0x04},/*"实",12*/
{0x00,0x20,0xF8,0x20,0x08,0x50,0x48,0x50,0x48,0x88,0x49,0x04,0x4A,0xFA,0x7C,0x00,
0x04,0x44,0x04,0x24,0x1D,0x24,0xE4,0xA8,0x44,0x88,0x04,0x10,0x2B,0xFE,0x10,0x00},/*"验",13*/
{0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x80,0x04,0x3F,0xF8,0x04,0x00,0x08,0x20,
0x1F,0xF0,0x01,0x10,0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00},/*"室",14*/
};
idata unsigned char date[3][32];
idata uchar i=0,displayflag=0;
uchar k=0;
void displaymoveup(unsigned char count,unsigned char time);
void display(unsigned char dis);//做为点阵扫描函数,将显示缓存的数据输出到点阵屏
void displaymove(unsigned char count,unsigned char timer);//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,
//非常好用的字摸软件PCtoLCD2002完美版 字模选项:阴码、逐行式、顺向
void main(void) //主入口函数
{
display(0);
while(1)
{
displaymove(16,10);
}
}
void display(unsigned char dis)//显示
{
unsigned char i,ia,j,tmp,x; //定义变量
DATE_OUT=0XFF; //置位高电平做准备
AB=0; //将列数据位清0,准备移位
for(i=0;i<16;i++)
{ //循环输出16行数据
SCK=0; //为列移位做准备
SCLT=0; //为行锁存做准备
for(x=3;x>0;x--)
{
for(ia=2;ia>0;)
{ //每行16个点,循环位移两个字节
ia--; //循环两次
if(dis==1)
{
tmp=~date[x-1][i*2+ia]; //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成, //电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据
}
if(dis==0)
tmp=0xff;
for(j=0;j<8;j++)
{ //循环两次,每次移一个字节,
SCLH=0; //为列移位做准备
DATA=tmp&0x01; //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位
tmp>>=1; //将数据缓冲右移一位,为下次输出做准备
SCLH=1; //将DATA上的数据移入寄存器
} //移入单字节结束
} //移入两个字节结束
}
SCK=1; //SCK拉高,列数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)
SCLT=1; //SCLT拉高,将数据锁存输出到相应行的点阵发光管显示,显示一行后将保持到下一行显示开始
AB=1; //列数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,
//移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱
}
j=20;
while(j--); //每一行的显示,保持16个移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度
SCK=0; //
SCK=1; //将最后一行数据移出
}
void displaymove(unsigned char count,unsigned char timer)//显示汉字内容的移动效果,
//LP指向要显示第一个字的首地址,C表示显示字的个数, //timer是移动的速度
{
unsigned char c=8,i=0,ia=0,num=0;
unsigned char timerc=0;
unsigned char tmp2[16];
for(i=0;i<16;i++)
{
tmp2[i]=dong[xxx/2][i*2+ccc%2]; //取半个汉字点阵数据,16字节
}
xxx++;
if(xxx==(count*2))
xxx=0;
ccc++;
while(c)
{ //循环处理
ia=0; //做为点阵数组的元素
for(i=0;i<16;i++)
{//移动是16行同时移,因此要处理16个字节
// if(date[num][ia]&0x80)
date[num][ia]<<=1; //移当前显示缓冲的前半行字节
if(date[num][ia+1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理
date[num][ia]++;
ia++;
date[num][ia]<<=1; //移当前显示缓冲的前半行字节
if(date[num+1][ia-1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理
date[num][ia]++;
ia--;
date[num+1][ia]<<=1; //移当前显示缓冲的前半行字节
if(date[num+1][ia+1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理
date[num+1][ia]++;
ia++;
date[num+1][ia]<<=1; //移当前显示缓冲的前半行字节
if(date[num+2][ia-1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理
date[num+1][ia]++;
ia--;
date[num+2][ia]<<=1; //移当前显示缓冲的前半行字节
if(date[num+2][ia+1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理
date[num+2][ia]++;
ia++;
date[num+2][ia]<<=1;
if(tmp2[i]&0x80) //判断下一个要显示汉字的前半行字节的高位是否为1,是移入,否则不处理
date[num+2][ia]++;
ia++;
tmp2[i]<<=1; //下一个要显示汉字的半行字节向高位移一位,准备下一次取位
}
timerc=timer; //处理完16行,调用显示函数更新点阵
while(timerc--) //循环做为处理的速度,即移动的速度
display(1);
//----------
c--; //移完一半,进入下一半或下一个汉字,直到结束
}
}
void displaymoveup(unsigned char count,unsigned char time)
{
unsigned char k,i,j,tim=0;
for(i=0;i<3;i++)
{
for(j=0;j<32;j++)
{
date[i][j]=xin[upcount][j];
}
upcount++;
}
if(upcount==count)
upcount=0;
for(k=0;k<16;k++)
{
for(i=0;i<3;i++)
{
for(j=0;j<32;j++)
{
if(j<30)
date[i][j]=date[i][j+2];
if(j>=30)
date[i][j]=0x00;
}
}
tim=time;
while(tim--)
display(1);
}
}
追问程序编译有错误呢? 我是用的4个8*8点阵拼的16*16的点阵,这个程序能行吗?
追答我是用的是4个8*8点阵拼的16*16的点阵,可以的,那程序有点问题,就是那xin我把他删了,你改下就可以了。