12864绘图程序大集合.docx
- 文档编号:9026261
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:38
- 大小:24.71KB
12864绘图程序大集合.docx
《12864绘图程序大集合.docx》由会员分享,可在线阅读,更多相关《12864绘图程序大集合.docx(38页珍藏版)》请在冰豆网上搜索。
12864绘图程序大集合
/**********************************************************************************************************************************************************************/
//程序说明:
本程序为12864(st7920)驱动程序,只实现了最简单的显示功能
//端口设置:
RS、RW、EN分别为P0口的0、1、2,数据口为P2口
用取模软件取的图形或汉字必须是逐行取的,因为本函数是在液晶上逐行打点的
/*********************************************************************************************************************************************************************/
#include
#include
#include
#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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 12864 绘图 程序 集合
![提示](https://static.bdocx.com/images/bang_tan.gif)