12864画图

  • 格式:doc
  • 大小:389.00 KB
  • 文档页数:11

1、打点部分/********************************************************名称:GUI_Point(打点)说明:X:横坐标(代表列的位置,0~127) Y:纵坐标(代表行的位置,0~63) 根据Datesheet需先把数据写到GDRAM,读取当前位置的数据,经过或和移位后再把数据重新写入GDRAM每行有16个位元,共64行,每个位元有两个8位(高低8位) 计算出在那个位元,在该位元的哪一位易出现的问题:1、打点位置的定位2、读取当前显示的数据3、或和移位,即重新写人的新数据********************************************************/void GUI_Point(uchar x,uchar y,uchar flag){uchar x_Dyte,x_byte; //定义列地址的字节位,及在字节中的哪1位uchar y_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_D yte选定上下屏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_byte<8) //判断其在高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 直线终点所在列的位置* 出口参数:无* 说明:操作失败原因是指定地址超出缓冲区范围。

*********************************************************/void GUI_Line8(uchar x0,uchar y0,uchar x1,uchar y1){int temp;int dx,dy; //定义起点到终点的横、纵坐标增加值int s1,s2,status,i;int Dx,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(Dy>Dx) //{ //以45度角为分界线,靠进Y轴是status=1,靠近X轴是status=0 temp=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;i<Dx;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份7 16 25 34*****************************************/void Draw_circle(uchar x0,uchar y0,uchar r){int a,b;int di;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(di<0)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、整屏画图部分这个比较简单,就直接上程序了void LCD_fulldisplay_picture_2(const uchar *pic) //全屏显示图片方法2 {unsigned int x=0;unsigned char i,j;Write_command(0x34); //扩展指令动作Write_command(0x36); //扩展指令动作for(i=0;i<32;i++) //上半屏显示{Write_command(0x80|i); //列位置Write_command(0x80); //行位置for(j=0;j<16;j++) //256/8=32 byte{ //列位置每行自动增加Write_data(*pic);pic++;}}for(i=0;i<32;i++) //下半屏显示{Write_command(0x80|i); //列位置Write_command(0x88); //行位置for(j=0;j<16;j++) //256/8=32 byte {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) (输入显示数据的位置)说明:(此显示位置的确定方法类似打点的程序)***************************************************/void LCD_display_zizao(uchar x,uchar y,const uchar *pin){uchar i,j;uchar X_byte=x/16; //计算在列的那个位元上(一行共16个位元)uchar Y_Dyte=y/31; //上下屏标志位uchar Y_byte=y&0x1f; //0~31行中哪一行for(j=0;j<16;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位数据}}const uchar hanzi_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};const uchar hanzi_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};const uchar hanzi_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};const uchar hanzi_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};const uchar hanzi_4[]={ //"想"0x10,0x08,0x11,0xFC,0x11,0x08,0xFF,0x08,0x11,0xF8,0x31,0x08,0x39,0xF8,0x55,0x08,0x91,0x08,0x11,0xF8,0x00,0x00,0x12,0x00,0x51,0x84,0x50,0x92,0x90,0x12,0x0F,0xF0};/****奥运五环图案****/void Olympic_rings(void){draw_rectangular(0,0,127,63); //以显示区域画一个边框Draw_circle(37,10,10);Draw_circle(64,10,10);Draw_circle(91,10,10);Draw_circle(50,20,10);Draw_circle(78,20,10);LCD_display_zizao(0,32,hanzi_0); //同LCD_display_zizao(16,32,hanzi_1); //一LCD_display_zizao(32,32,hanzi_2); //个LCD_display_zizao(48,32,hanzi_3); //梦LCD_display_zizao(64,32,hanzi_4); //想Write_command(0x30); //关闭绘图模式LCD_Display_Mixed(3,3,"同一个世界 "); //普通模式下输入汉字}就为大家讲这么多吧,希望我的东西对大家有用,如果有更优的源码可以交流交流,随便帮我解决那个“同”的问题,哦,对了,用点阵扫进去的位置好像也不怎么对,也请大家给看看啊,按一行128点,一列64点来处理。