昨天重写了LED电子屏的核心程序,重构后的程序框架可以方便的扩展各种显示特效,我只写了电子屏右移显示函数,点阵屏程序的更新就此结束,下一步将会进行步进电动机的控制方面的制作,电路还是按上一版http://www.51hei.com/mcu/2597.html 现在上程序:
//行扫1#74hc154芯片对应数据输入口:P0^0->P0^3数据输入控制口:P0^4低电平有效;行扫输出为互斥低电平输出; //列扫1#74hc595芯片对应数据输入口:P0^5移位寄存器时钟信号;P0^6存储寄存器数据更新时钟;P0^7数据输出使能,低电平时输出有效; //P2^0串行数据输入 #include<reg52.h>//包函头文件 #include<intrins.h>//包函_nop_延时函数的头文件 #define uchar unsigned char//宏定义 #define uint unsigned int//宏定义 //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// uchar ZMHCQ[]= { //16X16点阵显示缓冲区 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, }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// uchar code ZM000[]= { //源文件 / 文字: 祝 0x00,0x00,0x20,0x00,0x11,0xF8,0x01,0x08, 0x79,0x08,0x09,0x08,0x11,0x08,0x11,0xF8, 0x38,0x90,0x54,0x90,0x10,0x90,0x10,0x90, 0x11,0x14,0x11,0x14,0x12,0x0C,0x00,0x00, }; uchar code ZM001[]= { //源文件 / 文字: 荣 0x00,0x00,0x08,0x20,0x7F,0xFC,0x08,0x20, 0x00,0x00,0x7F,0xFC,0x40,0x04,0x01,0x00, 0x01,0x00,0x7F,0xFC,0x03,0x80,0x05,0x40, 0x19,0x30,0x61,0x0C,0x01,0x00,0x00,0x00, }; //////////////////////////////////////////////////////////////////////////////// sbit HC154_A=P0^0;//HC154数据输入口 sbit HC154_B=P0^1;//HC154数据输入口 sbit HC154_C=P0^2;//HC154数据输入口 sbit HC154_D=P0^3;//HC154数据输入口 sbit G1=P0^4;//HC154使能端控制 sbit SH=P0^5;//HC595移位控制 sbit ST=P0^6;//HC595锁存更新显示 sbit OE=P0^7;//HC595使能端控制 sbit DS=P2^0;//HC595串行数据输入 //////////////////////////////////////////////////////////////////////////////// void chushihua() //硬件初始化 { OE=1; //关闭HC595输出 G1=1; //关闭HC154输出 } //////////////////////////////////////////////////////////////////////////////// void delay(uint ms)//延时子程序 { uint x,y; for(x=ms;x>0;x--) for(y=0;y<240;y++); } //////////////////////////////////////////////////////////////////////////////// //低位先入 void sendbyte(uchar Rdate)//HC595串行输入一个字节 { uint a; uchar date=Rdate; for(a=0;a<8;a++) { SH=0; if(date&0x01)//先将最低位移入 { DS=1; SH=1; } else { DS=0; SH=1; } date=date>>1;//输入的字节位右移 } } //////////////////////////////////////////////////////////////////////////////// void HC595_GX() //HC595锁存数据更新并输出 { ST=0; _nop_(); ST=1; //HC595锁存数据更新 _nop_(); OE=0; //HC595输出 } //////////////////////////////////////////////////////////////////////////////// void HC154_HS(uint x)//X行低电平输出 { G1=0; switch(x) { case 1: HC154_A=0; HC154_B=0; HC154_C=0; HC154_D=0; break; case 2: HC154_A=1; HC154_B=0; HC154_C=0; HC154_D=0; break; case 3: HC154_A=0; HC154_B=1; HC154_C=0; HC154_D=0; break; case 4: HC154_A=1; HC154_B=1; HC154_C=0; HC154_D=0; break; case 5: HC154_A=0; HC154_B=0; HC154_C=1; HC154_D=0; break; case 6: HC154_A=1; HC154_B=0; HC154_C=1; HC154_D=0; break; case 7: HC154_A=0; HC154_B=1; HC154_C=1; HC154_D=0; break; case 8: HC154_A=1; HC154_B=1; HC154_C=1; HC154_D=0; break; case 9: HC154_A=0; HC154_B=0; HC154_C=0; HC154_D=1; break; case 10: HC154_A=1; HC154_B=0; HC154_C=0; HC154_D=1; break; case 11: HC154_A=0; HC154_B=1; HC154_C=0; HC154_D=1; break; case 12: HC154_A=1; HC154_B=1; HC154_C=0; HC154_D=1; break; case 13: HC154_A=0; HC154_B=0; HC154_C=1; HC154_D=1; break; case 14: HC154_A=1; HC154_B=0; HC154_C=1; HC154_D=1; break; case 15: HC154_A=0; HC154_B=1; HC154_C=1; HC154_D=1; break; case 16: HC154_A=1; HC154_B=1; HC154_C=1; HC154_D=1; break; default: break; } } //////////////////////////////////////////////////////////////////////////////// void OUT16x16()//点阵屏输出16x16点阵字模缓冲区数据 { uint y;//行扫数据控制 uint x_H;//列高位数据控制 uint x_L;//列低位数据控制 for(y=1,x_H=0,x_L=1;y<=16;y++) { sendbyte(ZMHCQ[x_L]); sendbyte(ZMHCQ[x_H]); HC595_GX(); HC154_HS(y); x_H+=2; x_L+=2; delay(1); } } //////////////////////////////////////////////////////////////////////////////// void ZMHCQ_GX(uchar code ZM[31])//以静态方式向字模缓冲区写入一个16x16点阵字模数据 { uint x; for(x=0;x<32;x++) { ZMHCQ[x]=ZM[x]; } } //////////////////////////////////////////////////////////////////////////////// void ZMHCQ_YY()//字模缓冲区数据按行右移一位 { uint x_H,x_L,y; uchar date; for(y=1,x_H=0,x_L=1;y<=16;y++) { ZMHCQ[x_L]=ZMHCQ[x_L]>>1;//将x_L字节的低位移出空出高位 date=ZMHCQ[x_H]; if(date&0x01)//将最x_H字节的低位移入x_L字节的高位 { ZMHCQ[x_L]=ZMHCQ[x_L]|0x80; } else { ZMHCQ[x_L]=ZMHCQ[x_L]&0x7F; } ZMHCQ[x_H]=ZMHCQ[x_H]>>1;//x_H字节右移一位 x_H+=2; x_L+=2; } } //////////////////////////////////////////////////////////////////////////////// uint byte_b(uchar Rdate,uint x)//函数返回date字节数据倒数第x位的值 { uchar date; date=Rdate; date=date>>(x-1); if(date&0x01) {return 1;}else {return 0;} } //////////////////////////////////////////////////////////////////////////////// void ZMHCQ_GX_YY(uchar code ZM[31],uint s)//以右移方式向字模缓冲区写入数据s为移动速度 { uint x,y,i,j; for(x=1;x<=8;x++) { ZMHCQ_YY(); for(i=1,y=1,j=0;i<=16;i++) { if(byte_b(ZM[y],x)) { ZMHCQ[j]=ZMHCQ[j]|0x80; } else { ZMHCQ[j]=ZMHCQ[j]&0x7F; } y+=2; j+=2; OUT16x16(); delay(s); } } for(x=1;x<=8;x++) { ZMHCQ_YY(); for(i=1,y=0,j=0;i<=16;i++) { if(byte_b(ZM[y],x)) { ZMHCQ[j]=ZMHCQ[j]|0x80; } else { ZMHCQ[j]=ZMHCQ[j]&0x7F; } y+=2; j+=2; OUT16x16(); delay(s); } } } //////////////////////////////////////////////////////////////////////////////// void main() //主函数 { uint x,y; chushihua(); while(1) { /////////////////////////////////////////////////////////////////////////// ZMHCQ_GX(ZM000); for(y=0;y<16;y++) { for(x=0;x<20;x++) { OUT16x16(); } ZMHCQ_YY(); } /////////////////////////////////////////////////////////////////////////// ZMHCQ_GX(ZM001); for(y=0;y<16;y++) { for(x=0;x<20;x++) { OUT16x16(); } ZMHCQ_YY(); } /////////////////////////////////////////////////////////////////////////// ZMHCQ_GX_YY(ZM000,2); ZMHCQ_GX_YY(ZM001,2); } }