12864液晶画点和画任意直线的原理和算法
程序原码经验证可行
12864实际上是256x64二维显示空间,整个液晶屏分上下两个半屏。整个屏一共有256列,64行。可以把它分成16大列,每一大列包含16列。图形RAM的起始址址为0x80,设置读或写的地址时,要先写Y坐标,再写X坐标。要使用画图功能,就要设置扩允指令集。
画点原理:先确定坐标->读出数据->修改数据->数据写回原处。
程序原码:
//画点函数
void Draw_Point(uchar x,uchar y,uchar color)
{
uchar row,tier,row_bit;
uchar ReadOldH,ReadOldL;
tier=x>>4; //把256列分成16大列,每大列包含16列
row_bit=x&0x0f; //计算所给坐标在某一大列中的哪一列
if(y<32) //分上下半屏显示
row=y; //上半屏
else
{
row=y-32; //下半屏
tier+=8;
}
WriteCommand(0x34); //8Bit扩充指令集,即使是36H也要写两次
WriteCommand(0x36); //绘图ON,基本指令集里面36H不能开绘图
WriteCommand(0x80+row); // 行位置
WriteCommand(0x80+tier); // 列位置
ReadData();
ReadOldH=ReadData(); //某大列的前8列数据,低位在前,高位在后
ReadOldL=ReadData(); //某大列的后8列数据
if( row_bit < 8 ) //修改读出的数据
{
switch( color)
{
case 0 : ReadOldH &=( ~( 0x01 << ( 7 - row_bit ))) ; break ;
case 1 : ReadOldH |= ( 0x01 << ( 7 - row_bit )) ; break ;
case 2 : ReadOldH ^= ( 0x01 << ( 7 - row_bit )) ; break ;
default : break ;
}
}
else
{
switch(color)
{
case 0 : ReadOldL &= (~( 0x01 << ( 15 - row_bit ))) ; break ;
case 1 : ReadOldL |= ( 0x01 << ( 15 - row_bit )) ; break ;
case 2 : ReadOldL ^= ( 0x01 << ( 15 - row_bit )) ; break ;
default : break ;
}
}
WriteCommand(0x80+row); // 行位置
WriteCommand(0x80+tier); // 列位置
WriteData( ReadOldH ) ; //把修改后的数据写回原地址
WriteData( ReadOldL ) ;
}
画任意两点间直线的原理和算法:采用Bresenham画线算法。
设线段方程:ax+by+c=0(x1<x<x2,y1<y<y2)
令dx=x2-x1,dy=y2-y1
则:斜率-a/b = dy/dx.
斜率大于0:
从第一个点开始,我们有F(x,1,y1) = a*x1+b*y1+c=0
下面求线段ax+by+c=0与x=x1+1的交点:
由a*(x1+1)+b*y+c = 0, 求出交点坐标y=(-c-a(x1+1))/b
所以交点与点(x+1,y+0.5)的y坐标差值Sub1 = (-c-a(x1+1))/b - (y1+0.5) = -a/b-0.5,即Sub1的处始值为-a/b-0.5。
则可得条件当 Sub1 = -a/b-0.5>0时候,即下个点为(x+1,y+1),反之,下个点为(x+1,y).
代入a/b,则Sub1 = dy/dx-0.5.
判断条件为:2dy-dx>0?
斜率小于0:同理。
斜率=0:即为横线。
斜率=1:即为竖线。
程序原码:
//画任意两点间的直线
void DrawLine( unsigned char StartX,unsigned char StartY, unsigned char EndX, unsigned char EndY, unsigned char Color )
{
int t, distance; /*根据屏幕大小改变变量类型(如改为int型)*/
int x = 0 , y = 0 , delta_x, delta_y ;
char incx, incy ;
delta_x = EndX - StartX ;
delta_y = EndY - StartY ;
//判断直线的方向
if( delta_x > 0 )
{
incx = 1;
}
//画竖线
else if( delta_x == 0 )
{
if(delta_y>0)
DrawTierLine( StartX,StartY, EndY-StartY, Color ) ;
else
DrawTierLine( StartX,EndY, StartY-EndY, Color ) ;
return ;
}
else
{
incx = -1 ;
}
if( delta_y > 0 )
{
incy = 1 ;
}
//画横线
else if(delta_y == 0 )
{
if(delta_x>0)
DrawRowLine( StartY,StartX,EndX-StartX, Color ) ;
else
DrawRowLine( StartY,EndX,StartX-EndX, Color ) ;
return ;
}
else
{
incy = -1 ;
}
if(delta_x<0)
delta_x =-delta_x ;
if(delta_y<0)
delta_y =-delta_y;
if( delta_x > delta_y )
{
distance = delta_x ;
}
else
{
distance = delta_y ;
}
DrawPoint( StartX, StartY, Color ) ;
/* Draw Line*/
for( t = 0 ; t <= distance+1 ; t++ )
{
DrawPoint( StartX, StartY, Color ) ;
x += delta_x ;
y += delta_y ;
//2dy-dx>0?
if( x > distance )
{
x -= distance ;
StartX += incx ;
}
if( y > distance )
{
y -= distance ;
StartY += incy ;
}
}
}
size=4]
一周热门 更多>