51单片机用汇编语言驱动16*16点阵滚动显示“RACE AS LIGHTNING”

硬件说是通过LS595来驱动的,四个IO口连在单片机上,很头疼怎么设计,在线等!

很简单/*16*16点阵屏的显示*/

#include <reg51.h>
#include <intrins.h>

#define DATAOUT P2 //指定P2口做为输出
sbit DATA=DATAOUT^0; //列数据输出位
sbit SCLH=DATAOUT^1; //列扫描时钟位
sbit SCLT=DATAOUT^2; //列数据锁存位
sbit AB=DATAOUT^4; //行数据输出位
sbit SCK=DATAOUT^5; //行扫描时钟位

unsigned char lhj[32];//32字节RAM做为16*16点阵屏显示缓存
void display();//做为点阵扫描函数,将显示缓存的数据输出到点阵屏
void displayS(unsigned int timer);//指定时间扫描显示
void displaymove(unsigned char *lp,unsigned char c,unsigned char timer);//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,
//timer是移动的速度
void displaymovetb(unsigned char din,unsigned char *lp,unsigned char timer);
//上下移动内容,din:1为向下,0为向上,lp指向要移入的内容,timer为移动速度
void delay(unsigned int a);//延时子函数

code unsigned char lin[32]={0x04,0x20,0x04,0x20,0xff,0xfe,0x04,0x20,//汉字"英"的点阵数据。汉字点阵数据,可用汉字库点阵生成软件获得
0x01,0x00,0x1f,0xf0,0x11,0x10,0x11,0x10,
0x11,0x10,0xff,0xfe,0x01,0x00,0x02,0x80,
0x04,0x40,0x08,0x30,0x10,0x1c,0x20,0x08};
code unsigned char yang[32]={//达
0x00,0x00,0x40,0x80,0x30,0x80,0x10,0x80,
0x0f,0xfc,0x00,0x80,0x00,0x80,0xe0,0x80,
0x21,0x40,0x21,0x20,0x22,0x18,0x24,0x0c,
0x28,0x08,0x50,0x02,0x8f,0xfc,0x00,0x00};
code unsigned char dian[32]={//通
0x40,0x00,0x27,0xf8,0x20,0x90,0x00,0x60,
0x07,0xf8,0x04,0x48,0xe7,0xf8,0x24,0x48,
0x24,0x48,0x27,0xf8,0x24,0x48,0x24,0x68,
0x24,0x50,0x50,0x00,0x8f,0xfe,0x00,0x00};
code unsigned char zi[32]={//讯
0x40,0x00,0x27,0xf8,0x31,0x08,0x21,0x08,
0x01,0x08,0xf1,0x08,0x17,0xe8,0x11,0x08,
0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x0a,
0x15,0x0a,0x19,0x0a,0x11,0x04,0x00,0x00};

code unsigned char LY[32]={//图案数据
0x00,0x00,0x30,0x00,0x30,0x20,0x30,0x30,
0x30,0x18,0x30,0x0C,0x30,0x06,0x3F,0x7F,
0x3F,0x7F,0x00,0x06,0x00,0x0C,0x00,0x18,
0x00,0x30,0x00,0x20,0x00,0x00,0x00,0x00};

