由程序看来p2口是用来控制点阵行扫描的,p1口负责送显示的数据
p2=0x01;
//起始行高电平
for(i=0;i<8;i++)
//循环点亮8行,循环送8次数据
{
p1=tab[i];
delay(100);
//每行点亮时送上相应的显示数据(即tab[i]里的数据)
p2=p2<<1|p2>>7;
//
点亮下一行
其实点阵显示就是:(针对1616点阵显示一个汉字)
静止的显示就是扫第一行时送汉字的第一行,扫第二行时送汉字的第二行扫第16行时送汉字的第16行,这叫第一帧扫完。如果想让字动那么扫第二帧时,行扫描第一行时,送汉字的第二行数据,行扫描第二行时,送汉字的第三行数据就这样错开一行,再下一帧时再错开一行,直至错开16次一个完整的字就上移至上面了。
总的说来就是一帧一帧的显示,每帧显示汉字的一个画面,重叠在一起就看见字在动了。
按照人的常规的视觉停留的频率计算就行了,一般地,扫描频率要50HZ以上肉眼看起来就不闪烁,就拿50HZ阀值,那么一个点阵显示的时间为1S/50=20mS,即需要20mS后再对它进行扫描;
但是你每行是5mS,那么一共有8行,重复扫描时间为5mS8=40mS>>20mS,所以当然看起来闪烁。
把扫描时间跳到25到2mS就差不多了,太小的话,通电时间过短,显示亮度不足。
如果是想一起显示四个字母,把所有的LED共阴共阳,用单片机做个简单的程序,控制其通断就可以了。如果是想单个显示,则需要把你想显示的单体字母共阴共阳,不过这个程序麻烦点,要控制好几个字母电源通断的时序。当然,如果你c语言过关的话,可以变更复杂的程序,变幻一下闪烁的顺序和频率,效果会更好!
题外话:用来追MM不错~
将四个点阵按照同样的方向排列,即有字一面向着同一方向,假设四个点阵的排列方式为:
00 01
10 11
将00与01的行控制线一对一连接,10和11的行控制线一对一连接;
00与10的列控制线一对一连接,01和11的列控制线一对一连接。
最后,00和01的16根列控制线就是16x16的列控制线;
00和10的行控制线就是16x16的行控制线。
#include<reg51h>
unsigned char seven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90};
unsigned char flash,mode=0;
char min=50,hour=12,hour_rom,min_rom,sec=25;
unsigned char j,k;
unsigned int i;
unsigned char key_set_s,key_up_s,key_down_s,key_reset_s;
sbit P0_7=P0^7;
sbit key_set=P3^4;
sbit key_up=P3^5;
sbit key_down=P3^6;
sbit key_reset=P3^7;
sbit buzzer=P1^0;
bit dop,bb; //声明
void delay(unsigned int x) //延时
{
while(x--);
}
void timer0_isr(void) interrupt 1 //中断服务函数
{
TH0=0xf8; //为65535-2000=63535转化为16进制取高八位
TL0=0x2f; //取低八位
i++;
bb=!bb;
if(i>=250) //半秒,五百一秒
{
i=0;
k++;
flash=~flash;
dop=!dop;
}
if(k>=2) //大于二归零
{
k=0;
sec++;
}
if(sec>=60) //秒
{
sec=0;
min++;
}
if(min>=60) //分
{
min=0;
hour++;
}
if(hour>=24) //小时
hour=0;
P0=0xff; //P0初始化为全1 11111111
if(mode==0) //正常显示
{
switch(j) //控制语句
{
case 0:P0=seven_seg[sec%10];P2=0xfe;break; //秒个位
case 1:P0=seven_seg[sec/10];P2=0xfd;break; //秒十位
case 2:P0=seven_seg[min%10];P0_7=dop;P2=0xfb;break;
case 3:P0=seven_seg[min/10];P2=0xf7;break;
case 4:P0=seven_seg[hour%10];P0_7=dop;P2=0xef;break; //dop为小数点
case 5:P0=seven_seg[hour/10];P2=0xdf;break;
}
}
////////////////////
if(mode==1) //模式一 C1状态
{
switch(j)
{
case 0:P0=seven_seg[min%10];P2=0xfe;break;
case 1:P0=seven_seg[min/10];P2=0xfd;break;
case 2:P0=seven_seg[hour%10]| flash;P2=0xfb;break; //flash为闪烁
case 3:P0=seven_seg[hour/10]| flash;P2=0xf7;break;
case 4:P0=seven_seg[1];P2=0xef;break; //1为C1状态
case 5:P0=0xc6;P2=0xdf;break; //0xc6为显示C
}
}
////////////////////
if(mode==2) //模式二 C1状态
{
switch(j)
{
case 0:P0=seven_seg[min%10]| flash;P2=0xfe;break;
case 1:P0=seven_seg[min/10]| flash;P2=0xfd;break;
case 2:P0=seven_seg[hour%10];P2=0xfb;break;
case 3:P0=seven_seg[hour/10];P2=0xf7;break;
case 4:P0=seven_seg[1];P2=0xef;break;
case 5:P0=0xc6;P2=0xdf;break;
}
}
////////////////////
if(mode==3) //模式三 C2状态
{
switch(j)
{
case 0:P0=seven_seg[min_rom%10];P2=0xfe;break;
case 1:P0=seven_seg[min_rom/10];P2=0xfd;break;
case 2:P0=seven_seg[hour_rom%10]| flash;P2=0xfb;break;
case 3:P0=seven_seg[hour_rom/10]| flash;P2=0xf7;break;
case 4:P0=seven_seg[2];P2=0xef;break;
case 5:P0=0xc6;P2=0xdf;break;
}
}
////////////////////
if(mode==4) //模式四 C2状态
{
switch(j)
{
case 0:P0=seven_seg[min_rom%10]| flash;P2=0xfe;break;
case 1:P0=seven_seg[min_rom/10]| flash;P2=0xfd;break;
case 2:P0=seven_seg[hour_rom%10];P2=0xfb;break;
case 3:P0=seven_seg[hour_rom/10];P2=0xf7;break;
case 4:P0=seven_seg[2];P2=0xef;break;
case 5:P0=0xc6;P2=0xdf;break;
}
}
j++;
if(j>=6)
j=0;
}
void key(void) //调用开关函数
{
////////////////
if(key_set==0) //设置
{
delay(300);
if(key_set==0)
key_set_s=1;
}
if(key_set==1&&key_set_s==1)
{
mode++;
if(mode>=5)
mode=1;
key_set_s=0;
}
////// ///
if(key_up==0) //上调
{
delay(300);
if(key_up==0)
key_up_s=1;
}
if(key_up==1&&key_up_s==1)
{
if(mode==1)hour++;
if(mode==2)min++;
if(mode==3)hour_rom++;if(hour_rom>=24)hour_rom=0;
if(mode==4)min_rom++;if(min_rom>=60)min_rom=0;
key_up_s=0;
}
/////////////////
if(key_down==0) //下调
{
delay(300);
if(key_down==0)
key_down_s=1;
}
if(key_down==1&&key_down_s==1)
{
if(mode==1)hour--;if(hour<0)hour=23;
if(mode==2)min--; if(min<0)min=59;
if(mode==3)hour_rom--;if(hour_rom<0)hour_rom=23;
if(mode==4)min_rom--;if(min_rom<0)min_rom=59;
key_down_s=0;
}
/////////////////
if(key_reset==0) //复位
{
delay(300);
if(key_reset==0)
key_reset_s=1;
}
if(key_reset==1&&key_reset_s==1)
{
key_reset_s=0;
mode=0;
}
}
void timer0_init(void) //timero初始化函数
{
TMOD=0x01; //方式1
TH0=0xf8;
TL0=0x2f;
EA=1; //中断开关
ET0=1; //中断小开关
TR0=1; //开始计数
}
void main(void) //主函数
{
timer0_init();
while(1)
key();
{
if(hour==hour_rom&&min==min_rom)
buzzer=bb; //buzzer为蜂鸣器
}
}
主循环程序中,j 循环结束别加延时,那个delay(250);删掉。j 循环一次只是显示一屏,应再循环显示n屏,再 i 循环,调这个n大小,就是调滚动的速度。
你现在是,一屏只显示一次,又加延时250,这等于黑屏了250的延时,那还不闪一下才怪!
以上就是关于LED点阵汉字显示移动程序全部的内容,包括:LED点阵汉字显示移动程序、我用51单片机串行通信方式去控制一块8×8LED点阵屏,显示的时候,文字闪烁厉害……、如何用单片机程序控制8x16点阵LED显示出LOVE 谢谢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)