12864各种画图程序带字库修改.docx

上传人:b****3 文档编号:4214112 上传时间:2023-05-06 格式:DOCX 页数:38 大小:24.91KB
下载 相关 举报
12864各种画图程序带字库修改.docx_第1页
第1页 / 共38页
12864各种画图程序带字库修改.docx_第2页
第2页 / 共38页
12864各种画图程序带字库修改.docx_第3页
第3页 / 共38页
12864各种画图程序带字库修改.docx_第4页
第4页 / 共38页
12864各种画图程序带字库修改.docx_第5页
第5页 / 共38页
12864各种画图程序带字库修改.docx_第6页
第6页 / 共38页
12864各种画图程序带字库修改.docx_第7页
第7页 / 共38页
12864各种画图程序带字库修改.docx_第8页
第8页 / 共38页
12864各种画图程序带字库修改.docx_第9页
第9页 / 共38页
12864各种画图程序带字库修改.docx_第10页
第10页 / 共38页
12864各种画图程序带字库修改.docx_第11页
第11页 / 共38页
12864各种画图程序带字库修改.docx_第12页
第12页 / 共38页
12864各种画图程序带字库修改.docx_第13页
第13页 / 共38页
12864各种画图程序带字库修改.docx_第14页
第14页 / 共38页
12864各种画图程序带字库修改.docx_第15页
第15页 / 共38页
12864各种画图程序带字库修改.docx_第16页
第16页 / 共38页
12864各种画图程序带字库修改.docx_第17页
第17页 / 共38页
12864各种画图程序带字库修改.docx_第18页
第18页 / 共38页
12864各种画图程序带字库修改.docx_第19页
第19页 / 共38页
12864各种画图程序带字库修改.docx_第20页
第20页 / 共38页
亲,该文档总共38页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

12864各种画图程序带字库修改.docx

《12864各种画图程序带字库修改.docx》由会员分享,可在线阅读,更多相关《12864各种画图程序带字库修改.docx(38页珍藏版)》请在冰点文库上搜索。

12864各种画图程序带字库修改.docx

12864各种画图程序带字库修改

/**********************************************************************************************************************************************************************/

//程序说明:

本程序为12864(st7920)驱动程序,只实现了最简单的显示功能

//端口设置:

RS、RW、EN分别为P0口的0、1、2,数据口为P2口

//注意:

1.要想在液晶屏上同时显示自定义字库和绘图,必须先显示自定义字库

//2.本程序所有函数均有用且正确,由于我的keil未破解不能编译,所以将其注释了

// 3.用取模软件取的图形或汉字必须是逐行取的,因为本函数是在液晶上逐行打点的

/***********************************************************************************************************************************************************/

#include

#include//内含-NOP-函数

#include//内含rand()函数

#defineucharunsignedchar

#defineuintunsignedint

//**********宏定义所需指令

#defineBASIC_SET0x30

#defineEXTEND_SET0x34

#defineDRAW_ON0x36

#defineDRAW_OFF0x34

//*************端口定义

sbitLCD_RS=P0^0;

sbitLCD_RW=P0^1;

sbitLCD_EN=P0^2;

//************变量定义

//uchardis1[10];

//****************短延时

voiddelay(uintk)

{

uinti;

ucharj;

for(i=0;i

for(j=0;j<10;j++);

}

//***********ms级延时函数

/*voiddelay_1ms(uintx)

{

uinti,j;

for(j=0;j

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

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 幼儿教育 > 育儿知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2