12686 实现画图功能

12686 实现画图功能_第1张图片本文作者:林子木

学历有限,如有纰漏敬请见谅!

首先看下12864的绘图显示原理


注意,不要简单的认为12864 是y轴64 x轴128 ;那是点阵的分布,不是读写的分布。

正的如图,y轴32行 从0~31 X轴16 从0~15;0~7为上半屏幕,8~15在下半屏幕

特别注意:X一个地址里面,有两个自己的内容,就是16位的数据

y 和 x的其实地址都是一样0x80,代表0(具体为什么,相见数据手册说明,前面的第8位为规定H,7、6为规定L,5~0为地址输入数值);

现在了解了以上的分布方式,那就简单了嘛,对不?

画一个点,只要找到那个点的x,y坐标不就可以了嘛,对不?

下面是我写的一段画图的代码,全部的文件,会在文章最后给出这里只是一个函数:

/*******************************************
函数名称:Draw_Point
功 能:在整个液晶屏幕上画图
参 数:无
返回值 :无
********************************************/
void Draw_Point(unsigned char x,unsigned char y)
{
uint dat = 0; //读取需要写入的两个字节的值
if(x>127) x = 127;
if(y>63) y = 63;
uchar y_Byte,y_bit,x_Byte,x_bit;
y_Byte = y/32; //0:上半屏幕 1:下半屏幕
y_bit = y%32; //y的行号
x_Byte = x/16; //x的列号
x_bit = x%16; //x的位
Write_Cmd(0x34); //打开扩展指令集
Write_Cmd(0x80+31-y_bit); //因为液晶y是从上往下的,这里简单的转换成从下往上
Write_Cmd(0x80+x_Byte+(1-y_Byte)*8);//(1-y_Byte)*8 代表上下半页
if(x_bit>7) //因为是地址是两个字节,但是写入还是一个一个字节的,所以需要判断
{
Write_Data(0x00);
Write_Data((0x80>>x_bit%8);//因为液晶显示,高位在前
} //如如果想把第八位点亮 直接写0x80 那么会 成100000000
else //而不是我们要的从左到右的 第八位 00000001 所以需要转换下
{
Write_Data((0x80>>x_bit%8));
Write_Data(0x00);
}
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x30); //回到基本指令集
}

哈哈,简单吧,不过问题又来了!

什么问题?那就是,简单的这样的话,画一个孤立的点是没为题,可是问题是,如果我要画一条直线就不行了,为什么?

因为,我想吧莫个点点亮,我写入的时候,不知道这个点所在的X轴的地址中的两个字节的内容是否已经有点了,所以我只能将其他位变为0

也就是说,其他位被清零了!纠结呀,这可怎么办呢?

哈哈,还好,记得不,液晶还有读的功能,记住这点就ok了,那就是添加一个读的功能

代码如下:

红色部分为修改的

/*******************************************
函数名称:Draw_Point
功 能:在整个液晶屏幕上画图
参 数:无
返回值 :无
********************************************/
void Draw_Point(unsigned char x,unsigned char y)
{
uint dat = 0; //读取需要写入的两个字节的值
dat = Read_Add(x,y); //注意,因为read 或者 write之后 地址指针AC会自动加+ 想对莫一块进行读和写的工作,就需要重新写入地址
if(x>127) x = 127;
if(y>63) y = 63;
uchar y_Byte,y_bit,x_Byte,x_bit;
y_Byte = y/32; //0:上半屏幕 1:下半屏幕
y_bit = y%32; //y的行号
x_Byte = x/16; //x的列号
x_bit = x%16; //x的位
Write_Cmd(0x34); //打开扩展指令集
Write_Cmd(0x80+31-y_bit); //因为液晶y是从上往下的,这里简单的转换成从下往上
Write_Cmd(0x80+x_Byte+(1-y_Byte)*8);//(1-y_Byte)*8 代表上下半页
if(x_bit>7) //因为是地址是两个字节,但是写入还是一个一个字节的,所以需要判断
{
Write_Data(0x00|((dat>>8)&0xff));
Write_Data((0x80>>x_bit%8)|(dat&0xff));//因为液晶显示,高位在前
} //如如果想把第八位点亮 直接写0x80 那么会 成100000000
else //而不是我们要的从左到右的 第八位 00000001 所以需要转换下
{
Write_Data((0x80>>x_bit%8)|((dat>>8)&0xff));
Write_Data(0x00|(dat&0xff));
}
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x30); //回到基本指令集
}

下面贴出具体的读的代码:

注意两个函数的区别

/*******************************************
函数名称:Read_Data
功 能:读取液晶屏幕的值
参 数:无
返回值 :无
********************************************/


uchar Read_Data(void)
{
uchar lcdtemp = 0;
uchar dat = 0;

LCD_RS_L;
LCD_RW_H;
LCD_DataIn; //设置为输入方式
do //判忙
{
LCD_EN_H;
_NOP();
lcdtemp = LCD2MCU_Data;
LCD_EN_L;
}
while(lcdtemp & 0x80);

LCD_RS_H; //置高
LCD_RW_H; //置高
_NOP();

LCD_EN_H; //使能
_NOP();
dat = LCD2MCU_Data; //读数据
_NOP();
LCD_EN_L;
return (dat);
}

/*******************************************
函数名称:Read_Add
功 能:读取液晶屏幕某一点的值
参 数:无
返回值 :无
********************************************/

unsigned int Read_Add(unsigned char x,unsigned char y)
{
unsigned int dat;
uchar dat_H = 0,dat_L = 0;
if(x>127) x = 127;
if(y>63) y = 63;
uchar y_Byte,y_bit,x_Byte,x_bit;
y_Byte = y/32; //0:上半屏幕 1:下半屏幕
y_bit = y%32; //y的行号
x_Byte = x/16; //x的列号
x_bit = x%16; //x的位
Write_Cmd(0x34); //打开扩展指令集
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x80+31-y_bit);
Write_Cmd(0x80+x_Byte+(1-y_Byte)*8);

Read_Data(); //注意:读操作要先执行有一个空读命令
dat_H = Read_Data();
dat_L = Read_Data();
Write_Cmd(0x30); //回到基本指令集
dat = dat_H*0x0100 + dat_L;
return dat;
}

由于百度文章的篇幅限制,剩下的代码,将在百度文库中给出,下面是连接地址:

http://wenku.baidu.com/view/25f763748e9951e79b892783.html

12686 实现画图功能_第2张图片

12686 实现画图功能_第3张图片

你可能感兴趣的:(实现)