LCD12864绘图之KS0108(3)

合集下载

CM12864-1规格书 KS0108控制器

CM12864-1规格书 KS0108控制器
void delay(int t) { int i,j,k;
for(i=0;i<t;i++) { for(j=0;j<255;j++)
k++;}
}
void write_com_l(unsigned int command) { cs1=1; rw=0; di=0; lcd_data=command; e=1; e=0; cs1=0; }
cs2=1; rw=0; di=1; lcd_data=data0; e=1; e=0; cs2=0;
} void disp0() {
unsigned int i,j; for (i=0;i<8;i++)
{write_com_l(0xb8+i); write_com_r(0xb8+i); write_com_l(0x40); write_com_r(0x40); for (j=0;j<64;j++)
write_com_r(0x40); for (j=0;j<64;j++)
{wr }
}
void disp2() {
unsigned int i,j; for (i=0;i<8;i++)
{write_com_l(0xb8+i); write_com_r(0xb8+i); write_com_l(0x40); write_com_r(0x40); for (j=0;j<64;j++)
do {}while(1); }
{write_data_l(0xf0); write_data_r(0xf0); } }

12864点阵型液晶模块的使用

12864点阵型液晶模块的使用

12864点阵型液晶模块的使用一、简介12864点阵型LCD是小型系统中很常用的显示器,目前常用的的主控芯片有KS0108、ST7920等。

KS0108是三星公司的产品,与HD61202控制器完全兼容,不带字库、不支持串口。

ST7920是台湾矽创电子公司生产的中文图形控制芯片,自带字库、支持4位、8位并行、2线、3线串行接口方式点阵型液晶因为能显示较丰富的信息,所以现在运用越来越广泛,下图为常用的12864液晶模块的正面图片。

二、功能介绍我们使用的模块为KS0108主控芯片,其接口定义如下:第1脚:VSS为电源地,接GND。

第2脚:VDD接5V正电源。

第3脚:VL为液晶显示器对比度调整端第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。

当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

第7~14脚:D0~D7为8位双向数据线。

第15脚:CS1为片选择信号,低电平时选择前64列。

1第16脚:CS2为片选择信号,低电平时选择后64列。

第17脚:RES复位信号,低电平有效。

第18脚:-5V LCD驱动电源,负压输出第19脚:BLA背光电源正极(+5V)输入引脚。

第20脚:BLK背光电源负极,接GND。

根据管脚定义,电路设计连接如下图:其指令表为:指令1:显示开/关设置。

DB0=H,开显示;DB0=L,关显示。

不影响显示RAM(DD RAM)中的内容。

指令2:功能:DD RAM 的列地址存储在Y地址计数器中,读写数据对列地址有影响,在对DD RAM进行读写操作后,Y地址自动加一。

指令3:设置页地址。

执行本指令后,下面的读写操作将在指定页内,直到重新设置。

页地址就是DD RAM 的行地址,页地址存储在X地址计数器中,A2-A0可表示8页,读写数据对页地址没有影响,除本指令可改变页地址外,复位信号(RST)可把页地址计数器内容清零。

ks0108中文资料

ks0108中文资料

电子发烧友 电子技术论坛点阵图形液晶显示模块HD61202控制器使用手册目录注意事项----------------------------------------------------------------------------------------------------------------------------2第一章、关于HD61202 及其兼容控制驱动器的一般介绍----------------------------------4一、HD61202 及其兼容控制驱动器的特点-------------------------------------------------------------------------4二、HD61202 及其兼容控制驱动器的引脚功能-------------------------------------------------------------------4三、HD61202 及其兼容控制驱动器的时序-------------------------------------------------------------------------6四、HD61202 及其兼容控制驱动器显示RAM 的地址结构-----------------------------------------------------7五、HD61202 及其兼容控制驱动器的指令系统-------------------------------------------------------------------7第二章:内藏HD61202 及其兼容控制驱动器图形液晶显示模块的电路结构特点-------------------------------------------------------------------------------------9第三章:内藏HD61202 及其兼容控制驱动器图形液晶显示模块的应用用----------------------------------------------------------------11注意事项十分感谢您购买我公司的产品。

12864液晶原理及程序电路图

12864液晶原理及程序电路图

12864液晶原理+程序+ 照片+电路图一;12864(带字库汉字显示演示程序);*************************************************************************** ;* sxj1974@ (51c51 test web) *;* Create by :石学军 更多例程请登陆网站 *;***************************************************************************RS EQU P2.0RW EQU P2.1E EQU P2.2PSB EQU P2.3RST EQU P2.5;-----------------------------------------------LCD_X EQU 30HLCD_Y EQU 31HCOUNT EQU 32HCOUNT1 EQU 33HCOUNT2 EQU 34HCOUNT3 EQU 35H;----------------------------------------------- LCD_DATA EQU 36HLCD_DATA1 EQU 37HLCD_DATA2 EQU 38HSTORE EQU 39H;----------------------------------------------- ORG 0000HLJMP MAINORG 0100H;----------------------------------------------- MAIN:MOV SP,#5FHCLR RST ;复位LCALL DELAY4SETB RSTNOPSETB PSB ;通讯方式为8位数据并口;********************初始化********************** LGS0: MOV A,#34H ;34H--扩充指令操作LCALL SEND_IMOV A,#30H ;30H--基本指令操作LCALL SEND_IMOV A,#01H ;清除显示LCALL SEND_IMOV A,#06H ;指定在资料写入或读取时,光标的移动方向LCALL SEND_I ;DDRAM 的地址计数器(AC)加1MOV A,#0CH ;开显示,关光标,不闪烁LCALL SEND_I;=============================================== TU_PLAY1:MOV DPTR,#TU_TAB1 ;显示图形LCALL PHO_DISPLCALL DELAY3;================================================= ;;显示汉字和字符;加入80ms的延时,使你能够看清楚显示的过程;根据汉字显示坐标分段写入(顺序写入);================================================= HAN_WR2:LCALL CLEAR_PHAN_WR2A:MOV DPTR,#TAB1A ;显示汉字和字符MOV COUNT,#10H ;地址计数器设为16。

12864液晶的说明

12864液晶的说明

液晶12864(KS0108主控)12864市面上比较流行的有两种,一种是以KS0108为主控芯片的,不带字库的,说白了就是只能靠打点才能显示出字符或图形的,当然要借助取模软件;另一种是以ST7920为主控芯片的,带ASCII码和中文字库。

至于两种的区别下一篇再讨论,这篇先讲述KS0108为主控芯片的12864的原理。

这是网上找的一个管脚图,当然不同品牌的可能略有差异,但是主要的还是一样的重点要讲一下CS1和CS2,KS0108控制的12864内部有两个控制器,分别控制左半屏和右半屏,如下图所示左半屏和右半屏操作时写的地址其实是一样的,那么只能通过片选CS1和CS2来选择哪半个屏了,如果两个都选通,则相当于两块64x64的液晶了,而且显示的内容是一样的,取模方式是纵向8点下高位。

好了,来说下原理,列的范围是0~63,我已经标出了,行是不能按位来写的,而是写“页”,一个页相当于8个点,也就是8位,即一个字符,高位在下面,那么页的范围是0~7,共8页,8页x8个点正好64个点。

这是我用取模软件截的一个“们”字,可以看出它是16x16大小的,实际上占用了两个“页”,16个列,而我们操作时先固定一个页,比如这个就先写上面那页,假设为n好了,从列0写到16,然后页n+1,再从列0写到16,这样一个“们”字就出来了,下面是其代码0x40,0x20,0xF8,0x07,0x00,0xF8,0x02,0x04, 0x08,0x04,0x04,0x04,0x04,0xF E,0x04,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F ,0x00,0x00,可见16x16的字符占了32个字节(上面n页16个字节加n+1页16个),那么如果一幅满幅的图片,就是128x64,占用128x8=1K个字节,可见还是非常占空间的。

LCD12864原理与应用

LCD12864原理与应用

LCD12864原理与应用1、LCD12864简介:LCD12864分为两种,带字库的和不带字库的,不带字库的液晶显示汉字的时候可以选择自己喜欢的字体。

而带字库的液晶,只能显示GB2312字体,当然也可以显示其他的字体,不过是用图片的形式显示。

下面介绍不带字库的LCD12864,以Proteus中的AMPIRE128×64为例,如下图所示,它的液晶驱动器为KS0108。

引脚功能:引脚符号状态引脚名称功能,输入芯片片选端,都是低电平有效CS1=0开左屏幕,CS1=1关左屏幕CS2=0开右屏幕,CS2=1关右屏幕RS输入数据/命令选择信号RS=1为数据操作,RS=0为写指令或读状态RW输入读写选择信号R/W=1为读选通,R/W=0为写选通E输入读写使能信号在E下降沿,数据被锁存(写)入液晶,在E高电平期间,数据被读出DB0—DB7三态数据总线数据或指令的传送通道输入复位信号,低电平时复位复位时,关闭液晶显示,使显示起始行为0,可以跟单片机的复位引脚RST相连,也可以直接接VCC,使之不起作用V0液晶显示器驱动电压-Vout-10V LCD驱动负电压与带字库的液晶不同,此块液晶含有两个液晶驱动器,每块驱动器都控制64*64个点,分为左右两个屏幕显示,总共为128*64个点(即有128×64个点)。

这就是为什么AMPIRE128*64有CS1和CS2两个片选端的原因。

此液晶有8页,一页有8行点阵点,左右各64列,共128列。

如下图所示:2、LCD12864中的几条重要指令(一)行(line)设置命令:由此可见显示的起始行地址为0XC0,共64行,有规律地改变起始行号,可以实现滚屏效果。

(二)页(page)设置指令:起始页地址为0XB8,因为液晶有64行点,分为8页,每页就有8行点。

(三)列(column)地址设置指令每块驱动器的列地址都是从0X40到0X7F,共64列,所以此液晶共有128列点。

LCD12864绘图之KS0108(1)

LCD12864绘图之KS0108(1)

LCD12864(KS0108)之绘图篇(一)写给无字库液晶(KS0108芯片)使用之初学者也许你见过12864LCD 的各种显示方案,也见过字库型液晶(ST7920)的绘图功能。

但要说到可以直接在PROTEUS 中进行软件仿真的Ampire128x64 的绘图功能,情况就不同了。

因为由KS0108芯片控制的Ampire128x64液晶屏,可以在Proteus 中进行软件仿真,这对于初学单片机的人,无疑是成本低廉,效果直观,而且易于操作,配合Keil 编译器,对程序的编写和修改,非常得心应手. Ampire128x64 是无字库点阵液晶屏, 相关使用说明主要体现了它的显示功能,甚至说它只能用显示编码数据。

如编码的汉字,数字,字母,符号,以及图片......而它的绘图功能却只字不提,乃至很多人认为Ampire128x64液晶屏根本不能直接绘制几何图形。

尽管网络上有一些关于Ampire128x64绘图程序的说法,但实际却是用于ST7920驱动的字库型液晶屏的,而在大海橡树的百度空间里出现过Ampire128x64绘图显示的图片,但程序也是一字不外漏。

本人经过近两月的潜心钻研,终于解开了Ampire128x64绘图的瓶颈,尽管走了不少弯路,却很值得。

使用Ampire128x64绘图,关键是点坐标的确定及画点函数的编写,正如有人说:"给我一个画点函数,我可以描绘整个世界". Ampire128x64绘图的瓶颈, 一在于它的扫描结构和ST7920不同,二在于KS0108无专门的绘图扩充指令. 本文针对初学LCD12864的遇到的问题,予以详细讲解,以期能对他们有所帮助。

内容不多,但仍将其分成几个小节进行讲解,以便让初学者有足够的时间进行学习和消化。

凯里市第一中等职业技术学校 电子应用技术高级教师 杨正富 2014-2-4 晚20:10 先上几张图:C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18LCAMPIRE12864C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18LCAMPIRE12864C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18AMPIRE12864。

LCD12864液晶的使用之字库型液晶(二)

LCD12864液晶的使用之字库型液晶(二)
Read_H=ReadByte(); //读高8位
Read_L=ReadByte(); //读低8位
write_LCD_command(ROW+0x80); //送入垂直地址
write_LCD_command(xlabel+0x80);//再送入水平地址
if(xlabel_bit<8)
{
switch(color)
address++;//指针地址指向下个位置
}
}
}
还有一点要注意的就是显示图片和显示ASCII码、汉字的初始化函数不同,显示图片用的是扩展指令:
void init_BMP()
{
write_LCD_command(0x36);//CL=1--8位。扩充指令(RE=1),绘图打开(G=1)
delay(100);//适当延时
下面这个显示温度曲线:
这两个的仿真图大家可以做一下!
/echoas/blog/item/525d2f74bc735508b151b92d.html
{
ROW=y;
}
else//显示的是下半屏
{
ROW=y-32;
xlabel+=8; //规定显示在下半屏
}
write_LCD_command(ROW+0x80); //送入垂直地址
write_LCD_command(xlabel+0x80);//再送入水平地址
ReadByte();//读取当前GDRAM数据前腰进行一次空读,接下来就可以读出数据了
break;
default:break;
}
write_LCD_data(Read_H);//将数据写入GDRAM

