问一个关于KS0108 控制器12864液晶读显示数据问题

2020-02-05 09:09发布

本帖最后由 yangjinke1118 于 2012-6-6 15:32 编辑

如题,本人最近搞12864显示程序,在写一个任意位置画点的函数时候发现一个问题,12864读显示数据非常慢。下面是手册提供的读数据时序图(在文章最下面):
任意位置画点函数的思路是这样的:首先根据传入的坐标位置x,y,计算出12864的“页地址”和“列地址”,然后再根据坐标的y坐标计算出在当前页中8个点中哪一个点显示(12864写显示数据是一个字节8位写的),也就是说在计算出“页地址”和“列地址”之外还需要计算出“显示数据”。那么在计算显示数据的时候还要考虑要保留原有的显示数据(不然在画点的时候就覆盖掉当前地址的其他显示数据了),比如原来8位显示数据是这样的0b01100000,现在需要在第一位显示一点,那么显示数据就需要修改为0b01100001,这样就需要在计算显示数据之前先读出当前地址的显示数据,然后与计算所得的显示数据做与运算,最终得到结果。
下面附相关代码:
static unsigned char RD_Data()//读显示数据,本篇文章的问题就出在这里
{
        unsigned char tmp;
        while(tmp==0x80)
        {
                tmp=RD_STATUS();
                tmp=tmp&0x80;
        }
        lcd_RW=1;
        lcd_DI=1;
        lcd_E=1;//注意1,空读操作
        lcd_E=0;//注意1,空读操作
        lcd_E=1;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
                _nop_();
        _nop_();
        _nop_();

        DB=0xFF;
        tmp=DB;
        lcd_E=0;
        return tmp;
}

void WR_DATA(unsigned char dat) //写显示数据
{
        unsigned char tmp;
        while(tmp==0x80)
        {
                tmp=RD_STATUS();
                tmp=tmp&0x80;
        }
        lcd_RW=0;
        lcd_DI=1;
        DB=dat;
        lcd_E=1;
        //_nop_();
        lcd_E=0;
}

void WR_CMD(unsigned char cmd) //写命令数据
{
        unsigned char tmp;
        while(tmp==0x80)
        {
                tmp=RD_STATUS();
                tmp=tmp&0x80;
        }
        lcd_RW=0;
        lcd_DI=0;
        DB=cmd;
        lcd_E=1;
        //_nop_();
        lcd_E=0;
}
//任意位置画点函数
void Dot(point one) //画任意位置点,保留原有地址显示数据
{        //x横向,0<=x<=63,y纵向,0<=y<=127
        unsigned char bitset;
        bitset=0x01;
        if (one.x<MAX_X)
        {
                SelectLeft();       
        }
        else
        {
                one.x=one.x-MAX_X;
                SelectRight();
        }
        WR_CMD(SET_FIRST_ROW);//设置首行
        WR_CMD(SET_PAGE|(one.y>>3));//设置页
        WR_CMD(SET_COLUMN|one.x);//设置列
        bitset=(bitset<<(one.y%8))|RD_Data();//计算出的显示数据与读出当前地址显示数据进行或运算,计算出重叠后的显示数据
        WR_CMD(SET_COLUMN|one.x);//设置列
        WR_DATA(bitset);//计算显示数据
}
***************************************************************************************************************
那么在读12864显示数据调用RD_Data()函数的时候发现,其时序的时效完全与手册提供的数据相悖,其读取显示数据的时间远远大于手册提供的时间(在RD_Data()函数中我加了好几nop,少一个都不行,无法获得正确显示数据)。
12864的读显示数据的性能是不是和液晶模块厂家有很大关系?
正因为12864读显示数据的性能如此之差,那么基于这个任意位置画点函数(Dot())的其他画线、画框等函数的性能将令人无法接受。。。。
不知大家有什么好的意见。。。。。。。。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
yangjinke1118
1楼-- · 2020-02-05 14:59
 精彩回答 2  元偷偷看……
dosomething
2楼-- · 2020-02-05 20:16
这样操作肯定很慢

可以建立一个跟液晶RAM同等大小的数组

先操作数组,然后直接写液晶

这样对液晶只有写操作,会快很多

还有写操作只针对需要刷新的区域进行,会更快
mcu_lover
3楼-- · 2020-02-06 00:25
3楼正解。如果需要快,可以建立屏幕缓冲区。
mcu_lover
4楼-- · 2020-02-06 01:09
你确定你的判断忙部分代码没有问题,我怎么看着感觉有点不对劲。
yangjinke1118
5楼-- · 2020-02-06 05:38
dosomething 发表于 2012-6-6 15:56
这样操作肯定很慢

可以建立一个跟液晶RAM同等大小的数组

不好意思,我忘记说了,液晶程序是AT89S52来跑的,因此,建立一个128*64字节的显存单元基本是奢侈的,也是不可能的。当然刷新肯定是只是对变化部分数据刷新,全屏刷新那就跟惨了。
我就是纳闷,读12864液晶内部的RAM的效率为何如此之差。

一周热门 更多>