您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 酒店餐饮 > 基于51单片机的lcd12864的画图程序
1、打点部分/********************************************************名称:GUI_Point(打点)说明:X:横坐标(代表列的位置,0~127)Y:纵坐标(代表行的位置,0~63)根据Datesheet需先把数据写到GDRAM,读取当前位置的数据,经过或和移位后再把数据重新写入GDRAM每行有16个位元,共64行,每个位元有两个8位(高低8位)计算出在那个位元,在该位元的哪一位易出现的问题:1、打点位置的定位2、读取当前显示的数据3、或和移位,即重新写人的新数据********************************************************/voidGUI_Point(ucharx,uchary,ucharflag){ucharx_Dyte,x_byte;//定义列地址的字节位,及在字节中的哪1位uchary_Dyte,y_byte;//定义为上下两个屏(取值为0,1),行地址(取值为0~31)Write_command(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_command(0x80+y_byte);//设定行地址(y坐标)Write_command(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通过8*y_Dyte选定上下屏Read_data();GDRAM_hbit=Read_data();//读取当前显示高8位数据GDRAM_lbit=Read_data();//读取当前显示低8位数据delay_us(5);if(flag==1){Write_command(0x80+y_byte);//设定行地址(y坐标)Write_command(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通过8*y_Dyte选定上下屏delay_us(5);if(x_byte8)//判断其在高8位,还是在低8位{Write_data(GDRAM_hbit|(0X01(7-x_byte)));//显示GDRAM区高8位数据Write_data(GDRAM_lbit);//显示GDRAM区低8位数据}else{Write_data(GDRAM_hbit);Write_data(GDRAM_lbit|(0x01(15-x_byte)));}}else{Write_data(0x00);//清除GDRAM区高8位数据Write_data(0x00);//清除GDRAM区低8位数据}}2、画线部分先看程序/*********************************************************名称:GUI_Line()采用布兰森汉姆(Bresenham)算法画线*功能:任意两点间的直线。根据硬件特点,实现加速。*入口参数:x0直线起点所在行的位置*y0直线起点所在列的位置*x1直线终点所在行的位置‘y1直线终点所在列的位置*出口参数:无*说明:操作失败原因是指定地址超出缓冲区范围。*********************************************************/voidGUI_Line8(ucharx0,uchary0,ucharx1,uchary1){inttemp;intdx,dy;//定义起点到终点的横、纵坐标增加值ints1,s2,status,i;intDx,Dy,sub;dx=x1-x0;if(dx=0)//X的方向是增加的s1=1;else//X的方向是降低的s1=-1;dy=y1-y0;//判断Y的方向是增加还是降到的if(dy=0)s2=1;elses2=-1;Dx=fabs(x1-x0);//计算横、纵标志增加值的绝对值Dy=fabs(y1-y0);if(DyDx)//{//以45度角为分界线,靠进Y轴是status=1,靠近X轴是status=0temp=Dx;Dx=Dy;Dy=temp;status=1;}elsestatus=0;/********判断垂直线和水平线********/if(dx==0)//横向上没有增量,画一条水平线GUI_XLine(x0,y0,y1,1);if(dy==0)//纵向上没有增量,画一条垂直线GUI_YLine(x0,y0,x1,1);/*********Bresenham算法画任意两点间的直线********/sub=2*Dy-Dx;//第1次判断下个点的位置for(i=0;iDx;i++){GUI_Point(x0,y0,1);//画点if(sub=0){if(status==1)//在靠近Y轴区,x值加1x0+=s1;else//在靠近X轴区,y值加1y0+=s2;sub-=2*Dx;//判断下下个点的位置}if(status==1)y0+=s2;elsex0+=s1;sub+=2*Dy;}}下面是图片:在(0,0)到(127,32)之间画线在(0,0)到(63,63)之间画线大家可以看到,直线越长其线性越差,主要是算法的问题(原文件名:IMG_1765.JPG)3、画圆部分主要思路是用Bresenham算法先画1/8个圆,在利用对称行画出其余的部分程序如下:/*****************************************名称:Draw_circle(在任意位置画圆)说明:使用Bresenham法画1/8个圆,在用对称性画出其他的7/8个圆按下图把圆分为8份07162534*****************************************/voidDraw_circle(ucharx0,uchary0,ucharr){inta,b;intdi;a=0;b=r;di=3-2*r;//判断下个点位置的标志while(a=b){GUI_Point(x0-b,y0-a,1);//3GUI_Point(x0+b,y0-a,1);//0GUI_Point(x0-a,y0+b,1);//1GUI_Point(x0-b,y0-a,1);//7GUI_Point(x0-a,y0-b,1);//2GUI_Point(x0+b,y0+a,1);//4GUI_Point(x0+a,y0-b,1);//5GUI_Point(x0+a,y0+b,1);//6GUI_Point(x0-b,y0+a,1);a++;/***使用Bresenham算法画圆**/if(di0)di+=4*a+6;else{di+=10+4*(a-b);b--;}GUI_Point(x0+a,y0+b,1);}}这是在以(63,32)为圆心,32为半径画的圆(小问题是当圆大后,会有部分画不出来,有待完善)(原文件名:IMG_1768.JPG)4、整屏画图部分这个比较简单,就直接上程序了voidLCD_fulldisplay_picture_2(constuchar*pic)//全屏显示图片方法2{unsignedintx=0;unsignedchari,j;Write_command(0x34);//扩展指令动作Write_command(0x36);//扩展指令动作for(i=0;i32;i++)//上半屏显示{Write_command(0x80|i);//列位置Write_command(0x80);//行位置for(j=0;j16;j++)//256/8=32byte{//列位置每行自动增加Write_data(*pic);pic++;}}for(i=0;i32;i++)//下半屏显示{Write_command(0x80|i);//列位置Write_command(0x88);//行位置for(j=0;j16;j++)//256/8=32byte{Write_data(*pic);pic++;}}Write_command(0x30);}下面是照片(原文件名:IMG_1769.JPG)5、图片和文字在一起显示我用的是带字库的,所以显示汉字较简单,即先作图,之后关闭绘图模式,打开普通模式就可以显示汉字了,先上个图片(原文件名:IMG_1777.JPG)(原文件名:IMG_1776.JPG)大家有可以已经看出来,同样的图,怎么一幅在“同”字那有边框,另为一幅没有呢?这个也是我的问题,因为“同一个梦想”是我用点阵的方式扫进去的,而另外的字是用带字库的写进去的,我也搞不懂,还想请大家帮忙呀。下面是程序/***************************************************名称:LCD_display_zizao(以点阵方式写入汉字或字符)输入:x(0~127),y(0~63)(输入显示数据的位置)说明:(此显示位置的确定方法类似打点的程序)***************************************************/voidLCD_display_zizao(ucharx,uchary,constuchar*pin){uchari,j;ucharX_byte=x/16;//计算在列的那个位元上(一行共16个位元)ucharY_Dyte=y/31;//上下屏标志位ucharY_byte=y&0x1f;//0~31行中哪一行for(j=0;j16;j++){Write_command(0x80+Y_byte+j);//计算行地址Write_command(0x80+X_byte+8*Y_Dyte);//8*Y_Dyte上下屏标志,确定列地址delay_us(5);Write_data(*pin++);//显示高8位数据Write_data(*pin++);//显示低8位数据}}constucharhanzi_0[]={//同0x00,0x04,0x7F,0xFE,0x40,0x04,0x40,0x24,0x5F,0xF4,0x40,0x04,0x40,0x24,0x4F,0xF4,0x48,0x24,0x48,0x24,0x48,0x24,0x48,0x24,0x4F,0xE4,0x48,0x24,0x40,0x14,0x40,0x08};constucharhanzi_1[]={//一0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};constucharhanzi_2[]={//个0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x11,0x10,0x21,0x0E,0xC1,0x04,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};constucharhanzi_3[]={//梦0x08,0x20,0x08,0x24,0xFF,0xFE,0x08,0x20,0x1C,0x70,0x2A,0xAE,0x49,0x24,0x8C,0x20,0x07,0xF8,0x0C,0x10,0x14,0x20,0x22,0x40,0x01,0x80,0x01,0x00,0x0E,0x00,0x70,0x00};constucharhanzi_4[]={//想0x10,0x08,0x11,0xFC,0x11,0x08,0xFF,
本文标题:基于51单片机的lcd12864的画图程序
链接地址:https://www.777doc.com/doc-4881523 .html