12864带字库(ST7920控制器)液晶学习+25页+1.4M
- 格式:pdf
- 大小:1.46 MB
- 文档页数:25
由于此液晶为 128*64,即是横向 128 个点,竖向 64 个点,由于该液晶控制器支持的字符 为 8*16,汉字为 16*16,因此只能显示四行,如果是汉字,为每行显示 8 个,如果是字符, 每行显示 16 个。 由上图设置 DDRAM 地址的指令可知,最高位为 1,余下 7 位为地址值,因此就对应了 为什么起始地址为 80H 的原因(即对应的写地址指令为 1000 0000) ; 因此如果你要设定显示的地址为第一行的第一个位置,只需要调用写指令函数,写入 0x80 即可。 存在的问题:参考网上的程序及在试验过程中发现,实际能显示出来的地址分布式这样的 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 //第一行汉字位置 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 //第二行汉字位置 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f //第三行汉字位置 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f //第四行汉字位置 百思不得其解,尤其让人受不了的是居然是第一行和第三行地址接续,而不是第二行,有明 白的高手给讲解一下… //******************************************************** //设置光标函数 //参数说明:x 为行号,y 为列号 //******************************************************** void Set_Cursor(unsigned char x, unsigned char y) { unsigned char i; switch(x)//确定行号 { case 0x00: i=0x80; break;//第一行 case 0x01: i=0x90; break;//第二行 case 0x02: i=0x88; break;//第三行 case 0x03: i=0x98; break;//第四行 default : break; } i = y+i;//确定列号
lcd_data=WCom; //将命令写入总线 E=0; } //******************************************************** //写数据函数 //******************************************************** void LcdWdata(unsigned char WData) { delay(1); RS=1; //指明操作对象为数据寄存器 RW=0; //指明为写操作 E=1; lcd_data=WData; //将数据写入总线 E=0; }[p=30, 2, left] 二、初始化操作
12864 带字库(ST7920 控制器)液晶学习
之前说学完 12864 字库液晶后和大家交流一下心得,一直没有时间,今天整理一下发上来, 希望对想学习的朋友能有点帮助… 首先说明一点,本人也是初学者,自感水平不高,若有不足及不对之处,望情指正… 以下以并行口传输为例,别的还不会,呵呵! 一、首先说一下关于驱动函数的书写,这些是液晶显示的基础 一般包括四个函数: 1、写命令函数; 2、写数据函数; 3、读状态函数; 4、读数据函数; 这四个函数并不是必须全部写的, 具体要看你实现的功能, 如果只是单纯的显示汉字和 字符,写命令、写数据、读状态这三个函数就够了,如过你还需要进行一些绘图的操作,那 读数据函数也必须书写。 另外关于读状态函数,其实也就是用于判忙操作,我看郭天祥的书里面是这样说的:原 则上每次对控制器进行读写操作之前, 都必须进行读写检测, 由于单片机的操作速度慢于液 晶控制器的反应速度,因此可不进行读写检测,或者只进行简短的延时即可。因此,读状态 函数也可以不写,只用简短的延时函数替换即可。 1、写操作的编写: 首先看一下时序图
照片 003.jpg 扩展程序: //******************************************************** //******************************************************** void Disp_HZ_line(unsigned char x,unsigned char y,unsigned char *HZ) { DispSetCursor(x,y); //设置显示的起始地址 while(HZ!='\0') LcdWdata(HZ[i++]); //写入需要显示汉字的高八位数据 LcdWdata(HZ[i++]); //写入需要显示字符的低八位数据 if((y+i)%16= =0) //如果满一行 if(x= =4) //如果满一屏 x=0; DispSetCursor(x,0); //重新设置显示的起始地址 } 显示一行汉字实例: /************************显示一行汉字*********************/ Display_HZ_Line(2,0,"欢迎转载,转载请注明出处,谢谢!");//显示一行汉字 效果图:
初始化操作如下: 1>芯片上电;
2>延时 40ms 以上; 3>复位操作:RST 出现一个上升沿(RST=1;RST=0;RST=1;) ; 4>功能设定; 5>延时 100us 以上; 6>再次进行功能设定; 7>延时 37us; 8>显示开关控制; 9>延时 100us 以上; 10>清除显示; 11>延时 10ms 以上; 12>进入点设置; 13>初始化结束; 这里我遇到了一个小问题,我的液晶按照这个顺序进行初始化结果不正确,无法显示, 最后我把调整了一下就可以了,调整后的顺序为:清除显示?进入点设置?显示开关控制,不 知道是什么原因,知道的告诉我一声… //******************************************************** //******************************************************** void Display_Init(v指令集 游标显示关,正常显示,整体显示开 设置为游标右移,DDRAM 位地址加 1,画面不移动 } 三、显示基本的字符和汉字 1、要想显示汉字或字符,首先要确定显示的位置,看看芯片说明书上关于屏幕地址的分配:
因为一个汉字占用两个字节的大小,因此要想显示一个汉字,需要进行两个数据写入操作。 所支持的 8192 个 16*16 的汉字详见数据手册附录中的 ST7920GB 中文字型码表。 参考程序: //******************************************************** //******************************************************** void Disp_HZ(unsigned char x,unsigned char y,unsigned char *HZ) { DispSetCursor(x,y); //设置显示的起始地址 LcdWdata(HZ[0]); //写入需要显示汉字的高八位数据 LcdWdata(HZ[1]); //写入需要显示字符的低八位数据 } 显示汉字实例: /************************显示汉字*************************/ Display_HZ(0,1,"电"); //显示电 Display_HZ(0,2,"子"); //显示子 Display_HZ(0,3,"园"); //显示园 效果图:
LcdWcom(i);//写地址 } 由数据手册可查看可以显示的字符及其显示码:
因此,当你设置好所要显示的光标位置后,即可调用写数据函数,写入对应相应字符的显示 码,比如要显示!就应该写入 0x21。 //******************************************************** //******************************************************** void Disp_Char(unsigned char Alphabet)
{ 写入需要显示字符的显示码 } 显示!实例: /**********************显示单个字符*************************/ 效果图:
扩展程序:在指定位置显示字符串 //******************************************************** //指定位置显示字符串函数 //参数说明:x 为行号,y 为列号 //******************************************************** void Display_String(unsigned char x,unsigned char y,unsigned char *Alphabet) { unsigned char i=0; Set_Cursor(x,y); //设置显示的起始地址 while(Alphabet[i]!='\0') { LcdWdata(Alphabet[i]); //写入需要显示字符的显示码 i++; } } 显示字符串实例: /***********************显示字符串*************************/ Display_String(1,0,""); //显示字符串 效果图:
写操作时序.jpg
由图可见操作很简单: 以下是我的驱动函数,仅供参考: /********************************液晶端口定义**************************/ #define lcd_data P0 //数据口 sbit RS = P2^4; //选择寄存器(并行) 0:指令寄存器 1:数据寄存器; sbit RW = P2^5; //读写控制脚(并行) 0:写入 1:读出 sbit E = P2^6; //读写数据启始脚(并行) sbit PSB = P2^1; //串并方式选择引脚,0 为串行模式,1 为 8/4 位数据口模式 sbit RST = P2^3; //复位引脚 //******************************************************** //延时函数 //******************************************************** void delay(unsigned int k) { unsigned int i; unsigned char j; for(i=0;i<k;i++) { for(j=0;j<10;j++); } } //******************************************************** //延时 1ms 函数 //******************************************************** void delay_ms(unsigned int k)//延时 0.994us,晶振 12M { unsigned int x,y; for(x=k;x>0;x--) for(y=121;y>0;y--); } //******************************************************** //写命令函数 //******************************************************** void LcdWcom(unsigned char WCom) { delay(1); RS=0; //指明操作对象为指令寄存器 RW=0; //指明为写操作 E=1;