找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2808|回复: 7
收起左侧

关于12864显示点,有两句单片机代码不是很理解

[复制链接]
ID:231376 发表于 2017-9-23 22:23 | 显示全部楼层 |阅读模式
写入一个点的单片机子程序。具体步骤是:计算出X轴、Y轴的地址、X轴中的第几位,然后读出该地址现在的值,因为一般写入新的点的时候,会覆盖掉16个点中其他点,当你要同时显示16个点中的两个点的时候就会冲突,所以先将显示中的点读出来,然后在或上要点亮的点,这样就可以同时点亮。注意读取数据的时候读取的第一个数据不要,从第二数据开始取,也就是说要读取三次,只取后面两次的值。还有就是读取数据之前要先写入你要读取数据的地址,读取数据之后的写入数据还要从新写入地址。最后就是输入数据地址,先输入Y轴,再输入X轴,输入数据。
*/
voidput_point(uchar x,uchar y)
{
       uint bt=0,read=0;
       uchar x_adr,y_adr,h_bit,l_bit;
       y_adr=0x80+y%32;                    //计算Y轴的地址,应为纵坐标有64个,所有对32求余,当Y大于31时,Y的坐标是下半屏的。
       if(y>31)             //计算X轴的地址当Y大于31时X的地址在下半屏,从0X88开始,小于31时X的地址是在上半屏,从0X80开始
              x_adr=0x88+x/16;        
       else
              x_adr=0x80+x/16;
       bt=0x8000>>(x%16);  //求这个点到底是在哪个点
       write_com(0x34);
       write_com(0x34);
       write_com(y_adr);   //读取数据的时候要先写入所取数据的地址
       write_com(x_adr);
       read_data();             //读取的第一个字节不要,
       read=read_data();     //从第二个字节开始接收。
       read<<=8;
       read|=read_data();
       bt=bt|read;
       h_bit=bt>>8;
       l_bit=bt;
       write_com(y_adr);    //写入点的时候,重新写入地址,因为地址已经改变。
       write_com(x_adr);
       write_num(h_bit);
       write_num(l_bit);
       write_com(0x36);    //开显示
       write_com(0x30);    //转回基本指令集           
}



根据文字提示的内容,为什么第一次读取的数据不要? 为什么与运算之后就可以同时显示了?

想请教下前辈指点下,哪怕是提示下都可以。小弟先谢谢了

回复

使用道具 举报

ID:235207 发表于 2017-9-24 00:28 | 显示全部楼层
哈哈,我也不是很了解
回复

使用道具 举报

ID:123289 发表于 2017-9-24 10:03 | 显示全部楼层
画出逻辑框图或许你自己就明白了。
回复

使用道具 举报

ID:231376 发表于 2017-9-24 12:33 来自手机 | 显示全部楼层
yzwzfyz 发表于 2017-9-24 10:03
画出逻辑框图或许你自己就明白了。

写代码从来不画框图,其实我就是不理解他为啥莫名其妙要多读一次,我昨天想想是不是所谓二缓冲技术
回复

使用道具 举报

ID:111634 发表于 2017-9-25 22:16 | 显示全部楼层
笔名很牛人不牛
回复

使用道具 举报

ID:231376 发表于 2017-9-26 19:56 | 显示全部楼层
zl2168 发表于 2017-9-25 22:16
笔名很牛人不牛

搞了两天得到了答案~
回复

使用道具 举报

ID:231376 发表于 2017-9-26 20:14 | 显示全部楼层
还是写个解答吧,网上关于这个资料比较少(搜索了一遍,都是剪刀胶布,关键地方没有说明为什么):

首先12864并不是点对点,就是你写个(1,10)进去,它就能显示出个点来,大致就是横向128,每次控制16位,也就是为啥
你写了个字符进去会显示出那么大个的字出来。

基本上可以理解为:基地址+偏移量=最终显示(代码就是这个思路)

另外这个屏幕Y轴是分了32+32,过了32地址又从“0”开始;


1.png

这是st7920的datesheet,这个芯片读取分两种模式,一种是每次读取4位,读取两次,另一种是一次性读取8位。

其次每次读取一个字节是8位,这里又接着读取了两次,可以猜想一下是先读了高位,然后读取低位。

一个地址是16位,这样的话

Dummy是“假的”的意思,大意是“空读”,就是每次要先空读一次,才能读取到真正的信息。

bt是用户要写入的地址,为什么要“与”一下呢?

QQ截图20170926200633.png 看到这张图,我想你已经理解了。



        uint bt = 0, readValue = 0;
        uchar x_adr, y_adr, h_bit, l_bit;

        //--Y轴最大一共64,但是12864分为上半屏和下半屏,超过32就是下半屏了,--//
        //--地址得又从零开始了。所以对32求余数,得到Y轴的坐标,然后加上80H的基地址--//
        y_adr = 0x80 + y % 32;                //计算Y轴的地址       
       
        //--当Y大于31时是下半屏,X(水平位置的地址)是从88H开始的,而且它是16位一--//
        //--个地址,所以对16求模。而上半屏的地址是从80H开始的--//
        if(y>31)
        {
                x_adr = 0x88 + x / 16;        //计算X轴的地址
        }
       
        else
        {
                x_adr = 0x80 + x / 16;
        }
       
        //--求出X(水平位置),点亮的点是在16位数据里面的哪一个位--//
        //--所以对这个数求余数--//
        bt = 0x8000 >> (x % 16);


        LCD12864_ReadData();                  //读取的第一个字节不要,  //空读
        readValue = LCD12864_ReadData();          //从第二个字节开始接收。//真正的读取
//        readValue <<= 8;                                           //高8位
//        readValue |= LCD12864_ReadData();           //低8位
        bt = bt | readValue;
        h_bit = bt >> 8;
        l_bit = bt;




后记:就这么多信息,我觉得12864的核心就在这里,可能这点东西需要下个使用者研究上几天,最近对这种事情也很感慨,学校里在搞智能车,
做的稀烂,能完整跑一圈的没几个,一个个还保密的不得了,以前也是做C++逆向的,不喜欢国内这种风气。我也在想:是不是自己傻,别人问我的,只要我会的都会告诉对方,一旦自己遇到问题了每个能帮助的字节的人~

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:237272 发表于 2017-10-16 14:55 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表