MSP430驱动12864-3图形点阵液晶(KS0108)

MSP430驱动12864-3图形点阵液晶(KS0108)

微控论坛原创主贴作者:zhangfuqiang82#include <MSP430x14x.h>//***************数据类型定义****************************#define uint unsigned int#define uchar unsigned char//***************液晶控制线定义****************************#define RS BIT1 //P3.1#define RW BIT0 //P3.0#define E BIT7 //P2.7#define CS1 BIT3 //P3.3#define CS2 BIT2 //P3.2#define RST BIT1 //P2.1//数据线:p4口//**************汉字定义为16*16,纵向,大小10,D0--D7 ,字体Times NewRoman******* *******const unsigned char code1[]={64,66,66,66,254,66,66,66,66,254,66,67,98,64,0,0,32,32,16,8,7,0,0, 0,0,63,0,0,0,0,0,0};//开const unsigned char code2[]={8,8,248,15,8,248,32,48,44,35,32,40,48,96,0,0,32,17,10,4,10,17,0, 63,17,17,17,17,63,0,0,0};//始const unsigned char code3[]={8,8,136,255,72,72,4,4,4,4,252,4,6,4,0,0,1,17,32,31,0,0,0,0,16,32,3 1,0,0,0,0,0};//打const unsigned char code4[]={0,252,68,68,66,67,2,0,252,4,4,4,252,0,0,0,0,15,8,4,4,2,2,0,63,0,2, 4,3,0,0,0};//印const unsigned char code5[]={4,4,132,196,52,12,23,20,20,212,52,20,6,4,0,0,2,1,0,63,0,1,1,17,33, 31,1,1,1,1,0,0};//存const unsigned char code6[]={64,32,248,7,64,204,32,40,168,255,168,176,172,32,0,0,0,0,63,0,0, 31,10,1,63,20,20,20,63,0,0,0};//储const unsigned char code7[]={16,97,134,64,254,2,250,2,254,0,252,0,255,0,0,0,2,62,1,32,19,8,7, 8,51,0,19,32,31,0,0,0};//测const unsigned char code8[]={0,32,32,190,170,170,170,170,170,170,170,191,34,32,0,0,0,32,40, 47,42,42,42,63,42,42,42,47,40,32,0,0};//量const unsigned char code9[]={32,33,230,0,128,136,136,255,136,136,255,136,136,136,0,0,16,8,7, 8,16,40,36,35,32,32,47,32,32,32,0,0};//进const unsigned char code10[]={16,136,68,227,24,32,34,34,34,34,226,35,50,32,0,0,1,0,0,63,0,0,0, 0,16,32,31,0,0,0,0,0};//行const unsigned char code11[]= {0,248,8,8,8,8,255,8,8,8,8,252,8,0,0,0,0,1,1,1,1,1,63,1,1,1,1,1,0, 0,0,0};//中const unsigned char code12[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,8,0,0,0,0,0,0};//点const unsigned char code100[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32};//线//******************函数声明*******************************void Init_Clock(void);void Init_IO(void);void Init_LCD (void);void delay (uint us);void delayl(uint ms);void WriteCommand_L (uchar com1);void WriteCommand_R (uchar com2);void WriteData_L (uchar dat1);void WriteData_R(uchar dat2);void ClearScreen(void);void AllScreen(void);void StateCheck(void);void WriteWord(uchar colum,uchar page, const uchar *code);void DrawLine(void);//*************系统主程序********************************** void main( void ){WDTCTL=WDTPW+WDTHOLD; //关闭看门狗Init_Clock();Init_IO();Init_LCD ();WriteWord(0,6, code1);WriteWord(16, 6, code2);WriteWord(48, 6, code3);WriteWord(64, 6, code4);WriteWord(96,6, code5);WriteWord(112, 6, code6);WriteWord(16, 2, code7);WriteWord(32, 2, code8);WriteWord(48, 2, code9);WriteWord(64, 2, code10);WriteWord(80, 2, code11);WriteWord(96, 2, code12);DrawLine();}//**********************IO初始化*************************** void Init_IO(void){P1DIR=0; //设置为输入P1SEL=0; //设置为一般IOP1OUT=0X00;P2DIR=0;P2SEL=0;P2OUT=0X00;P3DIR=0;P3SEL=0;P3OUT=0X00;P4DIR=0;P4SEL=0;P4OUT=0X00;P5DIR=0;P5SEL=0;P5OUT=0X00;P6DIR=0;P6SEL=0;P6OUT=0X00;}//*****************高频时钟初始化************************** void Init_Clock(void){//UTCTL1 = SSEL0;// BCSCTL1=0X00;//BCSCTL2=0X00;unsigned int iq0;BCSCTL1&=~XT2OFF; //打开XT2振荡器do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2=SELM_2+SELS; //选择MCLK、SMCLK为XT2, BCSCTL2|=DIVM_2; //MCLK 4分频MCLK=2MHZ BCSCTL2|=DIVS_2; //SMCLK 4分频SMCLK=2MHZ }//***************延时子程序****************************** void delay (uint us){while(us--);}void delayl (uint ms){uint i,j;for(i=0;i<ms;i++)for(j=0;j<1000;j++);}//*****************状态检查********************************* void StateCheck(void){ uchar cradd1;P3OUT&=~RS;P3OUT|=RW; //RS=0,R/W=1,以便读液晶状态P4DIR=0x00; //P4口为输入口do{P2OUT|=E; //E=1cradd1=P4IN;P2OUT&=~E; //E=0}while((cradd1&0x80)!=0);}//***************写指令代码子程序(左)******************* void WriteCommand_L (uchar com1){ P3OUT&=~CS1; //cs1=0P3OUT|=CS2; //cs2=1 选择左半屏StateCheck(); //检查是否忙P3OUT&=~RW; //rw=0P4DIR=0xff; //P4口为输出口P4OUT=com1;P2OUT|=E; //E=1P2OUT&=~E; //E=0}//*****************写指令代码子程序(右)******************* void WriteCommand_R (uchar com2){ P3OUT|=CS1; //cs1=1P3OUT&=~CS2; //cs2=0StateCheck(); //检查是否忙P3OUT&=~RW; //rw=0P4DIR=0xff; //P4口为输出口P4OUT=com2;P2OUT|=E; //E=1P2OUT&=~E; //E=0}//****************写显示数据子程序(左)********************** void WriteData_L (uchar dat1){P3OUT&=~CS1; //cs1=0P3OUT|=CS2; //cs2=1StateCheck(); //检查是否忙P3OUT|=RS; //rs=1P3OUT&=~RW; //rw=0P4DIR=0xff; //P4口为输出口P4OUT=dat1;P2OUT|=E; //E=1P2OUT&=~E; //E=0}//****************写显示数据子程序(右)********************** void WriteData_R(uchar dat2){P3OUT|=CS1; //cs1=1P3OUT&=~CS2; //cs2=0StateCheck(); //检查是否忙P3OUT|=RS; //rs=1P3OUT&=~RW; //rw=0P4DIR=0xff; //P4口为输出口P4OUT=dat2;P2OUT|=E; //E=1P2OUT&=~E; //E=0}//******************清屏************************void ClearScreen(void){ uchar i,j;for(i=0;i<8;i++){ WriteCommand_L(i|0xb8); //设置页地址WriteCommand_R(i|0xb8);WriteCommand_L(0x40); //设置列地址WriteCommand_R(0x40);for(j=0;j<64;j++) //写0x00{ WriteData_L(0x00);WriteData_R(0x00);}}}//******************满屏************************void AllScreen(void){ uchar i,j;for(i=0;i<8;i++){ WriteCommand_L(i|0xb8); //设置页地址WriteCommand_R(i|0xb8);WriteCommand_L(0x40); //设置列地址WriteCommand_R(0x40);for(j=0;j<64;j++) //写0xff{ WriteData_L(0xff);WriteData_R(0xff);}}}//****************LCD初始化****************************** void Init_LCD (void){P2DIR|=BIT1; //P2.7为输出口P2OUT&=~RST; //RST=0,LCD复位delayl(50); //延时P2OUT|=RST; //rst=1delayl(50);P3DIR|=BIT3; //P3.3为输出口P3OUT&=~CS1; //CS1=0P3DIR|=BIT2; //P3.2为输出口P3OUT&=~CS2; //CS2=0P3DIR|=BIT1; //P3.1为输出口P3OUT&=~RS; //RS=0P3DIR|=BIT0; //P3.0为输出口P3OUT&=~RW; //RW=0P2DIR|=BIT7; //P2.7为输出口P2OUT&=~E; //E=0WriteCommand_L(0xc0);WriteCommand_R(0xc0); //显示开始行WriteCommand_L(0x3f);WriteCommand_R(0x3f); //开显示ClearScreen();}//***********************写汉字*********************************void WriteWord (uchar colum,uchar page, const uchar *code)//page2:页 colum2:列 code 2:字代码{uchar i,j,colum0;uchar flag;for(j=0;j<2;j++){ WriteCommand_L(page|0xb8); //页WriteCommand_R(page|0xb8);colum0=colum;if(colum0>63) //右屏{ colum0=colum0-64;WriteCommand_R(colum0|0x40);flag=1;}else //左屏{WriteCommand_L(colum0|0x40);flag=0;}//*********************for(i=0;i<16;i++){if(flag==0){WriteData_L(*code);}else{WriteData_R(*code);}code++;if(colum0==64) //列=64{colum0=0;if(flag==0){flag=1;WriteCommand_R(colum0|0x40);}else{break;}}// colum++;}page++;}}//*******************画线*********************************void DrawLine(void){uchar i,j=0;for(i=0;i<8;i++){WriteWord(j,4,code100);j+=16;}}调试日记:8月19日;出现问题:液晶无法正常显示。

