12864.h #ifndef __12864_H__ #define __12864_H__ #include<reg52.h> #include <intrins.h> /*************************************** 利用I/O口模拟点阵液晶所需时序 点阵液晶控制端口定义,需根据硬件适当改变 ****************************************/ sbit LCD_RS = P2^0;//控制端口定义 sbit LCD_RW = P2^1; sbit LCD_E = P2^2; sbit LCD_CSA = P2^3;//H选通,即高电平有效 sbit LCD_CSB = P2^4; #define LCD_Data P0//LCD数据端口8位 #define R 1 #define L 2 /***************************************** 函数声明 *****************************************/ void ReadStatusLCD(unsigned char select);//从LCD读出忙标志位 unsigned char ReadDataLCD(unsigned char select);//从LCD读出数据 void WriteDataLCD(unsigned char WDLCD,unsigned char select);//向LED写入数据 void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select);//向LCD写入命令 void LcdReset(void) ;//初始化函数,完成液晶模块的初始设置 void clear_LCD(unsigned char select);//清屏函数 void Clr_All_Lcd(void);//全清屏函数 void set_XY(unsigned char Column,unsigned char Page);//设置数据写入或读出的地址,通过页号和列数可以唯一确定一个地址 void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW);//向指定行列写数据 void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte );//显示点 void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] );//显示16×16点阵的编码 void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num, unsigned char V_num, unsigned char * puts );//通用的显示函数 void Drawing_dot(unsigned char x,unsigned char y); void Drawing_line_vertical(unsigned x); #endif 12864.c /**************************************************** LCD12864点阵液晶屏, 通过I/O口直接控制,采用模拟时序控制 ****************************************************/ #include"12864.h" #include<math.h> /*********************************************************** 功能:从LCD读取状态位 变量:select用于选择LCD屏的左右,1选择左屏,2选择右屏 ***********************************************************/ void ReadStatusLCD(unsigned char select) { switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } LCD_Data = 0xff;//置位输入口,已实现输入 LCD_RS=0;LCD_RW=1;LCD_E=1;//高电平读取数据 //_nop_(); //若晶振速度高,可在此作延时处理 while(LCD_Data&0x80);//最高位为忙标志,检测忙信号状态 LCD_E=0; //_nop_(); //若晶振速度高,可在此作延时处理 } /*********************************************************** 功能:从LCD读取数据 变量:select用于选择LCD屏的左右,1选择左屏,2选择右屏 ***********************************************************/ unsigned char ReadDataLCD(unsigned char select) { unsigned char dataR; LCD_Data = 0xff;//置位输入口,已实现输入 switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } LCD_RW=1;LCD_RS=1;LCD_E = 1;// 操作允许脉冲信号,高电平读出 //_nop_(); //若晶振速度高,可在此作延时处理 dataR = LCD_Data; LCD_E= 0; return dataR; } /*********************************************************** 功能: 向LCD写入数据 参数: WDLCD待写入的字符数据 select用于选择LCD屏的左右,1选择左屏,2选择右屏 ***********************************************************/ void WriteDataLCD(unsigned char WDLCD,unsigned char select) { switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } ReadStatusLCD(select);//检测忙标志 LCD_RS = 1;LCD_RW = 0; LCD_Data = WDLCD; LCD_E = 1; //_nop_(); //若晶振速度高,可在此作延时处理 LCD_E = 0; //下降沿写入数据 //_nop_(); //若晶振速度高,可在此作延时处理 } /*********************************************************** 功能:向LCD写入命令 参数: WDLCD待写入的字符数据 BusyC是否要检查忙标志位选择标志,1为进行,0为不检测 select用于选择LCD屏的左右,1选择左屏,2选择右屏 ***********************************************************/ void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select) { if(BusyC) ReadStatusLCD(select);//根据需要检测忙 switch(select) { case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左 case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右 default: break; } LCD_Data = WCLCD; LCD_RS = 0;LCD_RW = 0;LCD_E = 1; //_nop_(); //若晶振速度高,可在此作延时处理 LCD_E = 0; } /****************************************************************************** 功能:清显示RAM区(清屏) 参数:select为驱动控制器选择 1为左 2为右 ********************************************************************************/ void clear_LCD(unsigned char select) { unsigned char i,j; for(i=0;i<8;i++) { //8页,换页清零 WriteCommandLCD( 0xb8|i,1 ,select);//页面地址设置,并分别写入左右模块中 WriteCommandLCD( 0x40,1 ,select);//列地址设置,设置为0列,并分别写入左右三个模块中 for(j=0;j<64;j++) { //页内清零 WriteDataLCD( 0 ,select); } } } /***************************************************************************** 功能:清LCD左右屏 *****************************************************************************/ void Clr_All_Lcd(void) { clear_LCD(1); clear_LCD(2); } /****************************************************************************** 功能:LCD初始化,分为左,右模块初始化 参数:select为驱动控制器选择 1为左 2为右 ********************************************************************************/ void LcdReset(void) { unsigned char i; for(i=0;i<5;i++) { WriteCommandLCD( 0xc0,0 ,R);//设置显示起始行为第一行,并分别写入左右模块中,不检测忙标志 WriteCommandLCD( 0xc0,0 ,L); //_nop_(); //若晶振速度高,可在此作延时处理 } WriteCommandLCD( 0xc0,1 ,R);//设置显示起始行为第一行,并分别写入左右模块中,检测忙标志 WriteCommandLCD( 0xc0,1 ,L); WriteCommandLCD( 0x3f,1 ,R);//开显示设置,并分别写入左右模块中 WriteCommandLCD( 0x3f,1 ,L); clear_LCD(R);//清左屏 clear_LCD(L);//清右屏 } /****************************************************************************** 功能:设置数据写入或读出的地址,通过页号和列数可以唯一确定一个地址 参数:Column表示列号,Page表示页号 ********************************************************************************/ void set_XY(unsigned char Column,unsigned char Page) { unsigned char x,y; unsigned char select; switch (Column&0x40) //完成左右屏的判断 ,根据列号完成区分,<64为左屏,>=64为右屏 { case 0x00: {select = 1;ReadStatusLCD(select);break;}/*为左区 */ case 0x40: {select = 2;ReadStatusLCD(select);break;}/*为右区 */ } x = Column&0x3F|0x40; /* col.and.0x3f.or.Set Y Address*/ y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */ WriteCommandLCD( y,1 ,select);//设置页面地址 WriteCommandLCD( x,1 ,select);//设置列地址 } /****************************************************************************** 功能:根据地址值(页数和列号),写入数据,即写入显示缓冲区,便可以显示在LCD屏上 参数:Column表示列号,Page表示页号,dataW表示待写入的数据 ********************************************************************************/ void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW) { set_XY(Column,Page); LCD_RW=0; LCD_RS=1; _nop_();//若晶振速度高,可在此作延时处理 LCD_Data = dataW;// 送数据 _nop_(); //若晶振速度高,可在此作延时处理 LCD_E = 1; _nop_(); //若晶振速度高,可在此作延时处理 LCD_E= 0; // 操作允许脉冲信号,下降沿写入 } /****************************************************************************** 功能: 用于显示点阵 参数:Column表示列号,Page表示页号, ********************************************************************************/ void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte ) { unsigned char i; i=Column; for(;Page<8;Page++) { for(;Column<128;Column++) { xy_Write(Column,Page,DotByte); //DotByte = ~DotByte; } Column=i; } } /****************************************************************************** 功能:在指定列,指定页显示待显示的点阵编码,用于显示16*16点阵码 参数:Column表示列号,Page表示页号,puts待显示的点阵编码首指针 ********************************************************************************/ void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] ) { unsigned char i,j; for(i=0;i<2;i++)//此处的2为控制点阵行数,实际点阵行数为2*8=16行,此处的16(对应的点行数)应为8的倍数 { for(j=0;j<16;j++)//此处控制每行显示的列数 { xy_Write(Column+j,Page+i,puts[i][j]); } } } /****************************************************************************** 功能:在指定列,指定页显示待显示指定点阵的编码 参数:Column表示列号,Page表示页号,C_num为显示点阵的行数(物理行 8的倍数),V_num为列(物理列)puts待显示的点阵编码首指针 ********************************************************************************/ void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num,unsigned char V_num, unsigned char * puts) { unsigned char i,j; for(i=0;i<(C_num/8);i++)//此处的2为控制点阵行数,实际点阵行数为2*8=16行,此处的16(对应的点行数)应为8的倍数 { for(j=0;j<V_num;j++)//此处控制每行显示的列数 { xy_Write(Column+j,Page+i,*(puts+i*V_num+j));//注意地址的变化规律 } } } /****************************************************************************** 功能:绘点 参数:Column表示列号,Page表示页号,C_num为显示点阵的行数(物理行 8的倍数),V_num为列(物理列)puts待显示的点阵编码首指针 ********************************************************************************/ void Drawing_dot(unsigned char x,unsigned char y) { unsigned char y_byte,x_bit,y_bit,reverse_y;//此处y_byte为page,y_bit为具体行号,x_bit为行号 unsigned char dot; reverse_y=63-y; x_bit=x; y_byte=reverse_y/8; y_bit=y%8; // for(;x_bit<128;x_bit++) if(y_bit==0) dot=0x80; if(y_bit==1) dot=0x40; if(y_bit==2) dot=0x20; if(y_bit==3) dot=0x10; if(y_bit==4) dot=0x08; if(y_bit==5) dot=0x04; if(y_bit==6) dot=0x02; if(y_bit==7) dot=0x01; xy_Write(x_bit,y_byte,dot); /* reverse_y=64-y; if(y_bit==7) y_byte=y_byte-1; y_bit=y%8; if(y_byte==(-1)) break;*/ } /****************************************************************************** 功能:绘垂直直线 参数:x表示列号 ********************************************************************************/ void Drawing_line_vertical(unsigned char x) { xy_Write(x,0,0xff); xy_Write(x,1,0xff); xy_Write(x,2,0xff); xy_Write(x,3,0xff); xy_Write(x,4,0xff); xy_Write(x,5,0xff); xy_Write(x,6,0xff); xy_Write(x,7,0xff); } 主程序.c /********************************************************************************************** 12864液晶屏上显示"南京绝妙科技发展有限公司,025-84532868 开发板欢迎使用","0~9",刷新后重显。 *************************************************************************************************/ #include<reg52.h> #include<math.h> #include"12864.h" #include"zifulib.h" #define uint unsigned int #define uchar unsigned char sbit adrd=P3^7; //IO口定义 sbit adwr=P3^6; sbit cs=P2^5; unsigned adval; /*********************************************************** 功能:延时程序 入口参数: 日期: ***********************************************************/ void DelayMs(unsigned char count) { unsigned int temp; while(count--) { for(temp=5000;temp;temp--) ; } } void adc() // 主程序 { //********************* 启动adc0804 **********************// adrd=1; cs=0; adwr=1; adwr=0; _nop_(); adwr=1; //********************* 读取adc0804 **********************// DelayMs(1); cs=0; adrd=0; //重新打开有AD片选信号锁存器的锁存端 adval=P1; //同时把AD的值送八个发光二极显示 } /************************************* 显示公司名称,电话等信息 *************************************/ /*void Dis_Information(void) { whiteword(16,0,nan);//南 whiteword(32,0,jing);//京 whiteword(48,0,jue);//绝 whiteword(64,0,miao);//妙 whiteword(80,0,ke);//科 whiteword(96,0,ji);//技 whiteword(16,2,fa);//发 whiteword(32,2,zhan);//展 whiteword(48,2,you);//有 whiteword(64,2,xian);//限 whiteword(80,2,gong);//公 whiteword(96,2,si);//司 WhiteWord_Com(16,4,16,8,shuzi[0]);//0 WhiteWord_Com(24,4,16,8,shuzi[2]);//2 WhiteWord_Com(32,4,16,8,shuzi[5]);//5 //WhiteWord_Com(40,4,16,8,heng);//- WhiteWord_Com(48,4,16,8,shuzi[8]);//8 WhiteWord_Com(56,4,16,8,shuzi[4]);//4 WhiteWord_Com(64,4,16,8,shuzi[5]);//5 WhiteWord_Com(72,4,16,8,shuzi[3]);//3 WhiteWord_Com(80,4,16,8,shuzi[2]);//2 WhiteWord_Com(86,4,16,8,shuzi[8]);//8 WhiteWord_Com(92,4,16,8,shuzi[6]);//6 WhiteWord_Com(100,4,16,8,shuzi[8]);//8 whiteword(16,6,kai);//开 whiteword(32,6,fa);//发 whiteword(48,6,ban);//板 whiteword(64,6,huan);//欢 whiteword(80,6,ying);//迎 whiteword(96,6,shi);//使 whiteword(112,6,yong);//用 } */ /************************************** 主函数 ***************************************/ void main(void) { unsigned char x,i,k;//x绘图坐标 xdata unsigned char y[128];//每个x对应的y坐标 float x_float; //unsigned x_move;//图像向右移动 //unsigned char i,j; //DelayMs(1);//如果上电速度过快,可做适当延时,以等待LCD完成复位 LcdReset(); //DelayMs(1);//可做适当延时,以等待LCD初始化完成 whiteword(48,0,xin); whiteword(64,0,dian); whiteword(80,0,tu); whiteword(96,0,yi); DelayMs(50); while(1) { for(k=0;k<128;k++) { x_float=2*3.14*k/32; y[0]=sin(x_float);//画出sin正弦波形 for(i=128;i>0;i--)//实现波形的移动 { y[i]=y[i-1]; } Clr_All_Lcd(); for(x=0;x<128;x++) { Drawing_dot(x,20+y[x]); } } // adc(); //y=adval/2; /*LcmPutDots(15,2, 0xff);// DelayMs(50); Clr_All_Lcd(); Dis_Information();//显示公司信息 DelayMs(100); Clr_All_Lcd(); for(j=0;j<4;j++) { for(i=0;i<10;i++) { WhiteWord_Com((i+j)*8+j,j*2,16,8,shuzi[i]); } DelayMs(10); Clr_All_Lcd(); } DelayMs(10); Clr_All_Lcd();*/ } } 字库文件.h #ifndef __ZIFULIB_H__ #define __ZIFULIB_H__ /**************************************************** *****************************************************/ //******心 code unsigned char xin[2][16]={ 0x00,0x00,0x80,0x00,0x00,0xE0,0x02,0x04,0x18,0x00,0x00,0x00,0x40,0x80,0x00,0x00, 0x10,0x0C,0x03,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x78,0x00,0x01,0x0E,0x00 }; //******电 code unsigned char dian[2][16]={ 0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00, 0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00 }; //******图 code unsigned char tu[2][16]={ 0x00,0xFE,0x02,0x42,0x22,0x32,0x5E,0x92,0x52,0x32,0x12,0x02,0x02,0xFE,0x00,0x00, 0x00,0xFF,0x42,0x42,0x42,0x51,0x55,0x64,0x69,0x41,0x42,0x42,0x42,0xFF,0x00,0x00 }; //******仪 code unsigned char yi[2][16]={ 0x00,0x80,0x60,0xF8,0x07,0x00,0x1C,0xE0,0x01,0x06,0x00,0xE0,0x1E,0x00,0x00,0x00, 0x01,0x00,0x00,0xFF,0x00,0x80,0x40,0x20,0x13,0x0C,0x13,0x20,0x40,0x80,0x80,0x00 }; /*************************** 阿拉伯数字 ***************************/ code unsigned char shuzi[10][16]={ /*-- 文字: 0 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0xF0,0x08,0x08,0x18,0xE0,0x00,0x00,0x00,0x0F,0x10,0x20,0x10,0x0F,0x00, /*-- 文字: 1 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x00,0x00,0x00, /*-- 文字: 2 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x30,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x14,0x13,0x10,0x08,0x00, /*-- 文字: 3 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0x10,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x11,0x0E,0x00, /*-- 文字: 4 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1F,0x02,0x00, /*-- 文字: 5 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0x70,0x48,0xC8,0x88,0x00,0x00,0x00,0x10,0x10,0x20,0x10,0x0F,0x00,0x00, /*-- 文字: 6 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0xE0,0x90,0x88,0x80,0x00,0x00,0x00,0x07,0x18,0x20,0x20,0x19,0x06,0x00, /*-- 文字: 7 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x10,0x08,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x00,0x18,0x07,0x00,0x00,0x00, /*-- 文字: 8 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x00,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x0C,0x12,0x21,0x21,0x1E,0x00,0x00, /*-- 文字: 9 --*/ /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/ 0x00,0x60,0x98,0x08,0x08,0xF8,0xC0,0x00,0x00,0x00,0x21,0x12,0x09,0x07,0x00,0x00 }; #endif |