lzh电子论坛

欢迎来到lzh电子论坛:
如果您对电子技术感兴趣就加入我们吧!在这里互相交流互相学习!主要讨论的方向有:单片机,ARM,PCB板设计,FPGA,汇编,C/C++等方面。
-----lzh电子论坛
lzhbbs.forumotion.com
lzh电子论坛

电子的道路是孤独的,要懂得左手温暖右手,要懂得把debug当作快乐去欣赏,去享受,那样你才会成功...

欢迎访问lzh电子论坛。可通过【谷歌,SOSO,搜狗】搜索“lzh电子论坛”直接进入论坛。点击了解论坛详细制度


    关于12864任意打点函数源代码

    分享
    avatar
    PZ
    初级会员
    初级会员

    帖子数 : 4
    威望 : 0
    注册日期 : 13-01-15

    关于12864任意打点函数源代码

    帖子 由 PZ 于 2013-05-01, 4:14 pm

    有了这个函数再结合好的算法,便可以玩转12864屏幕的任意位置 Like a Star @ heaven

    代码:

    #include<reg52.h>                            //包含所要用到的头文件
    #include<intrins.h>                            //同上
    #define uchar unsigned char                      //宏定义变量类型
    #define uint unsigned int                      //同上
    #define lcd P0                               //宏定义P0的8位数据口



    sbit RW=P2^5;                               //定义数据/命令选择端
    sbit E=P2^6;                               //定义使能输出端
    sbit PSB=P2^1;                               //定义并串传输方式端
    sbit RS=P2^4;                               //定义读写选择端
    sbit RES=P2^3;                               //定义复位脚



    void delayms(uchar);                         //声明毫秒级延时函数
    void delayus(uchar);                         //声明微妙级延时函数
    void init_12864();                            //声明分块画图的液晶初始化函数
    void write_com(uchar);                         //声明写入命令函数
    void write_data(uchar);                         //声明写入数据函数
    void GUIfunction(uchar,uchar,uchar);             //声明任意打点函数
    uchar read_data();                            //声明读取数据函数
    void point(uchar,uchar,uchar,uchar);             //声明画直线函数
    void clear_up();                            //声明清屏函数
    void init();                               //声明整屏画图的液晶初始化函数






    void main()                                   //主函数
    {                                       
       init();                                 //调用整屏画图的液晶初始化函数
       clear_up();                              //调用清屏函数
       init_12864();                           //调用分块画图的初始化函数
       point(5,121,16,1);                        //调用画直线函数
       point(5,121,17,1);                        //同上
       point(5,121,18,1);                        //同上
       while(1);                              //屏幕在此处显示稳定
    }




    void delayus(uchar xus)                        //定义微妙级函数,后面你懂得,亲!
    {
       uchar uscnt;                          
       uscnt=xus>>1;
       while(--uscnt);
    }




    void delayms(uchar xms)                       //定义毫秒级函数,后面你懂得,亲!
    {
       while(--xms)
       {
          delayus(250);
          delayus(250);
          delayus(250);
          delayus(250);   
       }
    }





    void init_12864()                             //定义分块画图的液晶初始化函数
    {
       delayms(15);                           //延时15MS让数据稳定下
       write_com(0x30);                        //写入基本指令
       write_com(0x06);                        //
       write_com(0x0c);
       write_com(0x01);
    }




    void write_com(uchar com)                       //定义写指令函数
    {
       delayms(15);                             //延时15MS让数据稳定一下
       RS=0;                                   //以下源代码参考时序图
       RW=0;
       E=0;
       delayus(40);
       E=1;
       lcd=com;
       delayus(400);
       E=0;
       RS=1;
    }




    void write_data(uchar dat)                       //定义写数据函数
    {
       delayms(15);                             //延时让数据稳定
       RS=1;                                   //参考时序图
       RW=0;
       E=0;
       delayus(40);
       E=1;
       lcd=dat;
       delayus(400);
       E=0;
       RS=0;   
    }




    uchar read_data()                            //定义读取数据函数
    {
       uchar temp;
       lcd=0Xff;                              //释放数据线
       RS=1;                                   //以下敬请参考时序图
       RW=1;                                   
       E=1;                                  
       delayus(40);                           
       temp=lcd;
       delayus(400);
       E=0;
       RS=0;
       return temp;
    }





    void GUIfunction(uchar x,uchar y,uchar color)       //定义任意打点函数
    {
       uchar x_byte,x_bit;            //定义两个变量:分别存放水平字符的哪一位字节和水平的哪一位
       uchar y_bit;               //定义此变量存放列的位,用来表示此刻在哪一行
       uchar pos_h,pos_l;            //定义两个变量:分别存放从液晶读取数据的高字节和低字节
       x_byte=x/16;               //x为输入的0-127之间的数,x/16表示此时该点在水平方向上的哪一个字节
       x_bit=x%16;                  //x%16表示此时该点在水平方向上哪个字节的哪一位
       if(y<32)                  //判断此时行是否<32
          y_bit=y;               //y<32表示此时给出的数据在液晶的上半个屏幕
       else                     //否则y>32,则此时在液晶的下半屏
       {   
          y_bit=y-32;               //Y-32确定了数据在下半行的具体哪一行
          x_byte+=8;               //水平字节加8位,将打点的位置移到下半行,注意:在液晶的水平方向上,我们规定一个字节为16位,则水平方向上只有8个字节。
       }   
       //write_com(y_bit+0x80);      //这里不要急着写入判断出来的地址
       //write_com(x_byte+0x80);      //同上
       write_com(0x34);            //写入扩充指令
       write_com(y_bit+0x80);         //地址入口在这里写
       write_com(x_byte+0x80);         //同上,不过千万注意:要先写y方向上的,再写x方向上的。这是血的教训,呜呜呜~~~
       read_data();               //千万千万注意:在这里一定要空读数据一次,不然出错。。。。。具体为什么还有待深入研究!
       pos_h=read_data();            //将读取的数据的高8位赋给POS_H
       pos_l=read_data();            //将读取的数据的低8位赋给POS_L
       //write_com(x_byte+0x80);      //在这里也不要写入地址
       //write_com(y_bit+0x80);      //同上
       if(x_bit<8)                  //判断该点是在某字节高位还是低位
       {                        //注意<8此时在高位
          switch(color)            //switch语句选择打点的颜色
          {
             case 0:               //0是白色
             pos_h&=(~(0x01<<(7-x_bit)));    //0x01左移(7-x_bit)位刚好是该点的位置,如果读到的数据在这是1,则会变成0,因为取反且与的缘故,如果是0就会还是0,则可以起到该点恒为0的作用,反映在液晶上就是白色
             break;                      //跳出switch语句
             case 1:                      //1是黑色
             pos_h|=((0x01<<(7-x_bit)));       //0x01左移(7-x_bit)位刚好是该点的位置,如果读到的数据在这是0,则会变成1,因为或的缘故,如果是1就会还是1,则可以起到该点恒为1的作用,反映在液晶上就是黑色
             break;                      //跳出switch语句
             case 2:                      //2是取反,及0变1,1变0
             pos_h^=((0x01<<(7-x_bit)));       //0x01左移(7-x_bit)位刚好是该点的位置,如果读到的数据在这是0,则会变成1,因为异或的缘故,如果是1就会是0,则可以起到该点恒为反的作用,反映在液晶上就是和原来颜色相反
             break;                      //跳出switch语句
          }
          write_com(y_bit+0x80);             //在这里写入入口地址,同样是先写y方向上的,再写x方向上的
          write_com(x_byte+0x80);             //写入x方向上的地址
          write_data(pos_h);                //写入高位数据,同样要先写高位
          write_data(pos_l);                //写入低位数据
       }
       else                            //否则在低位
       {
       switch(color)                      //进入switch语句
          {
             case 0:                      //0是白色
             pos_l&=(~(0x01<<(15-x_bit)));    //0x01左移(15-x_bit)位刚好是该点的位置,如果读到的数据在这是1,则会变成0,因为取反且与的缘故,如果是0就会还是0,则可以起到该点恒为0的作用,反映在液晶上就是白色
             break;                      //跳出switch语句
             case 1:                      //1是白色
             pos_l|=((0x01<<(15-x_bit)));    //0x01左移(15-x_bit)位刚好是该点的位置,如果读到的数据在这是0,则会变成1,因为或的缘故,如果是1就会还是1,则可以起到该点恒为1的作用,反映在液晶上就是黑色
             break;                      //跳出switch语句
             case 2:                      //2是取反,及0变1,1变0
             pos_l^=((0x01<<(15-x_bit)));    //0x01左移(15-x_bit)位刚好是该点的位置,如果读到的数据在这是0,则会变成1,因为异或的缘故,如果是1就会是0,则可以起到该点恒为反的作用,反映在液晶上就是和原来颜色相反
             break;                      //跳出switch语句
          }   
          write_com(y_bit+0x80);             //在这里写入入口地址,同样是先写y方向上的,再写x方向上的
          write_com(x_byte+0x80);             //写入x方向上的地址
          write_data(pos_h);                //写入高位数据,同样要先写高位
          write_data(pos_l);                //写入低位数据
       }
       write_com(0x36);                   //关闭扩充指令
       write_com(0x30);                   //写入基本指令函数
    }



    void point(uchar x0,uchar x1,uchar y,uchar color)   //调用画线函数
    {                                //x0是水平方向的起始点,x2是水平方向的截止点,color决定颜色
       uchar t;                     //定义中间变量t
       if(x0>x1)                     //如果起始点大于截止点就互换,始终保证起始点小于截止点
       {
          t=x0;
          x0=x1;
          x1=t;   
       }
       for(;x0<x1;x0++)               //利用for循环来完成X0到X1之间的打点
           GUIfunction(x0,y,color);      //利用GUI函数完成打一个点的工作
    }




    void clear_up()                        //定义清屏函数
    {
       uchar a,b,c,x,y;
       x=0x80;                           //x是数据在液晶中的水平字节地址
       y=0x80;                           //y是数据在竖直方向的位地址
       
       for(a=0;a<2;a++)                  //循环两次,使上下屏幕的数据写入液晶
       {
          for(b=0;b<32;b++)               //循环32次,把上半个屏幕数据写入液晶
          {
             write_com(y+b);                //每给完每一行的数据,竖直方向的位就加一,继续下一行,一共有32行
             write_com(x);               //写入水平方向的此时的字节地址
             for(c=0;c<16;c++)            //循环16次,当给完2个字节数值,X自动加一,继续写下一个“字节”,注意这里的“字节是16位而不是传统的8位”,直到给完8个“字节”
             {
                write_data(0x00);         //每个字节都00清屏
             }
          }
          x=0x88;                        //水平地址换到屏幕的下半部分
       }
    }




    void init()                            //该初始化方式为画图方式的初始化
    {
       delayms(40);                       //大于40MS的延时程序
       PSB=1;                             //设置为8BIT并口工作模式
       delayus(5);                          //延时
       RES=0;                             //复位
       delayus(1);                          //延时
        RES=1;                                 //复位置高
        delayus(10);
          
       write_com(0x36);                    //初始化指令
       delayms(1);
       write_com(0x36);
       delayms(1);
       write_com(0x3e);
       delayms(1);
       write_com(0x01);
       delayms(1);
    }
     

    附件
    12864分块画图.zip
    您无权下载这里的附件。
    (38 Kb) 下载4次
    avatar
    寒夜
    中级会员
    中级会员

    帖子数 : 34
    威望 : 0
    注册日期 : 13-04-22

    回复: 关于12864任意打点函数源代码

    帖子 由 寒夜 于 2013-05-01, 4:38 pm

    呵呵,楼主对12864玩的挺多的啊!!多谢楼主分享代码了
    avatar
    mcusb
    中级会员
    中级会员

    帖子数 : 46
    威望 : 3
    注册日期 : 13-01-28

    回复: 关于12864任意打点函数源代码

    帖子 由 mcusb 于 2013-05-01, 4:52 pm

    楼主可以搞一下那个啊,就是在屏幕上画任意直线,我以前搞过,感觉不是很容易的,如果楼主搞出来了就共享出来大家看看把.....跪求代码 Surprised

      目前的日期/时间是2018-09-22, 1:23 am