12864 实现画图功能

本文作者:林子木

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

首先看下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

 

 


 

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值