LCD12864的原理分析以及使用方法(含代码分析)

LCD12864的原理分析以及使用方法(含代码分析)

LCD12864液晶显示模块的使用与分析(函代码分析)一、LCD12864功能应用LCD12864液晶显示模块能显示中文汉字、数字、字符,能显示数字与字符的个数为64个(4行,每行16个数字或字符),能显示汉字的个数为32个(4行,每行8个汉字)。

其内置了8192个中文汉字(16*16的点阵)、128个字符(8*16点阵)、以及64*256 点阵显示RAM(GDRAM)。

图1外观尺寸图图2外观尺寸图图3 LCD12864读操作时序图4 LCD12864写操作时序二、LCD12864主要技术参数(1)工作电压:3.3V-5.5V,模块最佳电压为5V。

(2)可以在显示界面显示数字、字母和中文汉字。

(3)与外部单片机的通信方式有并行或串行两种通信方式,这里主要介绍并行通信方式。

(4)显示内容:128 列× 64 行(5)显示颜色:黄绿/蓝屏/灰屏(6)LCD 类型:STN(7)与MCU 接口:8 位或4 位并行/3 位串行(8)配置LED 背光(9)多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等三、LCD12864液晶显示的电路用法分析图5 LCD12864电路连接图图6 LCD12864电路连接图LCD12864模块主要用来显示所要的界面信息或数据,所以要求能显示汉字,字符和数字,而LCD12864满足系统要求的显示功能。

LCD12864在显示字母和数字时,是4*16的显示字符模块,即可以显示4行,每行可以显示16个字母或数字;在显示汉字时,是4*8的汉字显示模块,即可以显示4行,每行可以显示8个汉字。

下面进行介绍的是并行通信的显示方式。

按照电路原理图跟单片机最小系统进行连线,如图6所示。

LCD12864共有20个引脚,其引脚具体功能如表1所示,由表可得LCD12864引脚组成为8位数据传输端口(DB0-DB7);两个电源引脚(VCC,GND);两个电源背光引脚(BLK,BLA),控制LCD的背景亮度;一个VO引脚,外接一个上拉电阻(控制LCD12864的字符对比度,让字符更加的清晰可见);RST复位引脚,低电平有效,此处直接接高电平;第16、17位空引脚,不用管;剩下的RS,RW,EN 和PSB四个引脚则跟LCD12864的写入息息相关,通过PSB可以控制LCD12864跟单片机的通信方式,输入高电平,则LCD12864跟单片机的通信模式为并行通信,低电平则为串行通信。

LCD12864液晶显示器中文说明.

LCD12864液晶显示器中文说明.

一、液晶显示模块概述12864A-1汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。

主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压);显示内容:128列× 64行显示颜色:黄绿显示角度:6:00钟直视LCD类型:STN与MCU接口:8位或4位并行/3位串行配置LED背光多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等二、外形尺寸1.外形尺寸图2.主要外形尺寸二、模块引脚说明逻辑工作电压(VDD):4.5~5.5V电源地(GND):0V工作温度(Ta):0~60℃(常温) / -20~75℃(宽温)三、接口时序模块有并行和串行两种连接方法(时序如下):8位并行连接时序图MPU写资料到模块MPU从模块读出资料2、串行连接时序图串行数据传送共分三个字节完成:第一字节:串口控制—格式11111ABCA为数据传送方向控制:H表示数据从LCD到MCU,L表示数据从MCU到LCDB为数据类型选择:H表示数据是显示数据,L表示数据是控制指令C固定为0第二字节:(并行)8位数据的高4位—格式DDDD0000第三字节:(并行)8位数据的低4位—格式0000DDDD串行接口时序参数:(测试条件:T=25℃VDD=4.5V)四、用户指令集备注:1、当模块在接受指令前,微处理顺必须先确认模块内部处于非忙碌状态,即读取BF标志时BF需为0,方可接受新的指令;如果在送出一个指令前并不检查BF标志,那么在前一个指令和这个指令中间必须延迟一段较长的时间,即是等待前一个指令确实执行完成,指令执行的时间请参考指令表中的个别指令说明。

2、“RE”为基本指令集与扩充指令集的选择控制位元,当变更“RE”位元后,往后的指令集将维持在最后的状态,除非再次变更“RE”位元,否则使用相同指令集时,不需每次重设“RE”位元。

KS0108+控制器系列液晶模块使用说明书

KS0108+控制器系列液晶模块使用说明书

9) 12864-18
4-? 2.5PAD 4-? 5.0PTH
75.0± 0.3 70.6± 0.2
70.0 60.0(V.A)
55.01(A.A)
MAX12.5 8.5± 0.3
0.4 A
128x64 DOTS
54.7± 0.3 49.7
44.6± 0.2 32.6(V.A) 27.49(A.A)
2) 12832-3
10.0
@2.54*17=43.18
? 1.0
4-? 2.5
18
1
MAX14.5 10.0± 0.3
0.52
65.0± 0.3 61.0
42.0± 0.2 25.0(V.A)
18.19(A.A)
2.0 9.1 17.6 21.01
72.91(A.A) 76.0(V.A) 97.0± 0.2
DB0
R/W
DB0
DB0
DB3
DB7
8
R/W
CS
DB1
E
DB1
DB1
DB4
DB6
9
CS
DB7
DB2 DB0 DB2
DB2
DB5
DB5
10 /RST
DB6
DB3 DB1 DB3
DB3
DB6
DB4
11 DB0
DB5
DB4 DB2 DB4
DB4
DB7
DB3
12 DB1
DB4
DB5 DB3 DB5
DB5
/CS1
105.0 110.0± 0.3
0.05 1.60
3 深圳汉昇实业有限公司 SHENZHEN HANSHENG INDUSTRIAL CO.,LTD