void main(void) //主入口函数
{
unsigned char i=0,j=0;

for(i=0;i<32;i++)
lhj[i]=LY[i];//将图案数据复制到显示缓存
while(1){
displayS(2); //显示图案约2秒
displaymove(lin,4,7);//将从"英"开始的四个汉字从右向左移动
displayS(1); //等持约1秒
displaymovetb(1,0,10); //将点阵上显示的内容向下以10的速度移出,补上0,即清空显示屏
displayS(1); //等待1秒
displaymovetb(0,lin,10); //达"达"字以10的速度向上移动
displaymovetb(0,yang,10); //将"通"字以10的速度向上移动
displaymovetb(0,dian,10); //将"讯"字以10的速度向上移动
displaymovetb(0,zi,10); //将"子"字以10的速度向上移动
displaymovetb(0,0,10); //以10的速度向上清空
displayS(1); //等待1秒
displaymovetb(1,LY,10); //将"图案"以10的速度向下移动
}
}
void display()//显示
{
unsigned char i,ia,j,tmp; //定义变量
DATAOUT=0XFF; //置位高电平做准备
AB=0; //将行数据位清0,准备移位
for(i=0;i<16;i++){ //循环输出16行数据
SCK=0; //为行移位做准备
SCLT=0; //为列锁存做准备
for(ia=2;ia>0;){ //每行16个点,循环位移两个字节
ia--; //循环两次
tmp=~lhj[i*2+ia]; //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成,
//电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据
for(j=0;j<8;j++){ //循环两次,每次移一个字节,
SCLH=0; //为列移位做准备
DATA=tmp&0x01; //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位
tmp>>=1; //将数据缓冲右移一位,为下次输出做准备
SCLH=1; //将DATA上的数据移入寄存器
} //移入单字节结束
} //移入两个字节结束
DATAOUT|=0X24; //此句可以用以下两句来理解,如果不将两句合为一句,将出现拖影现像
//SCK=1; //SCK拉高,行数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)
//SCLT=1; //SCLT拉高,将数据锁存输出到相应列的点阵发光管显示,显示一行后将保持到下一行显示开始
AB=1; //行数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,
//移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱
}
j=64;
while(j--); //每一行的显示,保持了两字节的移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度
SCK=0; //
SCK=1; //将最后一行数据移出
}
void displayS(unsigned int timer) //指定时间扫描显示
{
unsigned char i;
while(timer--){ //当timer=1时,大约1秒时间
i=130;
while(i--)
display();
}
}
void displaymove(unsigned char *lp,unsigned char c,unsigned char timer)//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,
//timer是移动的速度
{
unsigned char i=0,j=0,ia=0;
unsigned int tmp=0,timerc=0;
unsigned char tmp2[16];
c*=2; //因一个汉字由32字节组成,而移位显示,要分开半个汉字16字节处理,因此将这里乘以2
for(i=0;i<16;i++)
tmp2[1]=0; //将缓冲区清0,
while(c){ //循环处理
if(lp!=0){ //当lp指向的地址为0时,直接用组缓冲0补上,效果是将当前显示的内容移出
tmp=c%2; //取余,目的是为了判断处理汉字的前半部份还是后半部份
for(i=0;i<16;i++){
tmp2[i]=lp[i*2+tmp]; //取半个汉字点阵数据,16字节
}
if(tmp) //当tmp为1时,表时一个字数组处理完成,将地址转到下一个字
lp+=32;
}
//--------------
tmp=8; //变量再次利用
while(tmp){ //循环8次,是将下一个字的前半部份的字节数据移入显示缓冲
ia=0; //做为点阵数组的元素
for(i=0;i<16;i++){//移动是16行同时移,因此要处理16个字节
lhj[ia]<<=1; //移当前显示缓冲的前半行字节
if(lhj[ia+1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理
lhj[ia]++;
ia++;
lhj[ia]<<=1; //移当前显示缓冲的后半行字节
if(tmp2[i]&0x80) //判断下一个要显示汉字的前半行字节的高位是否为1,是移入,否则不处理
lhj[ia]++;
ia++;
tmp2[i]<<=1; //下一个要显示汉字的半行字节向高位移一位,准备下一次取位
}
tmp--;
timerc=timer; //处理完16行,调用显示函数更新点阵
while(timerc--) //循环做为处理的速度,即移动的速度
display();
}
//----------
c--; //移完一半,进入下一半或下一个汉字,直到结束
}

}
void displaymovetb(unsigned char din,unsigned char *lp,unsigned char timer)
//上下移动内容,din:1为向下,0为向上,lp指向要移入的内容,timer为移动速度
{
unsigned char i=0,j=0,ia=0;
unsigned int tmp=0,timerc=0;
if(din){ //判断移动方向,向下
ia=32; //要移入第一个汉字的数组元素
i=16; //行索引
while(i--){ //逐行处理
j=30;
while(j){
j--;
lhj[j+2]=lhj[j]; //将上一行的内容复制到下一行,每两行内容相隔四个字节,复制15行
}
if(lp==0){ //最后一行的处理,判断移入的内容是否为空,是用0移入
lhj[0]=0;
lhj[1]=0;
}
else{ //否则,取字数组处理
ia--;
lhj[1]=lp[ia];
ia--;
lhj[0]=lp[ia];
}
timerc=timer; //处理完16行,调用显示函数更新点阵
while(timerc--) //循环做为处理的速度,即移动的速度
display();
}
}
else{ //移动方向,向上
ia=0; //向上移动,移入汉字从低位开始
for(i=0;i<16;i++){ //处理16行
for(j=0;j<30;j++) //将下一行的内容复制到上一行,每两行内容相隔四个字节,复制15行
lhj[j]=lhj[j+2];
if(lp==0){ //最后一行的处理,判断移入的内容是否为空,是用0移入
lhj[30]=0;
lhj[31]=0;
}
else{ //否则,取字数组处理
lhj[30]=lp[ia];
lhj[31]=lp[ia+1];
ia+=2;
}
timerc=timer; //处理完16行,调用显示函数更新点阵
while(timerc--) //循环做为处理的速度,即移动的速度
display();
}
}

}
void delay(unsigned int a) //延时
{
while(a--);
}

有字模软件修改你想要显示的字,程序要字模改动别告诉我你不懂追问

牛逼闪闪的程序啊!但是……要求用汇编,我也木有办法,蛋疼一比了。

追答

PDF

温馨提示:内容为网友见解,仅供参考
第1个回答  2012-03-07
电路图给出来呀,汇编与硬件要结合的。追问

电路图不是怎么详细,就是串行移位数据引脚在P2.0;串行移位时钟在P2.1;数码管LED输出锁存在P2.2;点阵LED输出锁存在P2.3
四块8x8点阵,用5片74HC595控制,4片用于控制LED每行的列数据,1片用于控制LED的行选择数据。
只有四个口……

第2个回答  2012-03-13
你给我QQ邮箱 我发给你吧追问

547754003@qq.com谢谢啦

本回答被提问者采纳

你好,51单片机16*16点阵滚动显示程序能不能发个给我,谢谢了!
tmp=~date[x-1][i*2+ia]; \/\/读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成, \/\/电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据 } if(dis==0) tmp=0xff; for(j=0;j<8;j++) { \/\/循环两次,每次移一个字节, SCLH=...

51单片机做音乐播放的问题
重复,中断服务程序return 单次,音乐代码执行完定时器关闭TR=0

急求用51单片机和一个74hc573芯片驱动点阵屏的C程序,如滚动显示0~9数字...
回答:这个挺好的,希望能采纳!!

...怎么做到可以三个汉字循环显示?怎么添加代码?
从而达到复位;之后,在C、C3、X以及单片机内部时钟电路的作用下,单片机89C51按照设定的程序在P0和P2接口输出与内部汉字对应的代码电平送至LED点阵的行选线(高电平驱动),同时在P1.1,P1.2,P1.3,P1.4接口输出列选扫描信号(低电平驱动),从而选中相应的象素LED发光,并利用人眼的视觉暂留特性合成整个汉字的显示。

12864LCD液晶屏如何滚动显示汉字?51单片机 求程序 汇编语言
顺序写入);=== HAN_WR2:LCALL CLEAR_P HAN_WR2A:MOV DPTR,#TAB1A ;显示汉字和字符 MOV COUNT,#10H ;地址计数器设为16。MOV A,#80H ;第一行起始地址 LCALL SEND_I LCALL QUSHU HAN_WR2B:

基于Proteus的51系列单片机设计与仿真的内容简介
《基于Proteus的51系列单片机设计与仿真》以目前流行的软、硬件仿真软件Proteus为核心,从实验、实践、实用的角度,通过丰富的实例详细叙述了该软件在51单片机课程教学和单片机应用产品开发过程中的应用。全书共9章,主要介绍51单片机系统的设计及相关软件的使用,在Proteus中原理图的绘制与仿真及PCB的制作、...

相似回答
大家正在搜