51单片机8*8点阵显示数字5,并加按键的程序,求解答
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 这个程序可以循环显示0~9.#include#include#define uchar unsigned char#define uint unsigned intuchar code Table_of_Digits[]={0x00,0x3e,0x41,0x41,0x41,0x3e,0x00,0x00, //00x00,0x00,0x00,0x21,0x7f,0x01,0x00,0x00, //10x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00, //20x00,0x22,0x49,0x49,0x49,0x36,0x00,0x00, //30x00,0x0c,0x14,0x24,0x7f,0x04,0x00,0x00, //40x00,0x72,0x51,0x51,0x51,0x4e,0x00,0x00, //50x00,0x3e,0x49,0x49,0x49,0x26,0x00,0x00, //60x00,0x40,0x40,0x40,0x4f,0x70,0x00,0x00, //70x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00, //80x00,0x32,0x49,0x49,0x49,0x3e,0x00,0x00, //90xff,0x81,0x81,0x81,0x81,0x81,0x81,0xff};uchar code xdat[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};uchar code ydat[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};uchar i=0,j=0,t=0,Num_Index,key,xi,yi; sbit we1=P1^1;sbit we2=P1^3;//主程序voidmain(){//P1=0x80;Num_Index=0; //从0 开始显示TMOD=0x01; //T0 方式0TH0=(65536-2000)/256; //2ms 定时TL0=(65536-2000)%256;IE=0x82;key=0;xi=0;yi=0;EX0=1;IT0=1;TR0=1; //启动T0while(1);}//T0 中断函数voidext_int0() interrupt 0{ key++; key&=0x03;}voidLED_Screen_Display() interrupt 1{TH0=(65536-2000)/256; //2ms 定时TL0=(65536-2000)%256;switch(key){case0: P0=0xff; we1=1; P0=~Table_of_Digits[Num_Index*8+i]; we1=0; P0=0xff; //输出位码和段码 we2=1; P0=xdat[i]; we2=0; if(++i==8) i=0; //每屏一个数字由8 个字节构成 if(++t==250) //每个数字刷新显示一段时间 { t=0; if(++Num_Index==10) Num_Index=0; //显示下一个数字 } break;case1: we1=1; P0=~xdat[xi]; we1=0; we2=1; P0=ydat[yi]; we2=0; if(++t==250) //每个数字刷新显示一段时间 { t=0; yi++; if(yi>7){yi=0;xi++;} if(xi>7)xi=0; } break;case2: we1=1; P0=0x00; we1=0; P0=0xff; //输出位码和段码 we2=1; P0=xdat[i]; we2=0; if(++t==250) //每个数字刷新显示一段时间 { if(++i==8) i=0; //每屏一个数字由8 个字节构成 t=0; } break;default: key=0; i=0; j=0; t=0; xi=0; yi=0; Num_Index=0; we1=1; P0=0xff; we1=0; we2=1; P1=0x80; we2=0; break;}}
我用74LS595做行驱动,74LS154做列驱动做了一个16*32的双色点...
/***************************************************** 16*128 LED点阵屏 C 程序 ****************************************************** 声明: 本程序供大家学习之用,用勿用于商业用途。
尊重版权。
编写:邓椿薪 时间:2006年1月20日 晚 邮箱:love2151@xinhuanet.com ******************************************************* //595连级输出数据,138行驱动。
P0_1为移动速度高速/*点阵显示汉字程串口输出字符数据, //P2口输出行扫描信号,P2_7输出595锁存信号。
*/ #define uchar unsigned char #define uint unsigned int #include #include uchar yid,h,d=12; //YID为移动计数器,H为行段计数器。
uint zimuo,zimuo1; //字模计数器 uchar BUFF[18]; //缓存 void in_data(void); //调整数据 void rxd_data(void); //发送数据 void in_data1(char h); void rxd_data1(void); void sbuf_out1(void); void sendsw(uchar k); //发送段代码 void sbuf_out(void); //16段扫描 void key(void); sbit AN1=P3^4; sbit AN2=P3^5; sbit clk=P3^3; unsigned code sw[16]={0x7f,0x6f,0x5f,0x4f,0x3f,0x2f,0x1f,0x0f,0xf7, 0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0}; /*16行段码*/ /********************************************/ void main(void) { uchar i; zimuo1=sizeof(hanzi)-6*32;//(zishu+9)*32; yid=0; zimuo=0; while(1) { while(yid=16){i=h-16;} else i=h; sendsw(sw[i]); } } /******************************************************/ void in_data1(char h) { char s,i; if(h>=16) {i=(h-16); for(s=5;s>=0;s--) //h为向后先择字节计数器,zimuoo为向后先字计数器 { // if(zimuo%32) BUFF[2*s+1]=hanzi[zimuo+1+32*s+2*i]; //把第一个字模的第一个字节放入BUFF1中,第二个字模和第一个字节放入BUFF3中 BUFF[2*s]=hanzi[zimuo+0+32*s+2*i]; // 把第一个字模的第二个字节放入BUFF0中,第二个字模的第二个字节放入BUFF1中 } } else { i=h; for(s=5;s>=0;s--) //h为向后先择字节计数器,zimuoo为向后先字计数器 { // if(zimuo%32) BUFF[2*s+1]=hanzi[zimuo+1+32*s+2*i]; //把第一个字模的第一个字节放入BUFF1中,第二个字模和第一个字节放入BUFF3中 BUFF[2*s]=hanzi[zimuo+0+32*s+2*i]; // 把第一个字模的第二个字节放入BUFF0中,第二个字模的第二个字节放入BUFF1中 } } } /*******************************************************/ void rxd_data1(void) //串行发送数据 { char s; for(s=0;s100) d=100; } } } if(AN2==0) {for(a=0;a 评论0 3 0
51单片机点阵显示一个汉字
8x8的点阵太小,很难正常显示一个汉字,通常,会使用4个8x8的点阵即16x16的点阵来显示一个汉字。
单片机在通过点阵显示汉字的时候,需要用到如下技术手段:1、汉字取模汉字取模,即把汉字对应16x16点阵的图形用16进制数来描述,形成可以用于驱动显示的数据。
例如下图,的汉字“中”该字的16x16点阵图形中,每行有16个像素,可以编码为2个字节,每8个像素,对应一个字节的高低位,则该字编码的前2个字节为0x01,0x80……,如此,可用32个字节描述汉字的点阵图形。
关于汉字取模有很多开源的软件,你可以搜索下载并使用,将你的程序中所需要使用的汉字,全部处理成字模,再定义到程序中即可。
(也可以使用汉字字库芯片,这里就不讨论了)2、扫描显示通常,驱动点阵设备时,为了节约单片机的管脚资源,会使用锁存器一类的期间,即锁存器输出端与点阵连接,而输入段由单片机控制,采用行、场扫描或分块行、场扫描的方式驱动,具体你可以搜寻相关资料。
【点阵编辑器】什么软件能编辑Windows下的fon格式点阵字体。
硬件资源: 1、一片AT89S51单片机2、由4个8*8点阵LED模块组成一个16X16点阵LED3、4个按键开关(功能预留)4、一个REST手动复位按键 注意:本电路板耗电较大,正常工作时LM7805稳压器比较烫手,有条件的客户可以加装散热器或者直接用5V/1A开关电源供电(跳过7805稳压器)工作原理分析: 从理论上说,不论显示图形还是文字,只要控制与组成这些图形或文字的各个点所在位置相对应的LED器件发光,就可以得到我们想要的显示结果,这种同时控制各个发光点亮灭的方法称为静态驱动显示方式。
16*16的点阵共有256个发光二极管,显然单片机没有这么多端口,如果我们采用锁存器来扩展端口,按8位的锁存器来计算,1 6*16的点阵需要256/8=32个锁存器。
这个数字很庞大,因为我们仅仅是16*16的点阵,在实际应用中的显示屏往往要大得多,这样在锁存器上花的成本将是一个很庞大的数字。
因此在实际应用中的显示屏都不采用这种设计,而采用另一种称为动态扫描的显示方法。
动态扫描的意思简单地说就是逐行轮流点亮,这样扫描驱动电路就可以实现多行(比如16行)的同名列共用一套列驱动器。
具体就1 6*16的点阵来说,把所有同l行的发光管的阳极连在一起,把所有同一列的发光管的阴极连在一起(共阳的接法),先送出对应第1行发光管亮灭的数据并锁存,然后选通第l行使其燃亮一定的时间,然后熄灭;再送出第2行的数据并镇存,然后选通第2行使其燃亮相同的时间,然后熄灭;-…?第16行之后,又重新燃亮第1行,腹轮回。
当这样轮回的速度足够快(每秒24次以上),由于人眼的视觉暂留现象,就能看到显示屏上稳定的图形了。
采用扫描方式进行显示时,每行有一个行驱动器,各行的同名列共用一个列驱动器。
显示数据通常存储在单片机的存储器中,按8位一个字节的形式顺序排放。
显示时要把一行中各列的数据都传送到相应的列驱动器上去,这就存在一个显示数据传输的问题。
从控制电路到列驱动器的数据传输可以采用并行方式或串行方式。
显然,采用并行方式时,从控制电路到列驱动器的线路数量大,相应的硬件数目多。
当列数很多时,并行传输的方案是不可取的。
采用串行传输的方法,控制电路可以只用一根信号线,将列数据一位一位传往列驱动器,在硬件方面无疑是十分经济的。
但是,串行传输过程较长,数据按顺序一位一位地输出给列驱动器,只有当一行的各列数据都已传输到位之后,这一行的各列才能并行地进行显示。
这样,对于一行的显示过程就可以分解成列数据准备(传输)和列数据显示两个部分。
对于串行传输方式来说,列数据准备时间可能相当长.在行扫描周期确定的情况下,留给行显示的时间就太少了,以致影响到LED的亮度。
解决串行传输中列数据准备和列数据显示的时间矛盾问题,可以采用重叠处理的方法。
即在显示本行各列数据的同时,传送下一行的列数据。
为了达到重叠处理的目的,列数据的显示就需要具有锁存功能。
经过上述分析,可以归纳出列驱动器电路应具备的主要功能。
对于列数据准备来说,它应能实现串人并出的移位功能;对于列数据显示来说,应具有并行锁存的功能。
这样,本行已准备好的数据打入并行锁存器进行显示时,串并移位寄存器就可以准备下一行的列数据,而不会影响本行的显示。
硬件电路大致上可以分成单片机系统及外围电路、列驱动电路和行驱动电路三部分单片机系统及外围电路: 单片机采用89C51或其兼容系列的芯片,采用24MHz或更高频率的晶振,以获得较高的刷新频率,使显示更稳定。
单片机的串口与列驱动器相连,用来送显示数据。
P1口低4位与行驱动器相连,送出行选信号;P1.5~P1.7口则用来发送控制信号。
PO和P2口空着,在有必要时可以扩展系统的ROM和RAM。
列驱动电路: 列驱动电路由集成电路74HC595构成。
它具有一个8位串人并出的移位寄存器和一个8位输出锁存器的结构,而且移位寄存器和输出锁存器的控制是各自独立的,可以实现在显示本行各列数据的同时,传送下一行的列数据,即达到重叠处理的目的。
它的输入侧有8个串行移位寄存器,每个移位寄存器的输出都连接一个输出锁存器。
引脚SI是串行数据的输入端。
引脚SCK是移位寄存器的移位时钟脉冲,在其上升沿发生移位,并将SI的下一个数据打人最低位。
移位后的各位信号出现在各移位寄存器的输出端,也就是输出锁存器的输入端。
RCK是输出锁存器的打人信号,其上升沿将移位寄存器的输出打人到输出锁存器。
引脚G是输出三态门的开放信号,只有当其为低时锁存器的输出才开放,否则为高阻态。
SCLR信号是移位寄存器的靖0输入端,当其为低时移位寄存器的输出全部为o。
由于SCK和RCK两个信号是互相独立的,所以能够做到输人串行移位与输出锁存互不干扰。
芯片的输出端为QA~QH.最高位QH可作为多片74HC595级联应用时,向上一级的级联输出。
但因QH受输出锁存器打人控制,所以还从输出锁存器前引出了QH',作为与移位寄存器完全同步的级联输出。
行驱动电路: 单片机P1口低4位输出的行号经4/16线译码器4515译码后生成1 6条行选通信号线,再经过驱动器驱动...
单片机汉字8x8点阵LED动态显示程序
#include sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;unsigned char code image[11][8] = { {0xC3, 0x81, 0x99, 0x99, 0x99, 0x99, 0x81, 0xC3}, //数字0 {0xEF, 0xE7, 0xE3, 0xE7, 0xE7, 0xE7, 0xE7, 0xC3}, //数字1 {0xC3, 0x81, 0x9D, 0x87, 0xC3, 0xF9, 0xC1, 0x81}, //数字2 {0xC3, 0x81, 0x9D, 0xC7, 0xC7, 0x9D, 0x81, 0xC3}, //数字3 {0xCF, 0xC7, 0xC3, 0xC9, 0xC9, 0x81, 0xCF, 0xCF}, //数字4 {0x81, 0xC1, 0xF9, 0xC3, 0x87, 0x9D, 0x81, 0xC3}, //数字5 {0xC3, 0x81, 0xF9, 0xC1, 0x81, 0x99, 0x81, 0xC3}, //数字6 {0x81, 0x81, 0x9F, 0xCF, 0xCF, 0xE7, 0xE7, 0xE7}, //数字7 {0xC3, 0x81, 0x99, 0xC3, 0xC3, 0x99, 0x81, 0xC3}, //数字8 {0xC3, 0x81, 0x99, 0x81, 0x83, 0x9F, 0x83, 0xC1}, //数字9 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //全亮};void main(){ EA = 1; //使能总中断 ENLED = 0; //使能U4,选择LED点阵 ADDR3 = 0; TMOD = 0x01; //设置T0为模式1 TH0 = 0xFC; //为T0赋初值0xFC67,定时1ms TL0 = 0x67; ET0 = 1; //使能T0中断 TR0 = 1; //启动T0 while (1);}/* 定时器0中断服务函数 */void InterruptTimer0() interrupt 1{ static unsigned char i = 0; //动态扫描的索引 static unsigned int tmr = 0; //1s软件定时器 static unsigned char index = 9; //图片刷新索引 TH0 = 0xFC; //重新加载初值 TL0 = 0x67; //以下代码完成LED点阵动态扫描刷新 P0 = 0xFF; //显示消隐 switch (i) { case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=image[index][0]; break; case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=image[index][1]; break; case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=image[index][2]; break; case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=image[index][3]; break; case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=image[index][4]; break; case 5: ADDR2=1; ADDR1=0; ADDR0=1; i++; P0=image[index][5]; break; case 6: ADDR2=1; ADDR1=1; ADDR0=0; i++; P0=image[index][6]; break; case 7: ADDR2=1; ADDR1=1; ADDR0=1; i=0; P0=image[index][7]; break; default: break; } //以下代码完成每秒改变一帧图像 tmr++; if (tmr >= 1000) //达到1000ms时改变一次图片索引 { tmr = 0; if (index == 0) //图片索引10~0循环 index = 10; else index--; }}
在proteus仿真软件中8*8LED点阵显示数码管,上面的引脚代表的是列...
你用取模软件先点个心形,然后用字节左右移来实现就可以了我有16*16点阵的各种动态效果程序给你看下总共有12种动态效果,你改成8*8就可以了/*************呈现各种显示效果的函数集****************/void flash_bai(uchar *flash_word,uchar flash_heard,uchar number,uchar sdu,uchar state)//百叶窗效果{register uchar i,j,k,l;for(i=0;i { for(j=0;j { for(l=0;l { if(j { dispram[l*4+1]=dispram[l*4+1]&0xff>(7-j)); dispram[l*4+2]=dispram[l*4+2]&0xff>>j|(flash_word[(flash_heard+i)*32+l*4+3] } else { dispram[l*4] =dispram[l*4]&0xff>(15-j); dispram[l*4+1]=flash_word[(flash_heard+i)*32+l*4]>(15-j)); dispram[l*4+2]=flash_word[(flash_heard+i)*32+l*4+2]>(j-7)); dispram[l*4+3]=(dispram[l*4+3]&0xff>>(j-7))|flash_word[(flash_heard+i)*32+l*4+3] } } delay(sdu*SPEED); } delay(state*SPEED); }}/*******************霓虹灯效果************************/void flash(uchar *flash_word,uchar flash_heard,uchar number,uchar sdu,uchar state){register uchar i,j,k,l;for(i=0;i { for(j=0;j { for(k=17;k>j;k--) { for(l=0;l { if(j>8) { dispram[l*2] =1>(16-j)); dispram[l*2+1]=flash_word[(flash_heard+i)*32+l*2+1]; } else { dispram[l*2]=1 dispram[l*2+1]=1>(8-j)); } } delay(sdu*SPEED); } for(k=17;k>j;k--) { for(l=0;l { if(j>8) { dispram[l*2]=1>(16-j)); } else { dispram[l*2]=1 dispram[l*2+1]=1>(8-j)); } } delay(sdu*SPEED); } } delay(state*SPEED); }}/*******************跳动的米奇*********************/void miqi_jump(void){uchar jump_i;while((receive[1]&0x0f){switch (abc/7280)//(receive[0]&0x0f)%9{case 0:for(jump_i=0;jump_i { dispram[jump_i*2] = Bmp1[14][jump_i*2]>7; dispram[jump_i*2+1] = Bmp1[14][jump_i*2+1] }break;case 1:for(jump_i=0;jump_i {dispram[0] = 0; dispram[1] = 0; dispram[jump_i*2+2] = Bmp1[14][jump_i*2]; dispram[jump_i*2+3] = Bmp1[14][jump_i*2+1];} break;//下移case 2:for(jump_i=0;jump_i { dispram[jump_i*2+1] = Bmp1[14][jump_i*2+1]>>1|Bmp1[14][jump_i*2] dispram[jump_i*2] = Bmp1[14][jump_i*2]>>1; }break;//右移case 3:for(jump_i=0;jump_i {dispram[30] = 0; dispram[31] = 0; dispram[jump_i*2] = Bmp1[14][jump_i*2+2]; dispram[jump_i*2+1] = Bmp1[14][jump_i*2+3];} break;//上移case 4: for(jump_i=0;jump_i { dispram[jump_i*2+2] = Bmp1[14][jump_i*2]>7; dispram[jump_i*2+3] = Bmp1[14][jump_i*2+1] dispram[0] = 0; dispram[1] = 0; } break;//下移case 5: for(jump_i=0;jump_i { dispram[jump_i*2+1] = Bmp1[14][jump_i*2+3]>>1|Bmp1[14][jump_i*2+2] dispram[jump_i*2] = Bmp1[14][jump_i*2+2]>>1; dispram[30] = 0; dispram[31] = 0; } break;//上移case 6: for(jump_i=0;jump_i { dispram[jump_i*2+3] = Bmp1[14][jump_i*2+1]>>1|Bmp1[14][jump_i*2] dispram[jump_i*2+2] = Bmp1[14][jump_i*2]>>1; dispram[0] = 0; dispram[1] = 0; } break;case 7: for(jump_i=0;jump_i { dispram[jump_i*2] = Bmp1[14][jump_i*2+2]>7; dispram[jump_i*2+1] = Bmp1[14][jump_i*2+3] dispram[30] = 0; dispram[31] = 0; } break;case 8:for(jump_i=0;jump_i dispram[jump_i] = Bmp1[14][jump_i];break;}}}/********从wordsp的第OpenDheard个字开始开门效果显示number个字**********///开门效果void Open_door(uchar wordsp[][32],uchar OpenDheard,uchar number,uchar sdu,uchar state) {register uchar i,j,w;for(w=0;w { for(j=1;j { for(i=0;i { dispram[i*2]=dispram[i*2]&0xff>(8-j); dispram[i*2+1]=dispram[i*2+1]&0xff>>j|wordsp[OpenDheard+w][1+2*i]&0xff } delay(sdu*SPEED); } delay(state*TIME); }}/********从wordsp的第CloseDheard个字开始关门效果显示number个字**********///关门效果void Close_door(uchar wordsp[][32],uchar CloseDheard,uchar number,uchar sdu,uchar state) {register uchar i,j,w;for(w=0;w { for(j=1;j { for(i=0;i { dispram[i*2]=dispram[i*2]&0xff>>j|wordsp[CloseDheard+w][2*i]&0xff dispram[i*2+1]=dispram[i*2+1]&0xff>(8-j); } delay(sdu*SPEED); } delay(state*TIME); }}/********从wordsp的第Far_Awayheard个字开始两边拉开显示number个字**********///两边拉开void Far_Away(uchar wordsp[][32],uchar Far_Awayheard,uchar number,uchar sdu,uchar state) {register uchar i,j,w;for(w=0;w { for(j=1;j { for(i=0;i { dispram[i*2]=dispram[i*2]>(8-j); dispram[i*2+1]=dispram[i*2+1]>>j|wordsp[Far_Awayheard+w][1+2*i]&0xff } delay(sdu*SPEED); } delay(state*TIME); }}/********从wordsp的第Close_Toheard个字开始两边合拢显示number个字**********///两边合拢void Close_To(uchar wordsp[][32],uchar Close_Toheard,uchar number,uchar sdu,uchar state) {register uchar i,j,w;for(w=0;w { for(j=1;j { for(i=0;i { dispram[i*2]=dispram[i*2]&0xff>>j|wordsp[Close_Toheard+w][2*i] dispram[i*2+1]=dispram[i*2+1]&0xff>(8-j); } delay(sdu*SPEED); } delay(state*TIME); }}/****************卷帘出显示number个字***************///卷帘出显示void M_Words(uchar *wordsp,uchar MWheard,uchar number,uchar sdu,uchar state) {register uchar i,w;for(w=0;w { for(i=0;i { dispram[i]=wordsp[(MWheard+w)*32+...
转载请注明出处51数据库 » c51点阵显示模拟软件