液晶屏内核KS0108显示源程序

液晶屏内核KS0108显示源程序
#define read_state_addr_1 XBYTE[0x7ffe] //读状态地址左
#define write_data_addr_1 XBYTE[0x7ffd] //写数据地址左
#define write_cmd_addr_2 XBYTE[0xbffc] //写指令地址右
*/
#include<reg52.h>
#inclቤተ መጻሕፍቲ ባይዱde<intrins.h>
#include<absacc.h>
#define uint unsigned int
#define uchar unsigned char
#define write_cmd_addr_1 XBYTE[0x7ffc] //写指令地址左
write_data_addr_2=dis_data;
}
//清内存左
void clear_1()
{uchar i;
uchar k;
for(i=0;i<8;i++)
{ write_cmd_1(0xb8+i);
for(k=0;k<64;k++)
{write_cmd_1(0x40+k);
},
{
0x80,0x40,0x20,0xF8,0x07,0x02,0x00,0x00,
0xFF,0xC0,0x60,0x30,0x1C,0x08,0x00,0x00,
0x00,0x00,0x00,0x7F,0x00,0x04,0x02,0x01,
0x3F,0x40,0x40,0x40,0x40,0x78,0x00,0x00/*"化",8*/

ks0107_ks0108_液晶12864控制命令

ks0107_ks0108_液晶12864控制命令

128×64点阵型LCD屏幕显示与DD RAM地址映射关系 Y1 Y2 Y3 Y4 Y61 Y62 Y63 Y64 …… 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 …… …… …… …… …… …… …… …… …… …… …… …… …… …… …… …… 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 … DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7
P12
图11-4 总线方式
+5V
AT89S51
P0.0 P0.1 P0.2 P0.3 P0.4 P0.5 P0.6 P0.7 P2.0 P2.1 P2.2 P2.3 P2.4 P2.5 39 38 37 36 35 34 33 32 21 22 23 24 25 26

12864液晶

12864液晶

KS0108液晶12864屏的12x12汉字显示笔记2009-12-12 22:32今天要好好写写这个项目使用的12864液晶显示12x12汉字的驱动体会!先上几个原理图片,便于后面分析使用.我就是这样分析实现的!先说说图1: 这是KS0108/KS0107芯片组成12864液晶屏的显示方式:点阵纵向取模,字节倒序(低位在前--上,高位在后--下).比如取得的字节是0xAB既二进制表示为:1010,1011,显示时的位排列对应液晶屏从上到下依次是:1101,0101.ASCII码纵向上半个字6个字节,汉字是12个字节,下半个字也是6个和12个字节. 先写上半个字,再写下半个字. 这就是图1 显示的液晶显示原理!再来看图2:这是说明使用该型液晶显示5行汉字时的组成情况.以及液晶屏分页情况,每页8行(0~7),一屏8页(0~7),可以看出,要显示5行汉字,就必须跨行才能实现.可是该液晶的驱动并没有相关命令.只有自己写驱动了.在0行写汉字时,已经占用了1页的前4行,如果再写1页就会覆盖掉上一行的下半个字(严格说是下4位内容),如果写2页,就不能实现5行显示.所以第2行汉字必须写1页.为了不影响上一行的汉字,就要先读出1页的对应列的字节值( BYTEs),并对准备写入的字节(BYTEx)做处理:temp =BYTEx<<4; BYTEs |=temp; 再在原地写入字节BYTEs; 依次循环6(ASCII 码)或12(汉字)次,完成1页(就是第2行汉字的上半部分).这时候,第2行汉字的下半部分,也要做相应的处理:1,回归列地址,行地址+1; 2,取得对应列的上次取出来的字节(BYTEx)和本次要写入的字节(BYTEb),做处理:temp =BYTEx>>4; temp2 =BYTEb<<4; temp |= temp2; 再将temp写入本次要写入的地址. 这样循环就完成第2行的显示.从图2可以看出:第0,3,6页不需要做处理,可以直接写,就是第1,4页需要做以上处理这里0,1,3,4,6对应液晶屏的0,1,2,3,4行汉字.于是又出现怎么使用这个行号的问题? 根据其对应关系,很容易找到处理办法:行号y =0,1,3,4,6对0,1,2,3,4可以这样处理,在调用函数时,还是使用0,1,2,3,4,但是在检索内码函数中,首先对y处理: temp =y/2; y =temp + y; 就得到对应的0,1,3,4,6.另外,这种处理需要单独写2个函数,分别对应ASCII码和汉字,在检索内码的函数中判断并标记,以分辨使用需要处理和不需要处理的写字函数.最后得到图3 所示结果. 的确有点麻烦! 但是,在讲求成本效率的当今,应该还是值得的!。

51单片机LCD12864绘图

51单片机LCD12864绘图

LCD12864绘图方法如下:一、绘图方法:1、使用扩展指令集并关闭绘图显示2、输入y轴坐标3、输入x轴坐标4、写入数据D15-D85、写入数据D7-D06、开绘图显示7、返回普通指令对应程序如下:LCD_write_comm(0x34);//使用扩充指令集LCD_delay();LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80+x);//x坐标起始地址LCD_delay();LCD_write_date(0x55);//写入数据D15-D8LCD_delay();LCD_write_date(0x55);//写入数据D7-D0LCD_delay();LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();程序执行效果则是第一行的第1-16个像素点会描出0x5555的二进制像素点,则后面的整个屏幕则是花屏,如果只想看到这0x5555,这几个像素点,则必须要给LCD的RAM重新赋值,也可以说是清屏,程序如下:void LCD12864_RAM_Cls(){u8 x,y;//xy坐标LCD_write_comm(0x34);//使用扩充指令集LCD_delay();for(y=0;y<32;y++){LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80);//x坐标起始地址LCD_delay();for(x=0;x<16;x++){LCD_write_date(0x00);LCD_delay();LCD_write_date(0x00);LCD_delay();}}LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();}二、坐标与显示X轴坐标设定初始值后会自动加1,取值范围0-15Y轴需要人为加1,取值范围为0-31整个屏幕分为上下屏,上屏对应坐标为x(0-7)y(0-31),下屏对应坐标为x(8-15)y(0-31)三、LCD12864图片显示代码1、Main.c#include"common.h"#include"delay.h"#include"12864.h"unsigned char code Picture[]= // 图片数据表{//此处添加图片取模16进制码共1024Byte,取模方式:从左到右从上到下0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x06,0x30,0x01,0xE0,0x00,0x00,0x2A,0x00,0x00,0xD8,0x00,0x00,0x00,0x00,0x01,0x80,0x0F,0x7B,0x63,0xE0,0x00,0x00,0x22,0x00,0x01,0x24,0x00,0x00,0x00,0x00,0x01,0x80,0x0D,0xDB,0x63,0x01,0xBC,0x00,0x08,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x1B,0x63,0x07,0xB0,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x01,0x80,0x0C,0x1B,0x63,0xED,0xB0,0xDB,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x19,0xE1,0xE7,0xB0,0xDB,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x19,0xE1,0xE7,0xB0,0xDB,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x03,0xC0,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x80,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x0A,0x00,0x00,0xFF,0xF8,0xE0,0x05,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x06,0xC0,0x15,0x00,0x1F,0xFF,0xFF,0xC0,0x02,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x09,0x20,0x11,0x00,0xFB,0xFF,0xE1,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x08,0x20,0x0A,0x03,0x9F,0x00,0x9E,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x04,0x40,0x04,0x0E,0x70,0x00,0x81,0xC7,0x80,0x01,0x40,0x00,0x00,0x00,0x01,0x80,0x02,0x80,0x00,0x1D,0x80,0x00,0xE0,0x61,0xE0,0x02,0xA0,0x00,0x00,0x00,0x01, 0xC0,0x01,0x00,0x00,0x77,0x9F,0xFC,0xF0,0x18,0xF8,0x02,0x20,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x01,0xDF,0x00,0x00,0xF3,0x0C,0x3C,0x01,0x40,0x00,0x00,0x00,0x01, 0xC0,0x00,0x00,0x03,0x9E,0x00,0x00,0xF8,0x06,0x1E,0x00,0x80,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x07,0x0E,0x30,0x01,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x07,0x0E,0x30,0x01,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xC0,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x0F,0xFD,0xFF,0xFF,0xFF,0xFF,0xFC,0x01,0xF0,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x3F,0x81,0xFF,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0xFE,0xF0,0x00,0x00,0x01,0x00,0x00,0xC0,0x1C,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0xC0,0x07,0x80,0x00,0x03,0xE0,0x07,0x00,0x1C,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x80,0x03,0x60,0x00,0x03,0xE0,0x0C,0x00,0x0E,0x00,0x00,0x00,0x00,0x01,0x80,0x07,0x00,0x00,0xC0,0x00,0x00,0x20,0x18,0x00,0x07,0x00,0x00,0x00,0x00,0x01,0x80,0x09,0x01,0x80,0x60,0x00,0x00,0x20,0x73,0x9F,0x03,0x80,0x00,0x00,0x00,0x01,0x80,0x1E,0x0F,0xF2,0x20,0x00,0x00,0x20,0x67,0xFF,0xC1,0xC0,0x00,0x00,0x00,0x01, 0x80,0x1E,0x1F,0xF9,0x30,0x00,0x00,0x20,0xEF,0xFF,0xE0,0xE0,0x00,0x00,0x00,0x01, 0x80,0x38,0x3F,0xFC,0x90,0x00,0x00,0x20,0xCB,0xFF,0xF9,0xF0,0x00,0x00,0x00,0x01, 0x80,0x7F,0x7F,0xFE,0x10,0x00,0x00,0x20,0xDB,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x01, 0x80,0x6E,0xF9,0xBF,0x10,0x00,0x00,0x20,0xF7,0xED,0xFF,0xF0,0x00,0x00,0x00,0x01, 0x80,0x7C,0xFC,0x3F,0x10,0x00,0x00,0x20,0x67,0xE1,0xFD,0xE0,0x00,0x00,0x00,0x01, 0x80,0x7C,0xFC,0x3F,0x10,0x00,0x00,0x20,0x67,0xE1,0xFD,0xE0,0x00,0x00,0x00,0x01, 0x80,0x38,0xFC,0x3F,0x18,0x00,0x00,0x20,0x87,0xE0,0xFD,0xC0,0x00,0x00,0x00,0x01, 0x80,0x38,0xF1,0x8F,0x18,0x00,0x1F,0xE7,0x87,0x9C,0x7D,0xC0,0x00,0x00,0x00,0x01, 0x80,0x1C,0xFE,0x1F,0x81,0xFF,0xFF,0xC0,0x0F,0xE0,0xFF,0x80,0x00,0x00,0x00,0x01, 0x80,0x0C,0xFC,0x3F,0x80,0x00,0x00,0x00,0x0F,0xE1,0xF8,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0xF9,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xFE,0x00,0x00,0x00,0x00,0x01, 0x80,0x03,0xF9,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x01, 0x80,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE0,0x00,0x00,0x00,0x60,0x00,0x00,0x01,0xC0,0x02,0x80,0x00,0x00,0x00,0x1C,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };void main(){LCD12864_init();//LCD初始化//LCD12864_RAM_Cls();LCD_Picture_show(Picture);while(1);}2、common.h#ifndef __COMMON_H#define __COMMON_H#include<STC12C5A60S2.h>#include "intrins.h"#define u8 unsigned char//无符号字符型#define u16 unsigned int//无符号整型#endif3、delay.h#ifndef __DELAY_H#define __DELAY_H#include "common.h"#define MAIN_Fosc 24000000L //定义主时钟void delay_ms(u16 ms);void LCD_delay();//LCD延时函数#endif4、delay.c#include "delay.h"//-------毫秒延时函数---------------void delay_ms(u16 ms){u16 i;do{i = MAIN_Fosc / 13000;while(--i) ; //14T per loop }while(--ms);}//------LCD延时函数-----------------void LCD_delay(void){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}5、12864.h#ifndef __12864_H#define __12864_h#include "common.h"sbit CS =P1^1;//片选sbit SID=P1^2;//数据口sbit CLK=P1^3;//同步时钟void LCD_write_spi(u8 date);//LCD SPI数据写入void LCD_write_comm(u8 comm);//LCD写指令void LCD_write_date(u8 date);//LCD写数据void LCD12864_init();//LCD初始化void LCD12864_RAM_Cls();//RAM清屏void LCD_print(u8 *date);//LCD字符串显示void LCD_Picture_show(u8 *date);#endif6、12864.c#include"common.h"#include"delay.h"#include"12864.h"//------LCD SPI数据写入--------------------void LCD_write_spi(u8 date){u8 i;for(i=0;i<8;i++){CS=1;if(date&0x80){SID=1;}else{SID=0;}date <<= 1;CLK=1;LCD_delay();CLK=0;}}//------LCD写指令--------------------void LCD_write_comm(u8 comm){u8 date = 0xf8;//串行写入指令到LCD(数据手册)u8 comm_H = comm&0xf0;u8 comm_L = comm<<4;CS =0;CLK=0;SID=0;LCD_delay();LCD_write_spi(date);LCD_write_spi(comm_H);LCD_write_spi(comm_L);CS=0;}//------LCD写数据-----------------------void LCD_write_date(u8 date){u8 date2 = 0xfa;//串行写入指令到LCD(数据手册)u8 date_H = date&0xf0;u8 date_L = date<<4;CS =0;CLK=0;SID=0;LCD_delay();LCD_write_spi(date2);LCD_write_spi(date_H);LCD_write_spi(date_L);CS=0;}//-----LCD初始化--------------------------void LCD12864_init(){LCD_write_comm(0x01);//清屏幕delay_ms(1);LCD_write_comm(0x0c);//开显示,游标显示关闭LCD_delay();LCD_write_comm(0x81);//设定坐标LCD_delay();}//-----写RAM清屏--------------------------void LCD12864_RAM_Cls(){u8 x,y;//xy坐标LCD_write_comm(0x34);//使用扩充指令集LCD_delay();for(y=0;y<32;y++){LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80);//x坐标起始地址LCD_delay();for(x=0;x<16;x++){LCD_write_date(0x00);LCD_delay();LCD_write_date(0x00);LCD_delay();}}LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();}//----LCD字符串显示-----------------------void LCD_print(u8 *date){u8 j=0;while(date[j]!='\0'){LCD_write_date(date[j]);j++;LCD_delay();}}//----图片显示-----------------------------void LCD_Picture_show(u8 *date){u8 x,y;//xy坐标LCD_write_comm(0x34);//使用扩充指令集LCD_delay();for(y=0;y<32;y++){LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80);//x坐标起始地址LCD_delay();for(x=0;x<8;x++)//写上半屏幕{LCD_write_date(date[16*y+x*2]);LCD_delay();LCD_write_date(date[16*y+x*2+1]);LCD_delay();}for(x=0;x<8;x++)//写下半屏幕{LCD_write_date(date[16*(y+32)+x*2]);LCD_delay();LCD_write_date(date[16*(y+32)+x*2+1]);LCD_delay();}}LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();}四、程序执行效果。

LCD12864绘图之KS0108(3)

LCD12864绘图之KS0108(3)

12864(KS0108)之绘图篇(三)常用几何图形绘制函数收集整理:杨正富(KL YZX-JDBDZZY-YZF)//画水平线: x0、x1为起始点和终点的水平坐标,y为垂直坐标void draw_Hline(uchar x0,uchar x1,uchar y,uchar color){uchar bak; //数据互换的中间变量,if(x0>x1){bak=x1;x1=x0;x0=bak;} //若x0>X1, 交换数据,使x1为大值do{draw_point(x0,y,color); //从左到右逐点显示x0++; //x0自加1}while(x1>=x0); //直到x0=x1为止}//画竖直线函数: x为起始点和终点的水平坐标,y0、y1为垂直坐标void draw_Vline(uchar x,uchar y0,uchar y1,uchar color){uchar bak; //数据互换的中间变量if(y0>y1){bak=y1;y1=y0;y0=bak;} //若y0>y1, 交换数据,使y1为大值do{draw_point(x,y0,color); //从上到下逐点显示y0++; //y0自加1}while(y1>=y0); //直到y0=y1为止}//任意两点间画直线:x0、y0为起始点坐标,x1、y1为终点坐标void draw_Rline(uchar x0,uchar y0,uchar x1,uchar y1,uchar color){int dx; //直线x轴差值变量int dy; //直线y轴差值变量char dx_sym; //x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym; //y轴增长方向,为-1时减值方向,为1时增值方向int dx_x2; //dx*2值变量,用于加快运算速度int dy_x2; //dy*2值变量,用于加快运算速度int di; //决策变量/****************************画垂直线******************************/if(x0==x1) //如果水平坐标相等,则为垂直线{if(y0>y1) //若起点大于终点{dx=y0;y0=y1;y1=dx;} //交换数据(即交换起点)for(dx=y0;dx<y1+1;dx++) //从y0到y1逐点画线{draw_point(x0,dx,color); //画点}}/****************************画水平线******************************/if(y0==y1) //如果垂直坐标相等,则为水平线{if(x0>x1) //若起点横坐标大于终点{dy=x0;x0=x1;x1=dy;} //交换数据(即交换起点)for(dy=x0;dy<x1+1;dy++) //从X0到X1逐点画线{draw_point(dy,y0,color); //画点}}/****************************画斜线******************************/dx=x1-x0; //求取两点之间的差值dy=y1-y0;if(dx>0){dx_sym=1;} //判断x轴方向:dx>0,设置dx_sym=1 else if(dx<0){dx_sym=-1;} //判断x轴方向:dx<0,设置dx_sym=-1 if(dy>0){dy_sym=1;} //判断y轴方向:dy>0,设置dy_sym=1 else if(dy<0){dy_sym=-1;} //判断y轴方向:dy<0,设置dy_sym=-1 dx=dx_sym*dx; //将dx、dy取绝对值dy=dy_sym*dy;dx_x2=dx*2; //计算2倍的dx及dy值dy_x2=dy*2;/*************使用Bresenham法进行画直线**************************/if(dx>=dy) //对于dx>=dy,则使用x轴为基准{di=dy_x2-dx;while(x0!=x1){draw_point(x0,y0,color);x0+=dx_sym;if(di<0){di+=dy_x2;} //计算出下一步的决策值else{di+=dy_x2-dx_x2;y0+=dy_sym;}}draw_point(x0,y0,color); //显示最后一点}else //对于dx<dy,则使用y轴为基准{di=dx_x2-dy;while(y0!=y1){draw_point(x0,y0,color);y0+=dy_sym;if(di<0){di+=dx_x2;}else{di+=dx_x2-dy_x2;x0+=dx_sym;}}draw_point(x0,y0,color); //显示最后一点}}//画矩形rect: 矩形起左上顶点(x0,y0);右下顶点(x1,y1)void draw_rect(int x0, int y0, int x1, int y1,uchar color){int i;if(x0>x1){i=x0;x0=x1;x1=i;}if(y0>y1){i=y0;y0=y1;y1=i;}for(i=x0;i<x1+1;i++){draw_point(i,y0,color);draw_point(i,y1,color);}for(i=y0;i<y1+1;i++){draw_point(x0,i,color);draw_point(x1,i,color);}}//画实心矩形: 矩形起左上顶点(x0,y0);右下顶点(x1,y1)void draw_rectfill(int x0, int y0, int x1, int y1,uchar color){int i,j;if(x0>x1){i=x0;x0=x1;x1=i;}if(y0>y1){i=y0;y0=y1;y1=i;}for(i=y0;i<y1+1;i++){for(j=x0;j<x1+1;j++)draw_point(j,i,color);}}//画正方形函数: x0、y0为正方形左上角坐标,with正方形边长void draw_square(uchar x0,uchar y0,uchar with,uchar color){if(with == 0)return;if((x0+with)>127)return; //横轴超出液晶边界if((y0+with)>63)return;draw_rect(x0,y0,x0+with,y0+with,color);}//画填充正方形函数: x0、y0为正方形左上角坐标,with正方形边长void draw_squarefill(uchar x0,uchar y0,uchar with,uchar color){if(with==0) return;if((x0+with)>127)return; //横轴超出液晶边界if((y0+with)> 63)return;draw_rectfill(x0,y0,x0+with,y0+with,color);}//画圆函数: 圆心坐标(x1,y1),半径rvoid draw_circle(int x1,int y1,uint r,uchar color){int x=0, y=r, d=1-r; //计算初始值while(x<=y){////////绘制点(x,y)及其在八分圆中的另外7个对称点draw_point(x1+x,y1+y,color);draw_point(x1+y,y1+x,color);draw_point(x1-y,y1+x,color);draw_point(x1-x,y1+y,color);draw_point(x1-x,y1-y,color);draw_point(x1-y,y1-x,color);draw_point(x1+y,y1-x,color);draw_point(x1+x,y1-y,color);if(d<0){d+=2*x+3;} //根据误差项d的判断,决定非最大位移方向上是走还是不走else{d+=2*(x-y)+5;y--;}x++;}}//画实心圆: 圆心坐标(x1,y1),半径rvoid draw_circlefill(int x1, int y1, uint r,uchar color){int x,y,d;x=0;y=r;d=1-r; // 计算初始值while(x<=y){// 绘制点(x,y)及其在八分圆中的另外7 个对称点draw_Rline(x1+x,y1+y,x1-x,y1+y,color);draw_Rline(x1+x,y1-y,x1-x,y1-y,color);draw_Rline(x1+y,y1+x,x1-y,y1+x,color);draw_Rline(x1+y,y1-x,x1-y,y1-x,color);if(d<0)d+=2*x+3; // 根据误差项d 的判断,决定非最大位移方向上是走还是不走else{ d+=2*(x-y)+5;y--;}x++;}}//画正椭圆函数: 给定椭圆的四个点的参数,//最左、最右点的x轴坐标值为x0、x1,最上、最下点的y轴坐标为y0、y1.void draw_ellipse(char x0, char x1, char y0, char y1,uchar color){char draw_x0, draw_y0; // 刽图点坐标变量char draw_x1, draw_y1;char draw_x2, draw_y2;char draw_x3, draw_y3;char xx, yy; // 画图控制变量char center_x, center_y; // 椭圆中心点坐标变量char radius_x, radius_y; // 椭圆的半径,x轴半径和y轴半径int radius_xx, radius_yy; // 半径乘平方值int radius_xx2, radius_yy2; // 半径乘平方值的两倍char di; // 定义决策变量//参数过滤if((x0==x1)||(y0==y1)) return;//计算出椭圆中心点坐标center_x=(x0+x1)>>1;center_y=(y0+y1)>>1;//计算出椭圆的半径,x轴半径和y轴半径if(x0>x1) radius_x=(x0-x1)>>1;else radius_x=(x1-x0)>>1;if(y0>y1) radius_y=(y0-y1)>>1;else radius_y=(y1-y0)>>1;//计算半径平方值radius_xx = radius_x * radius_x;radius_yy = radius_y * radius_y;//计算半径平方值乘2值radius_xx2 = radius_xx<<1;radius_yy2 = radius_yy<<1;//初始化画图变量xx = 0;yy = radius_y;di = radius_yy2 + radius_xx - radius_xx2*radius_y ; // 初始化决策变量//计算出椭圆y轴上的两个端点坐标,作为作图起点draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x;draw_y0 = draw_y1 = center_y + radius_y;draw_y2 = draw_y3 = center_y - radius_y;draw_point(draw_x0, draw_y0, color); // 画y轴上的两个端点draw_point(draw_x2, draw_y2, color);while( (radius_yy*xx) < (radius_xx*yy) ){if(di<0)di+= radius_yy2*(2*xx+3);else{di+=radius_yy2*(2*xx+3)+4*radius_xx-4*radius_xx*yy;yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;}xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;draw_point(draw_x0, draw_y0, color);draw_point(draw_x1, draw_y1, color);draw_point(draw_x2, draw_y2, color);draw_point(draw_x3, draw_y3, color);}di=radius_xx2*(yy-1)*(yy-1)+radius_yy2*xx*xx+radius_yy+radius_yy2*xx-radius_xx2*radius_yy; while(yy>=0){ if(di<0){ di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy;xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;}else{ di += radius_xx2*3 - 2*radius_xx2*yy;}yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;draw_point(draw_x0,draw_y0,color);draw_point(draw_x1,draw_y1,color);draw_point(draw_x2,draw_y2,color);draw_point(draw_x3,draw_y3,color);}}。

LCD12864原理与应用(源程序+原理图+proteus仿真)

LCD12864原理与应用(源程序+原理图+proteus仿真)

LCD12864原理与应用1、LCD12864简介:LCD12864分为两种,带字库的和不带字库的,不带字库的液晶显示汉字的时候可以选择自己喜欢的字体。

而带字库的液晶,只能显示GB2312字体,当然也可以显示其他的字体,不过是用图片的形式显示。

下面介绍不带字库的LCD12864,以Proteus中的AMPIRE128×64为例,如下图所示,它的液晶驱动器为KS0108。

引脚功能:引脚符号状态引脚名称功能,输入芯片片选端,都是低电平有效CS1=0开左屏幕,CS1=1关左屏幕CS2=0开右屏幕,CS2=1关右屏幕RS 输入数据/命令选择信号RS=1为数据操作,RS=0为写指令或读状态RW 输入读写选择信号R/W=1为读选通,R/W=0为写选通E 输入读写使能信号在E下降沿,数据被锁存(写)入液晶,在E高电平期间,数据被读出DB0—DB7 三态数据总线数据或指令的传送通道输入复位信号,低电平时复位复位时,关闭液晶显示,使显示起始行为0,可以跟单片机的复位引脚RST相连,也可以直接接VCC,使之不起作用V0 液晶显示器驱动电压-Vout -10V LCD驱动负电压与带字库的液晶不同,此块液晶含有两个液晶驱动器,每块驱动器都控制64*64个点,分为左右两个屏幕显示,总共为128*64个点(即有128×64个点)。

这就是为什么AMPIRE128*64有CS1和CS2两个片选端的原因。

此液晶有8页,一页有8行点阵点,左右各64列,共128列。

如下图所示:2、LCD12864中的几条重要指令(一)行(line)设置命令:由此可见显示的起始行地址为0XC0,共64行,有规律地改变起始行号,可以实现滚屏效果。

(二)页(page)设置指令:起始页地址为0XB8,因为液晶有64行点,分为8页,每页就有8行点。

(三)列(column)地址设置指令每块驱动器的列地址都是从0X40到0X7F,共64列,所以此液晶共有128列点。

128x64液晶KS0108控制器驱动程序

128x64液晶KS0108控制器驱动程序

#include "absacc.h"#include "intrins.h"//自定义库在"C:\comp51\UserLib\"文件夹中#include ".\inc\ASCII816.h" //标准ASCII库#include ".\inc\HZTable.h" //汉字点阵库(自做)#include ".\inc\Menu.h" //菜单库(自做)// LCD128*64 数据线#define LCD12864DataPort P1// LCD128*64 I/O 信号管脚sbit di =P3^1; // 数据\指令选择sbit rw =P3^3; // 读\写选择sbit en =P3^2; // 读\写使能sbit cs1 =P3^4; // 片选1,低有效(前64列)sbit cs2 =P3^5; // 片选2,低有效(后64列)sbit reset=P0^7; // 复位/*----------------------------------------------------------------------------------------------------*/ /* ****函数列表****//开关显示void SetOnOff(unsigned char onoff)//选择屏幕//screen: 0-全屏,1-左屏,2-右void SelectScreen(unsigned char screen)//清屏//screen: 0-全屏,1-左屏,2-右void ClearScreen(unsigned char screen)//显示8*8点阵//旋转90度:字模被竖着切分//lin:行(0-7), column: 列(0-15)//address : 字模区首地址void Show88(unsigned char lin,unsigned char column,unsigned int address)//显示8*16字符//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//character:字符代码(标准ASCII码)void ShowChar(unsigned char lin,unsigned char column,unsigned char character)//显示8*16字符串//!!!只能显示在一行上即: 串长+column <=15//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//address : 字模区首地址void ShowString(unsigned char lin,unsigned char column, unsigned char *string)//显示一个汉字//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//hzcode: 汉字代码(自定义的)void ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode)//显示图片//旋转90度:字模被竖着切分//startline :开始行//startcolumn:开始列//linechar :图片行点除8(图片以8*8点阵为单位)//columnchar :图片列点除8(图片以8*8点阵为单位)//address : 字模区首地址void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnchar,unsigned int address)//!!问题大户//显示一行汉字//lin:行//lineheadaddr: 此行汉字代码区首地址void ShowLine(unsigned char lin,unsigned int lineheadaddr)//显示一屏汉字//pageheadaddr:此屏汉字代码地址区首地址void ShowPage(unsigned int pageheadaddr)//反显一个8*8字块//lin:行(0-3), column: 列(0-7)void ReverseShow88(unsigned char lin,unsigned char column)//反显一个字符//lin:行(0-4), column: 列(0-15)void ReverseShowChar(unsigned char lin,unsigned char column)//反显一个汉字//lin:行(0-3), column: 列(0-7)ReverseShowHZ(unsigned char lin,unsigned char column)//反显一行汉字//lin:行ReverseShow(unsigned char lin)//初始化LCDvoid InitLCD()****函数列表结束**** *//*----------------------------------------------------------------------------------------------------*//*--基本函数源程序------------------------------------------------------------------------------------*/ //延时Lcd12864delay(){unsigned int i=500;while(i--) {;}}/*----------------------------------------------------------------------------------------------------*///状态检查void CheckState(){unsigned char dat;di=0;rw=1;do{LCD12864DataPort=0xff;en=1; dat=LCD12864DataPort; en=0;dat=0x90 & dat; //仅当第4,7位为0时才可操作}while(!(dat==0x00));}/*----------------------------------------------------------------------------------------------------*///写显示数据//dat:显示数据void WriteByte(unsigned char dat){CheckState();di=1; rw=0;LCD12864DataPort=dat;en=1; en=0;}/*-----------------------------------------------------------------------------------------------------*/ //向LCD发送命令//command :命令SendCommandToLCD(unsigned char command){CheckState();rw=0;LCD12864DataPort=command;en=1; en=0;}/*----------------------------------------------------------------------------------------------------*/ //设定行地址(页)--X 0-7void SetLine(unsigned char line){line=line & 0x07; // 0<=line<=7line=line|0xb8; //1011 1xxxSendCommandToLCD(line);}//设定列地址--Y 0-63void SetColumn(unsigned char column){column=column &0x3f; // 0=<column<=63column=column | 0x40; //01xx xxxxSendCommandToLCD(column);}//设定显示开始行--XXvoid SetStartLine(unsigned char startline) //0--63{startline=startline & 0x07;startline=startline|0xc0; //1100 0000SendCommandToLCD(startline);}//开关显示void SetOnOff(unsigned char onoff){onoff=0x3e | onoff; //0011 111xSendCommandToLCD(onoff);}/*---------------------------------------------------------------------------------------------------*///选择屏幕//screen: 0-全屏,1-左屏,2-右屏void SelectScreen(unsigned char screen){ //北京显示器:负有效cs1: 0--右; cs2: 0--左switch(screen){ case 0: cs1=0;//全屏_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();cs2=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_();break;case 1: cs1=1;//左屏_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();cs2=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();break;case 2: cs1=0;//右屏_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();cs2=1;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();break;}}/*---------------------------------------------------------------------------------------------------*///清屏//screen: 0-全屏,1-左屏,2-右void ClearScreen(unsigned char screen){ unsigned char i,j;SelectScreen(screen);for(i=0;i<8;i++){ SetLine(i);for(j=0;j<64;j++){WriteByte(0x00);}}}/*--------------------------------------------------------------------------------------------------*/ //显示8*8点阵//旋转90度:字模被竖着切分//lin:行(0-7), column: 列(0-15)//address : 字模区首地址void Show88(unsigned char lin,unsigned char column,unsigned int address) { unsigned char i;if(column>16) {return;}if(column<8) SelectScreen(1); //如果列数<8(0,1,2,3,4,5,6,7)则写在第一屏上else {SelectScreen(2); //否则(8,9,10,11,12,13,14,15)写在第二屏上column=column & 0x07; //防止越界}SetLine(lin);SetColumn(column<<3);for(i=0;i<8;i++) WriteByte( CBYTE[address+i] );}/*------------------------------------------------------------------------------------------------*///显示8*16字符//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//character:字符代码(标准ASCII码)void ShowChar(unsigned char lin,unsigned char column,unsigned char character) { lin=lin<<1;Show88(lin ,column,ASCII816[character-0x20] );Show88(lin+1,column,ASCII816[character-0x20]+8 );}/*-----------------------------------------------------------------------------------------------*//*//显示8*16字符串//!!!只能显示在一行上即: 串长+column <=15//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//address : 字模区首地址void ShowString(unsigned char lin,unsigned char column, unsigned char *string) { unsigned char ch;unsigned char i=0;while(*string!='\0'){ch=*string;if(i+column >15) break; //(只能显示在一行上即: 串长+column <=15) ShowChar(lin,i+column,ch);string++; i++;}}*//*----------------------------------------------------------------------------------------------*///显示一个汉字//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-7)//hzcode: 汉字代码(自定义的)//uchar code HZtablevoid ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode){lin=lin<<1; //lin*2Show88(lin,column,HZTable[hzcode]);Show88(lin,column+1,HZTable[hzcode]+8);Show88(lin+1,column,HZTable[hzcode]+16);Show88(lin+1,column+1,HZTable[hzcode]+24);}/*----------------------------------------------------------------------------------------------*///显示图片//旋转90度:字模被竖着切分//startline :开始行//startcolumn:开始列//linechar :图片行点除8(图片以8*8点阵为单位)//columnchar :图片列点除8(图片以8*8点阵为单位)//address : 字模区首地址void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnchar,unsigned int address){ unsigned char i,j;for(i=0;i<columnchar;i++)for(j=0;j<linechar;j++)Show88(startline+i , startcolumn+j , address+(i*linechar+j)*8 );}/*----------------------------------------------------------------------------------------------*///显示一行字符串(汉字,字母混排,一行16字节)//lin:行//lineheadaddr: 此行汉字代码区首地址void ShowLine(unsigned char lin,unsigned char linehead[]) { unsigned char i;unsigned char byte;unsigned int hzcode;for( i=0; i<16; ){ byte=linehead[i];if(byte < 0x80) //字母{if(i>15) return; //!!编译器有问题,须强制退出ShowChar(lin, i , byte);i=i+1;}else // byte >= 0x80(汉字){if(i>15) return; //!!编译器有问题,须强制退出byte=byte & 0x7f; //最高位置0,即:减去0x8000 hzcode=(unsigned int)byte<<8; //?? //高8位hzcode=hzcode+linehead[i+1]; //加低8位,组合成整型数地址ShowHZ( lin,i,hzcode);i=i+2;}}}/*----------------------------------------------------------------------------------------------------*///显示一屏汉字//pageheadaddr:此屏汉字代码地址区首地址void ShowPage(unsigned char pagehead[][16]){ unsigned char i;for(i=0;i<4;i++) ShowLine(i,pagehead[i]); //1行8个汉字,16字节}/*----------------------------------------------------------------------------------------------------*///读显示数据unsigned char ReadByte(){unsigned char dat;CheckState();di=1; rw=1;LCD12864DataPort=0xff;en=1; dat=LCD12864DataPort; en=0;return(dat);}/*----------------------------------------------------------------------------------------------------*/ //反显一个8*8字块//lin:行(0-3), column: 列(0-7)void ReverseShow88(unsigned char lin,unsigned char column){ unsigned char i;unsigned char tab[8];if(column<8) SelectScreen(1); //如果列数<4(0,1,2,3),则写在第一屏上else SelectScreen(2); //否则(4,5,6,7), 写在第二屏上//读上部8列column=column<<3; //每个方块8*8大小SetLine(lin);SetColumn(column);tab[0]=ReadByte(); //空读!!!!! //?for(i=0;i<8;i++) tab[i]=~ReadByte();//写回SetLine(lin);SetColumn(column);for(i=0;i<8;i++) WriteByte(tab[i]);}/*----------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------*/ //反显一个字符//lin:行(0-4), column: 列(0-15)void ReverseShowChar(unsigned char lin,unsigned char column){ lin=lin<<1;ReverseShow88(lin ,column);ReverseShow88(lin+1,column);}/*----------------------------------------------------------------------------------------------------*///反显一个汉字//lin:行(0-3), column: 列(0-7)ReverseShowHZ(unsigned char lin,unsigned char column){lin=lin<<1;column=column<<1;ReverseShow88(lin ,column );ReverseShow88(lin ,column+1);ReverseShow88(lin+1,column );ReverseShow88(lin+1,column+1);}/*----------------------------------------------------------------------------------------------------*/ //反显一行汉字//lin:行ReverseShow(unsigned char lin){ unsigned char i;for(i=0;i<8;i++) ReverseShowHZ(lin,i);}/*----------------------------------------------------------------------------------------------------*/ void InitLCD() //初始化LCD{ unsigned char i=250; //延时while(i--);//reset=0;//复位//reset=1;SelectScreen(0);SetOnOff(0); //关显示ClearScreen(1);//清屏ClearScreen(2);SelectScreen(0);SetOnOff(1); //开显示SelectScreen(0);SetStartLine(0); //开始行:0}/*----------------------------------------------------------------------------------------------------*/void Reset() //液晶复位{//reset 低复位_|-reset=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();reset=1;//全屏cs1=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();cs2=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); SendCommandToLCD(0x3F);}</FONT< p>。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

12864(KS0108)之绘图篇(三)常用几何图形绘制函数收集整理:杨正富(KL YZX-JDBDZZY-YZF)//画水平线: x0、x1为起始点和终点的水平坐标,y为垂直坐标void draw_Hline(uchar x0,uchar x1,uchar y,uchar color){uchar bak; //数据互换的中间变量,if(x0>x1){bak=x1;x1=x0;x0=bak;} //若x0>X1, 交换数据,使x1为大值do{draw_point(x0,y,color); //从左到右逐点显示x0++; //x0自加1}while(x1>=x0); //直到x0=x1为止}//画竖直线函数: x为起始点和终点的水平坐标,y0、y1为垂直坐标void draw_Vline(uchar x,uchar y0,uchar y1,uchar color){uchar bak; //数据互换的中间变量if(y0>y1){bak=y1;y1=y0;y0=bak;} //若y0>y1, 交换数据,使y1为大值do{draw_point(x,y0,color); //从上到下逐点显示y0++; //y0自加1}while(y1>=y0); //直到y0=y1为止}//任意两点间画直线:x0、y0为起始点坐标,x1、y1为终点坐标void draw_Rline(uchar x0,uchar y0,uchar x1,uchar y1,uchar color){int dx; //直线x轴差值变量int dy; //直线y轴差值变量char dx_sym; //x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym; //y轴增长方向,为-1时减值方向,为1时增值方向int dx_x2; //dx*2值变量,用于加快运算速度int dy_x2; //dy*2值变量,用于加快运算速度int di; //决策变量/****************************画垂直线******************************/if(x0==x1) //如果水平坐标相等,则为垂直线{if(y0>y1) //若起点大于终点{dx=y0;y0=y1;y1=dx;} //交换数据(即交换起点)for(dx=y0;dx<y1+1;dx++) //从y0到y1逐点画线{draw_point(x0,dx,color); //画点}}/****************************画水平线******************************/if(y0==y1) //如果垂直坐标相等,则为水平线{if(x0>x1) //若起点横坐标大于终点{dy=x0;x0=x1;x1=dy;} //交换数据(即交换起点)for(dy=x0;dy<x1+1;dy++) //从X0到X1逐点画线{draw_point(dy,y0,color); //画点}}/****************************画斜线******************************/dx=x1-x0; //求取两点之间的差值dy=y1-y0;if(dx>0){dx_sym=1;} //判断x轴方向:dx>0,设置dx_sym=1 else if(dx<0){dx_sym=-1;} //判断x轴方向:dx<0,设置dx_sym=-1 if(dy>0){dy_sym=1;} //判断y轴方向:dy>0,设置dy_sym=1 else if(dy<0){dy_sym=-1;} //判断y轴方向:dy<0,设置dy_sym=-1 dx=dx_sym*dx; //将dx、dy取绝对值dy=dy_sym*dy;dx_x2=dx*2; //计算2倍的dx及dy值dy_x2=dy*2;/*************使用Bresenham法进行画直线**************************/if(dx>=dy) //对于dx>=dy,则使用x轴为基准{di=dy_x2-dx;while(x0!=x1){draw_point(x0,y0,color);x0+=dx_sym;if(di<0){di+=dy_x2;} //计算出下一步的决策值else{di+=dy_x2-dx_x2;y0+=dy_sym;}}draw_point(x0,y0,color); //显示最后一点}else //对于dx<dy,则使用y轴为基准{di=dx_x2-dy;while(y0!=y1){draw_point(x0,y0,color);y0+=dy_sym;if(di<0){di+=dx_x2;}else{di+=dx_x2-dy_x2;x0+=dx_sym;}}draw_point(x0,y0,color); //显示最后一点}}//画矩形rect: 矩形起左上顶点(x0,y0);右下顶点(x1,y1)void draw_rect(int x0, int y0, int x1, int y1,uchar color){int i;if(x0>x1){i=x0;x0=x1;x1=i;}if(y0>y1){i=y0;y0=y1;y1=i;}for(i=x0;i<x1+1;i++){draw_point(i,y0,color);draw_point(i,y1,color);}for(i=y0;i<y1+1;i++){draw_point(x0,i,color);draw_point(x1,i,color);}}//画实心矩形: 矩形起左上顶点(x0,y0);右下顶点(x1,y1)void draw_rectfill(int x0, int y0, int x1, int y1,uchar color){int i,j;if(x0>x1){i=x0;x0=x1;x1=i;}if(y0>y1){i=y0;y0=y1;y1=i;}for(i=y0;i<y1+1;i++){for(j=x0;j<x1+1;j++)draw_point(j,i,color);}}//画正方形函数: x0、y0为正方形左上角坐标,with正方形边长void draw_square(uchar x0,uchar y0,uchar with,uchar color){if(with == 0)return;if((x0+with)>127)return; //横轴超出液晶边界if((y0+with)>63)return;draw_rect(x0,y0,x0+with,y0+with,color);}//画填充正方形函数: x0、y0为正方形左上角坐标,with正方形边长void draw_squarefill(uchar x0,uchar y0,uchar with,uchar color){if(with==0) return;if((x0+with)>127)return; //横轴超出液晶边界if((y0+with)> 63)return;draw_rectfill(x0,y0,x0+with,y0+with,color);}//画圆函数: 圆心坐标(x1,y1),半径rvoid draw_circle(int x1,int y1,uint r,uchar color){int x=0, y=r, d=1-r; //计算初始值while(x<=y){////////绘制点(x,y)及其在八分圆中的另外7个对称点draw_point(x1+x,y1+y,color);draw_point(x1+y,y1+x,color);draw_point(x1-y,y1+x,color);draw_point(x1-x,y1+y,color);draw_point(x1-x,y1-y,color);draw_point(x1-y,y1-x,color);draw_point(x1+y,y1-x,color);draw_point(x1+x,y1-y,color);if(d<0){d+=2*x+3;} //根据误差项d的判断,决定非最大位移方向上是走还是不走else{d+=2*(x-y)+5;y--;}x++;}}//画实心圆: 圆心坐标(x1,y1),半径rvoid draw_circlefill(int x1, int y1, uint r,uchar color){int x,y,d;x=0;y=r;d=1-r; // 计算初始值while(x<=y){// 绘制点(x,y)及其在八分圆中的另外7 个对称点draw_Rline(x1+x,y1+y,x1-x,y1+y,color);draw_Rline(x1+x,y1-y,x1-x,y1-y,color);draw_Rline(x1+y,y1+x,x1-y,y1+x,color);draw_Rline(x1+y,y1-x,x1-y,y1-x,color);if(d<0)d+=2*x+3; // 根据误差项d 的判断,决定非最大位移方向上是走还是不走else{ d+=2*(x-y)+5;y--;}x++;}}//画正椭圆函数: 给定椭圆的四个点的参数,//最左、最右点的x轴坐标值为x0、x1,最上、最下点的y轴坐标为y0、y1.void draw_ellipse(char x0, char x1, char y0, char y1,uchar color){char draw_x0, draw_y0; // 刽图点坐标变量char draw_x1, draw_y1;char draw_x2, draw_y2;char draw_x3, draw_y3;char xx, yy; // 画图控制变量char center_x, center_y; // 椭圆中心点坐标变量char radius_x, radius_y; // 椭圆的半径,x轴半径和y轴半径int radius_xx, radius_yy; // 半径乘平方值int radius_xx2, radius_yy2; // 半径乘平方值的两倍char di; // 定义决策变量//参数过滤if((x0==x1)||(y0==y1)) return;//计算出椭圆中心点坐标center_x=(x0+x1)>>1;center_y=(y0+y1)>>1;//计算出椭圆的半径,x轴半径和y轴半径if(x0>x1) radius_x=(x0-x1)>>1;else radius_x=(x1-x0)>>1;if(y0>y1) radius_y=(y0-y1)>>1;else radius_y=(y1-y0)>>1;//计算半径平方值radius_xx = radius_x * radius_x;radius_yy = radius_y * radius_y;//计算半径平方值乘2值radius_xx2 = radius_xx<<1;radius_yy2 = radius_yy<<1;//初始化画图变量xx = 0;yy = radius_y;di = radius_yy2 + radius_xx - radius_xx2*radius_y ; // 初始化决策变量//计算出椭圆y轴上的两个端点坐标,作为作图起点draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x;draw_y0 = draw_y1 = center_y + radius_y;draw_y2 = draw_y3 = center_y - radius_y;draw_point(draw_x0, draw_y0, color); // 画y轴上的两个端点draw_point(draw_x2, draw_y2, color);while( (radius_yy*xx) < (radius_xx*yy) ){if(di<0)di+= radius_yy2*(2*xx+3);else{di+=radius_yy2*(2*xx+3)+4*radius_xx-4*radius_xx*yy;yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;}xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;draw_point(draw_x0, draw_y0, color);draw_point(draw_x1, draw_y1, color);draw_point(draw_x2, draw_y2, color);draw_point(draw_x3, draw_y3, color);}di=radius_xx2*(yy-1)*(yy-1)+radius_yy2*xx*xx+radius_yy+radius_yy2*xx-radius_xx2*radius_yy; while(yy>=0){ if(di<0){ di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy;xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;}else{ di += radius_xx2*3 - 2*radius_xx2*yy;}yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;draw_point(draw_x0,draw_y0,color);draw_point(draw_x1,draw_y1,color);draw_point(draw_x2,draw_y2,color);draw_point(draw_x3,draw_y3,color);}}。

相关文档
最新文档