1、打点部分
/********************************************************
名称:GUI_Point(打点)
说明:X:横坐标(代
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
列的位置,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_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_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;
else
s2=-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;
}
else
status=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
=0)
{
if(status==1) //在靠近Y轴区,x值加1
x0+=s1;
else //在靠近X轴区,y值加1
y0+=s2;
sub-=2*Dx; //判断下下个点的位置
}
if(status==1)
y0+=s2;
else
x0+=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份
0
7 1
6 2
5 3
4
*****************************************/
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); //3
GUI_Point(x0+b,y0-a,1); //0
GUI_Point(x0-a,y0+b,1); //1
GUI_Point(x0-b,y0-a,1); //7
GUI_Point(x0-a,y0-b,1); //2
GUI_Point(x0+b,y0+a,1); //4
GUI_Point(x0+a,y0-b,1); //5
GUI_Point(x0+a,y0+b,1); //6
GUI_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) //全屏显示图片
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
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点来处理。