for(i=0;i<110;i++);
}*/
//***********12864写指令函数
voidwrite_com(ucharcmd)
{
LCD_RS=0;
LCD_RW=0;
P2=cmd;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
//********12864写数据函数
voidwrite_dat(uchardat)
{
LCD_RS=1;
LCD_RW=0;
P2=dat;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
//****************从LCD中读数据
ucharread_dat(void)
{
uchartemp;
P2=0XFF;//释放数据线
LCD_RS=1;//数据
LCD_RW=1;//读模式
LCD_EN=1;//E为高电平进行读数据或指令
delay
(1);
temp=P2;
LCD_EN=0;
returntemp;
}
//********************************************************
//设置光标(地址)函数
//参数说明:
x---为行号,y为列号
//********************************************************
voidset_cursor(unsignedcharx,unsignedchary)
{
unsignedchari;
switch(x)//确定行号
{
case0x00:
i=0x80;break;//第一行
case0x01:
i=0x90;break;//第二行
case0x02:
i=0x88;break;//第三行
case0x03:
i=0x98;break;//第四行
default:
break;
}
i=y+i;//确定列号
write_com(i);
}
//********************************************************
//显示字符函数
//********************************************************
voiddisplay_char(unsignedcharAlphabet)
{
write_dat(Alphabet);//写入需要显示字符的显示码
}
//********************************************************
//指定位置显示字符串函数
//参数说明:
x为行号,y为列号
//********************************************************
voiddisplay_string(unsignedcharx,unsignedchary,unsignedchar*Alphabet)
{
unsignedchari=0;
set_cursor(x,y);//设置显示的起始地址
while(Alphabet[i]!
='\0')
{
write_dat(Alphabet[i]);//写入需要显示字符的显示码
i++;
}
}
//***********************以下为GDRAM绘图部分***************************//
//*********************绘图显示的清屏函数(因清屏指令在画图时不能用)------------------------------------------------------------------------------注意
voidgui_clear()
{
uchari,j,k;
write_com(EXTEND_SET);//扩展指令集,8位数据传输
write_com(DRAW_OFF);//绘图显示关闭
for(i=0;i<2;i++)//分上下两屏写
{
for(j=0;j<32;j++)
{
write_com(0x80+j);//写y坐标
delay
(1);
if(i==0)//写x坐标
{
write_com(0x80);
delay
(1);
}
else//写下半屏
{
write_com(0x88);
delay
(1);
}
for(k=0;k<16;k++)//写一整行数据
{
write_dat(0x00);//写高字节
write_dat(0x00);//写低字节
delay
(1);
}
}
}
write_com(DRAW_ON);//打开绘图显示
write_com(BASIC_SET);//打开基本指令集
}
//******************************************************************
//*****有反白显示功能的打点函数***********
//参数:
color=1,该点填充1;color=0,该点填充白色0;
//*******************************************************************
voidGUI_Point(unsignedcharx,unsignedchary,unsignedcharcolor)
{
unsignedcharx_Dyte,x_byte;//定义列地址的字节位,及在字节中的哪1位
unsignedchary_Dyte,y_byte;//定义为上下两个屏(取值为0,1),行地址(取值为0~31)
unsignedcharGDRAM_hbit,GDRAM_lbit;
write_com(0x36);//扩展指令命令
/***X,Y坐标互换,即普通的X,Y坐标***/
x_Dyte=x/16;//计算在16个字节中的哪一个
x_byte=x&0x0f;//计算在该字节中的哪一位
y_Dyte=y/32;//0为上半屏,1为下半屏
y_byte=y&0x1f;//计算在0~31当中的哪一行
write_com(0x80+y_byte);//设定行地址(y坐标),即是垂直地址
write_com(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通过8*y_Dyte选定上下屏,即是水平地址
read_dat();//预读取数据
GDRAM_hbit=read_dat();//读取当前显示高8位数据
GDRAM_lbit=read_dat();//读取当前显示低8位数据
delay
(1);
write_com(0x80+y_byte);//设定行地址(y坐标)
write_com(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通过8*y_Dyte选定上下屏
delay
(1);
if(x_byte<8)//判断其在高8位,还是在低8位
{
if(color==1)
{
write_dat(GDRAM_hbit|(0x01<<(7-x_byte)));//置位GDRAM区高8位数据中相应的点
}
else
write_dat(GDRAM_hbit&(~(0x01<<(7-x_byte))));//清除GDRAM区高8位数据中相应的点
write_dat(GDRAM_lbit);//显示GDRAM区低8位数据
}
else
{
write_dat(GDRAM_hbit);
if(color==1)
write_dat(GDRAM_lbit|(0x01<<(15-x_byte)));//置位GDRAM区高8位数据中相应的点
else
write_dat(GDRAM_lbit&(~(0x01<<(15-x_byte))));//清除GDRAM区高8位数据中相应的点
}
write_com(0x30);//恢复到基本指令集
}
//***********(给定坐标并打点的)任意位置打点函数
voidlcd_set_dot(ucharx,uchary)
{
ucharx_byte,x_bit;//确定在坐标的那一字节哪一位
uchary_ping,y_bit;//确定在坐标的哪一屏哪一行
uchartmph,tmpl;//定义两个临时变量,用于存放读出来的数据
write_com(EXTEND_SET);//扩展指令集
write_com(DRAW_OFF);//绘图显示关闭
x_byte=x/16;//算出在哪一字节,注意一个地址是16位的
x_bit=x%16;//&0x0f;//算出在哪一位
y_ping=y/32;//确定在上半屏还是下半屏,0代表上半屏,1代表下半屏
y_bit=y%32;//&0x1f;//确定在第几行
write_com(0X80+y_bit);//先写垂直地址(最高位必须)
write_com(0x80+x_byte+8*y_ping);//水平坐标,下半屏坐标起始地址为0x88,(+8*y_ping)就是用来确定上半屏还是下半屏
read_dat();//预读取数据
tmph=read_dat();//读取当前显示高8位数据
tmpl=read_dat();//读取当前显示低8位数据
delay
(1);
write_com(0x80+y_bit);//读操作会改变AC,所以重新设置一下
write_com(0x80+x_byte+8*y_ping);
delay
(1);
if(x_bit<8)
{
write_dat(tmph|(0x01<<(7-x_bit)));//写高字节,因为坐标是从左向右的,GDRAM高位在昨,低位在右
write_dat(tmpl);//原低位数据送回
}
else
{
write_dat(tmph);//原高位数据送回
write_dat(tmpl|(0x01<<(15-x_bit)));
}
write_com(DRAW_ON);//打开绘图显示
write_com(BASIC_SET);//回到基本指令集
}
//************画水平线函数**********************************//
//x0、x1为起始点和终点的水平坐标,y为垂直坐标***************//
//**********************************************************//
voidgui_hline(ucharx0,ucharx1,uchary)
{
ucharbak;//用于对两个数互换的中间变量,使x1为大值
if(x0>x1)
{
bak=x1;
x1=x0;
x0=bak;
}
do
{
lcd_set_dot(x0,y);//从左到右逐点显示
x0++;
}while(x1>=x0);
}
//***********画竖直线函数***********************************//
//x为起始点和终点的水平坐标,y0、y1为垂直坐标***************//
//**********************************************************//
voidgui_rline(ucharx,uchary0,uchary1)
{
ucharbak;//用于对两个数互换的中间变量,使y1为大值
if(y0>y1)
{
bak=y1;
y1=y0;
y0=bak;
}
do
{
lcd_set_dot(x,y0);//从上到下逐点显示
y0++;
}while(y1>=y0);
}
//*********任意两点间画直线*********************************//
//x0、y0为起始点坐标,x1、y1为终点坐标**********************//
//**********************************************************//
voidgui_line(ucharx0,uchary0,ucharx1,uchary1)
{
chardx;//直线x轴差值
chardy;//直线y轴差值
chardx_sym;//x轴增长方向,为-1时减值方向,为1时增值方向
chardy_sym;//y轴增长方向,为-1时减值方向,为1时增值方向
chardx_x2;//dx*2值变量,用于加快运算速度
chardy_x2;//dy*2值变量,用于加快运算速度
chardi;//决策变量
if(x0==x1)//判断是否为垂直线
{
gui_rline(x0,y0,y1);//画垂直线
return;
}
if(y0==y1)//判断是否为水平线
{
gui_hline(x0,x1,y0);//画水平线
return;
}
dx=x1-x0;//求取两点之间的差值
dy=y1-y0;
//****判断增长方向,或是否为水平线、垂直线、点*//
if(dx>0)//判断x轴方向
dx_sym=1;
else
{
if(dx<0)
dx_sym=-1;
else
{
gui_rline(x0,y0,y1);
return;
}
}
if(dy>0)//判断y轴方向
dy_sym=1;
else
{
if(dy<0)
dy_sym=-1;
else
{
gui_hline(x0,x1,y0);
return;
}
}
/*将dx、dy取绝对值***********/
dx=dx_sym*dx;
dy=dy_sym*dy;
/****计算2倍的dx、dy值*******/
dx_x2=dx*1;//我改为了一倍,这样才跟真实的两点对应
dy_x2=dy*1;
/***使用bresenham法进行画直线***/
if(dx>=dy)//对于dx>=dy,使用x轴为基准
{
di=dy_x2-dx;
while(x0!
=x1)
{
lcd_set_dot(x0,y0);
x0+=dx_sym;
if(di<0)
di+=dy_x2;//计算出下一步的决策值
else
{
di+=dy_x2-dx_x2;
y0+=dy_sym;
}
}
lcd_set_dot(x0,y0);//显示最后一点
}
else//对于dx{
di=dx_x2-dy;
while(y0!
=y1)
{
lcd_set_dot(x0,y0);
y0+=dy_sym;
if(di<0)
di+=dx_x2;
else
{
di+=dx_x2-dy_x2;
x0+=dx_sym;
}
}
lcd_set_dot(x0,y0);//显示最后一点
}
}
//***************************************************************************//
//*******************画指定宽度的任意两点之间的直线**************************//
//参数说明:
x0、y0为起始点坐标,x1、y1为终点坐标,with为线宽*****************//
//***************************************************************************//
voidgui_linewith(ucharx0,uchary0,ucharx1,uchary1,ucharwith)
{
chardx;//直线x轴差值变量
chardy;//直线y轴差值变量
chardx_sym;//x轴增长方向,为-1时减值方向,为1时增值方向
chardy_sym;//y轴增长方向,为-1时减值方向,为1时增值方向
chardx_x2;//dx*2值变量,用于加快运算速度
chardy_x2;//dy*2值变量,用于加快运算速度
chardi;//决策变量
charwx,wy;//线宽变量
chardraw_a,draw_b;
//参数过滤
if(with==0)return;
if(with>50)with=50;
dx=x1-x0;//求取两点之间的差值
dy=y1-y0;
wx=with/2;
wy=with-wx-1;
//判断增长方向,或是否为水平线、垂直线、点
if(dx>0)//判断x轴方向
{
dx_sym=1;//dx>0,设置dx_sym=1
}
else
{
if(dx<0)
{
dx_sym=-1;//dx<0,设置dx_sym=-1
}
else
{
//dx==0,画垂直线,或一点
wx=x0-wx;
if(wx<0)wx=0;
wy=x0+wy;
while
(1)
{
x0=wx;
gui_rline(x0,y0,y1);
if(wx>=wy)break;
wx++;
}
return;
}
}
if(dy>0)//判断y轴方向
{
dy_sym=1;//dy>0,设置dy_sym=1
}
else
{
if(dy<0)
{
dy_sym=-1;//dy<0,设置dy_sym=-1
}
else
{
//dy==0,画水平线,或一点
wx=y0-wx;
if(wx<0)wx=0;
wy=y0