12864各种画图程序带字库修改Word下载.docx
《12864各种画图程序带字库修改Word下载.docx》由会员分享,可在线阅读,更多相关《12864各种画图程序带字库修改Word下载.docx(38页珍藏版)》请在冰点文库上搜索。
j++);
}
//***********ms级延时函数
/*voiddelay_1ms(uintx)
uinti,j;
for(j=0;
j<
x;
j++)
for(i=0;
i<
110;
i++);
}*/
//***********12864写指令函数
voidwrite_com(ucharcmd)
LCD_RS=0;
LCD_RW=0;
P2=cmd;
delay(5);
LCD_EN=1;
LCD_EN=0;
//********12864写数据函数
voidwrite_dat(uchardat)
LCD_RS=1;
P2=dat;
//****************从LCD中读数据
ucharread_dat(void)
uchartemp;
P2=0XFF;
//释放数据线
//数据
LCD_RW=1;
//读模式
//E为高电平进行读数据或指令
delay
(1);
temp=P2;
returntemp;
//********************************************************
//设置光标(地址)函数
//参数说明:
x---为行号,y为列号
voidset_cursor(unsignedcharx,unsignedchary)
unsignedchari;
switch(x)//确定行号
{
case0x00:
i=0x80;
break;
//第一行
case0x01:
i=0x90;
//第二行
case0x02:
i=0x88;
//第三行
case0x03:
i=0x98;
//第四行
default:
}
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);
//绘图显示关闭
2;
i++)//分上下两屏写
32;
j++)
{
write_com(0x80+j);
//写y坐标
delay
(1);
if(i==0)//写x坐标
{
write_com(0x80);
delay
(1);
}
else//写下半屏
write_com(0x88);
for(k=0;
k<
16;
k++)//写一整行数据
write_dat(0x00);
//写高字节
//写低字节
}
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位数据
//设定行地址(y坐标)
//设定列地址(x坐标),并通过8*y_Dyte选定上下屏
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);
write_dat(GDRAM_lbit|(0x01<
(15-x_byte)));
write_dat(GDRAM_lbit&
(15-x_byte))));
//清除GDRAM区高8位数据中相应的点
}
write_com(0x30);
//恢复到基本指令集
//***********(给定坐标并打点的)任意位置打点函数
voidlcd_set_dot(ucharx,uchary)
ucharx_byte,x_bit;
//确定在坐标的那一字节哪一位
uchary_ping,y_bit;
//确定在坐标的哪一屏哪一行
uchartmph,tmpl;
//定义两个临时变量,用于存放读出来的数据
//扩展指令集
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)就是用来确定上半屏还是下半屏
//预读取数据
tmph=read_dat();
//读取当前显示高8位数据
tmpl=read_dat();
//读取当前显示低8位数据
write_com(0x80+y_bit);
//读操作会改变AC,所以重新设置一下
if(x_bit<
8)
write_dat(tmph|(0x01<
(7-x_bit)));
//写高字节,因为坐标是从左向右的,GDRAM高位在昨,低位在右
write_dat(tmpl);
//原低位数据送回
write_dat(tmph);
//原高位数据送回
write_dat(tmpl|(0x01<
(15-x_bit)));
//打开绘图显示
//回到基本指令集
//************画水平线函数**********************************//
//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)
//用于对两个数互换的中间变量,使y1为大值
if(y0>
y1)
bak=y1;
y1=y0;
y0=bak;
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);
//画水平线
dx=x1-x0;
//求取两点之间的差值
dy=y1-y0;
//****判断增长方向,或是否为水平线、垂直线、点*//
if(dx>
0)//判断x轴方向
dx_sym=1;
if(dx<
0)
dx_sym=-1;
else
gui_rline(x0,y0,y1);
return;
if(dy>
0)//判断y轴方向
dy_sym=1;
if(dy<
dy_sym=-1;
gui_hline(x0,x1,y0);
/*将dx、dy取绝对值***********/
dx=dx_sym*dx;
dy=dy_sym*dy;
/****计算2倍的dx、dy值*******/
dx_x2=dx*1;
//我改为了一倍,这样才跟真实的两点对应
dy_x2=dy*1;
/***使用bresenham法进行画直线***/
=dy)//对于dx>
=dy,使用x轴为基准
di=dy_x2-dx;
while(x0!
=x1)
lcd_set_dot(x0,y0);
x0+=dx_sym;
if(di<
di+=dy_x2;
//计算出下一步的决策值
else
di+=dy_x2-dx_x2;
y0+=dy_sym;
}
lcd_set_dot(x0,y0);
//显示最后一点
else//对于dx<
dy使用y轴为基准
di=dx_x2-dy;
while(y0!
=y1)
lcd_set_dot(x0,y0);
y0+=dy_sym;
di+=dx_x2;
di+=dx_x2-dy_x2;
x0+=dx_sym;
//***************************************************************************//
//*******************画指定宽度的任意两点之间的直线**************************//
x0、y0为起始点坐标,x1、y1为终点坐标,with为线宽*****************//
voidgui_linewith(ucharx0,uchary0,ucharx1,uchary1,ucharwith)
//直线x轴差值变量
//直线y轴差值变量
//x轴增长方向,为-1时减值方向,为1时增值方向
//y轴增长方向,为-1时减值方向,为1时增值方向
//dx*2值变量,用于加快运算速度
//dy*2值变量,用于加快运算速度
//决策变量
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>
0,设置dx_sym=1
if(dx<
0)
{
//dx<
0,设置dx_sym=-1
//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++;
if(dy>
0)//判断y轴方向
//dy>
0,设置dy_sym=1
if(dy<
//dy<
0,设置dy_sym=-1
//dy==0,画水平线,或一点
wx=y0-wx;
wy=y0