搜索
bottom↓
回复: 18

12864液晶屏显示程序(几乎你能用12864干得 我都搞定了 哈哈)

[复制链接]

出0入0汤圆

发表于 2011-12-8 17:40:43 | 显示全部楼层 |阅读模式
这是用STC89C52单片机为核心板 全部都试验过 可以直接用  可作为模版



void        init()
{   PCON=0x00;         //单片机处于正常工作状态
    TMOD=0x20;        //定时器1工作在方式2     8位自动从装系统
    TH1=0xfd;
    TL1=0xfd;                 // 首次的装初值         9600
        TI=0;                        //发送中断标志位
        RI=0;                        //接受中断标志位
    TR1=1;                         //定时器1控制        允许位
    TF1=0;                //定时器1中断标志位
        SM0=0;
        SM1=1;
        REN=1;
        EA=1;
        ES=1;                  //打开串口中断
}



3、12864液晶屏(蓝底黑字)   51单片机显示  史上最全的显示内容 (自己总结的)
#include<stdio.h>               //调用数据类型
#include<reg52.h>                    //调用52引脚定义
#include<string.h>                            //字符操作指令         
#include<math.h>
#define        uint unsigned int
#define uchar unsigned char
uchar        code LCD_data1[];        
uchar        code LCD_data2[];
uint        code  LCD_data4[];
uchar        code LCD_picture1[];             //人物图
uchar        code LCD_picture2[];            //梦回广德
uchar   code LCD_picture3[];            //小兔子
uchar         code menu_pic[][96];            //标签图(6副)
sbit RS = P2^4;                                                 //并行指令数据选择信号
sbit RW = P2^5;                                                 //读写选择信号
sbit EN = P2^6;                                                //使能端
sbit PSB = P2^1;                                        //H并口数据   L串口数据
sbit RST = P2^3;                                            //复位  低电平有效
sbit Dataport = P0;
sbit Busyport = P0^7;                                //因为写指令时最高位为 BF
///////////////////////////////////////////////

uchar        code LCD_data1[]=
{
                "菩提本无树,    "
                "明镜亦非台!    "
                "本来无一物,    "
                "何处惹尘埃?    "


};
uchar        code LCD_data2[] ={

                "there is more   "
                "god   is a  girl"
                "人生若只如初见?"
                "何事秋风悲画扇!"       
};

uchar        code LCD_data3[] ={

                "E 通科技社!    "
                "                "
                "                "
                "                "       
};

uint        code  LCD_data4[] = {156};

void        delay_10ms(unsigned int n)                   //n*15ms延迟
{
        unsigned int i,j;
        for(i=n;i>0;i--)
                for(j=2000;j>0;j--);
}

void        delay(unsigned int n)                       //n*1us延迟                   可以通过debug测试
{
        unsigned int i,j;
        for(i=n;i>0;i--)
                for(j=10;j>0;j--);
}
///////////////  判断 BF 信号////////////////////

void check_LCD_busy(void)
{
        Dataport = 0xff;      
        RS = 0;                                        
        RW = 1;                         //读取液晶状态(BF)
        EN = 1;
        while(Busyport);    //液晶工作时 BF 为1,   等待指令执行完成 后认为置零
        EN = 0;
}


//////////////////写指令//////////////
void write_com(uchar command)
{
        check_LCD_busy();
        RS = 0;                 //命令
        RW = 0;
        delay(1);
        P0 = command;
        EN = 1;
        delay(1);
        EN = 0;
        RS = 0;
        delay(2);
        RW = 1;               
}

/////////////写数据//////////////////////////
void write_data(uchar dat)
{
        check_LCD_busy();
        RW = 0;       
        RS = 1;
        delay(1);
        P0 = dat;
        EN = 1;
        delay(1);
        EN = 0;
        RS = 0;
        delay(2);
        RW = 1;               
}

//////////////清屏函数//////////////
void lcdClear(void)
{
        write_com(0x01);          //清屏指令       
}

///////////////复位函数//////////////
void reset(void)
{
        RST = 0;                        //低电平复位
        delay(1);
        RST = 1;
        delay(10);
}


///////////////////////////////////清除GDRAM函数/////////////////////////////////////////////////
void Lcd12864_ClrGdRam(void)                                        //说明一点 在DRAM 中第三行地址连着第一行地址 第四行地址连着第二行地址
{
        uchar i,j,x;
        i=0x80;
        write_com(0x34);                     //开扩展指令集  
        for(j = 0;j < 32;j ++)             //每一个汉字纵向有16个格
                {  
                         write_com(i++);         //横坐标
                         write_com(0x80);                 //列坐标
                        for(x = 0;x < 32;x ++)
                                {
                                        write_data(0x00);    //地址清零
                                }
                }
        write_com(0x30);                     //返回基本指令集  
}


///////////书写汉字///////////////////////此程序也可用于字符串显示////////////////
void dispSting(uchar X,Y,uchar *mesg)                    //定点显示字符
{
        if(X==0)  X=0x80;
        else if(X==1) X=0x90;
        else if(X==2)  X=0x88;
        else X=0x98;
        Y = X + Y;
        write_com(Y);
        while(*mesg)
                {
                        write_data(*mesg);
                        mesg++;
                }
}


///////////////全屏字符显示///////////////////////////////////

void   lcd_mesg(unsigned char code *adder1)            //全屏显示字符
{
        unsigned char i;
    write_com(0x80);  
    delay(100);
        for(i=0;i<16;i++)
                {
                          write_data(*adder1);
                           adder1++;
                }
       
        write_com(0x90);  
    delay(100);
        for(i=16;i<32;i++)
                {
                          write_data(*adder1);
                           adder1++;
                }

    write_com(0x88);  
    delay(100);
        for(i=32;i<48;i++)
                {
                          write_data(*adder1);
                           adder1++;
                }

        write_com(0x98);  
    delay(100);
        for(i=48;i<64;i++)
                {
                          write_data(*adder1);
                           adder1++;
                }                
}

/////////////////显示字符串(定位写入字符串函数)//////////////////////////////////////////////////////////

void Lcd_wrnum(uchar x,y,uint code *num)
{
        write_com(0x30);
        y = y % 7 ;                                                                                                        //舍去大于八的数据
        switch(x)
        {
                case 1:
                        write_com(0x80 + y); break;
                case 2:       
                        write_com(0x90 + y); break;
                case 3:
                        write_com(0x88 + y); break;
                case 4:
                        write_com(0x98 + y); break;
                default:
                        break;                       
        }

                if(*num / 100 != 0)
                write_data(0x30 + *num / 100);
                if(*num / 10 % 10 != 0)
                write_data(0x30 + *num / 10 % 10);
                write_data(0x30 + *num % 10);
}


///////////////全屏显示图像(128*64)///////////////////////////////////////////
void disppicture(uchar code *adder)
{                  
        uint i,j;
////////////显示上半屏内容//////////////////////////
        for(i=0;i<32;i++)
        {
                write_com(0x80+i);                   //写垂直地址              垂直地址不能自动加1
                write_com(0x80);                  //写水平地址                 水平地址从00到0f后自动变为00h  80h-87h and 90h-97h
                for(j=0;j<16;j++)                 //两个字节一块显示  
                        {
                                write_data(*adder);
                                adder++;
                        }
        }
///////////////显示下半屏内容///////////////
        for(i=0;i<32;i++)
        {
                write_com(0x80+i);                  //写垂直地址              垂直地址不能自动加1
                write_com(0x88);                  //写水平地址                 水平地址从00到0f后自动变为00h   88h-8fh 和  98h-9fh
                for(j=0;j<16;j++)                 
                        {
                                write_data(*adder);
                                adder++;
                        }
        }
}

///////////////显示半屏(下)内容//////////////////

void disppicture1()
{
        uchar i,j,y;
        ///////////////显示下半屏内容///////////////

                for(j=0;j<32;j++)
                {
                        for(i=0;i<8;i++)
                                {       
                                        write_com(0x34);
                                        write_com(0x80+y);                  //写垂直地址              垂直地址不能自动加1
                                        write_com(0x88+i);                  //若改为0x80  则是显示上半屏
                                        write_com(0x30);
                                        write_data(~LCD_picture3[j*16+i*2]);
                                        write_data(~LCD_picture3[j*16+i*2+1]);
                                }
                        y++;
                }
                write_com(0x36);
}

/////////////////////////////////不同的位置画图(6副图片)////////////////////////////////////////////////////

void Lcd12864_anti_nor_pic (uchar cpl_sign,uchar menu_num)
{
        uchar i,j,x,y;
        x=menu_num*3;                                           // 计算图片显示横坐标   为 0x80+(00h 03h 06h 08 0b 0e        )
        if(x>6) x--;
         y=8;
        for(j=0;j<24;j++)
        {
                for(i=0;i<2;i++)                        //该图片大小为16*24
                {
                        write_com(0x34);                //打开扩充指令集
                        write_com(0x80+y);                //写列坐标地址
                        write_com(0x80+x+i);    //分两次显示 16bit         (i可以不要  因为横坐标是自动加的)
                        write_com(0x30);                //基本指令集
                        if(cpl_sign==1)                      // 图片反选
                        {
                                write_data(~menu_pic[menu_num][j*4+i*2]);
                                write_data(~menu_pic[menu_num][j*4+i*2+1]);
                        }
                        else                                         // 正常显示
                        {
                                write_data(menu_pic[menu_num][j*4+i*2]);
                                write_data(menu_pic[menu_num][j*4+i*2+1]);
                        }
                }
                        y++;                                     //24+8=32
//                        if(y==32&&menu_num<3) {x+=8;y=0;}   // 跳入下一屏  横坐标地址地址到0x88  y 地址变成0x80  (个人觉得这句话在这里面很是没有必要 可能就是起到了指针转移的作用了)
        }
                        write_com(0x36);                   //开绘图显示  G=1
}

       
///////////////显示上下两幅图片/////////////////////////
void Lcd12864_anti_nor_2pic (uchar cpl_sign,uchar menu_num)
{
        uchar i,j,x,y;
        if(menu_num==0)                  //写横坐标
                x=2;       
                else
                x=10;
                y=8;
        for(j=0;j<24;j++)                                  //        图片大小为32*24
        {
                for(i=0;i<2;i++)                  //连写两个字节
                {
                        write_com(0x34);                  //开启扩展指令集
                        write_com(0x80+y);                  //写列地址
                        write_com(0x80+x+i);                    //纵坐标写满  横坐标 上下分别为0x82  、0x88+02
                        write_com(0x30);
                        if(cpl_sign==1)                        // 图片反选 (跟你的取字模的方式有关)
                        {
                                write_data(~menu_pic[menu_num][j*4+i*2]);
                                write_data(~menu_pic[menu_num][j*4+i*2+1]);
                        }
                        else                                          // 正常显示
                        {
                                write_data(menu_pic[menu_num][j*4+i*2]);
                                write_data(menu_pic[menu_num][j*4+i*2+1]);
                        }
                }
                y++;
//                if(y==32&&menu_num==0) {x+=8;y=0;}  
        }
        write_com(0x36);                                //图像显示
}


///////////////显示上下4幅图片/////////////////////////
void Lcd12864_anti_nor_4pic (uchar cpl_sign,uchar menu_num)
{
        uchar i,j,x,y;
        x=menu_num*3;
        if(x==0)                           //0x80
                {
                        x=x+2;
                }
         else if(x==3)                        //0x83
                 {
                        x=x+2;
                }
         else if(x==6)                        //0x8a
                 {
                        x=x+4;
            }
         else if(x==9)                        //0x8d
                 {
                        x=x+4;
                }
          y=8;
        for(j=0;j<24;j++)                                  //        图片大小为32*24
        {
                for(i=0;i<2;i++)                  //连写两个字节
                {
                        write_com(0x34);                  //开启扩展指令集
                        write_com(0x80+y);                  //写列地址
                        write_com(0x80+x+i);                    //纵坐标写满  横坐标 上下分别为0x82  、0x88+02
                        write_com(0x30);
                        if(cpl_sign==1)                        // 图片反选 (跟你的取字模的方式有关)
                        {
                                write_data(~menu_pic[menu_num][j*4+i*2]);
                                write_data(~menu_pic[menu_num][j*4+i*2+1]);
                        }
                        else                                          // 正常显示
                        {
                                write_data(menu_pic[menu_num][j*4+i*2]);
                                write_data(menu_pic[menu_num][j*4+i*2+1]);
                        }
                }
                y++;
        }
        write_com(0x36);                                //图像显示
}

////////////////lcd字符初始化//////////////////////////////////
void lcdinit_str(void)
{
        delay(100);          
        PSB=1;                                                //八位并行串口方式
        delay(100);          
        reset();                                           //复位
        write_com(0x30);                    //设置基本指令集  DL 必须为1   G=0;绘图显示off
        delay(100);          
        write_com(0x30);                           //判断是否设置完
        delay(100);   
        write_com(0x08);                     //关掉显示  关掉游标
        delay(100);
        write_com(0x10);                        //设置游标位置  允许光标设置移动
        delay(100);
        write_com(0x0C);                           //整体显示开
        delay(100);
        write_com(0x01);                    //清屏
        delay(100);
        write_com(0x06);                          // 光标从右向左加一位移动
        delay(100);       
}  

//////////////LCD图片初始化/////////////////
void lcdinit_pic(void)
{
        delay(40);                     //大于40ms延迟程序
        PSB=1;                                 //设置8位并口工作模式
        delay(1);
        reset();
        write_com(0x36);         //扩充指令集   开启绘图显示
        delay_10ms(10);             //延迟100ms
        write_com(0x36);     //判断是否设置完
        delay(50);           //大于37us
        write_com(0x3E);     //是否真需要  
        delay_10ms(10);
        write_com(0x01);         //清屏
        delay(100);               
}
//////////////////主程序////////////////////////////////////////
void main()
{
                lcdinit_str();                                                        //全屏字符显示部分
                delay_10ms(10);
                lcd_mesg(LCD_data1);
                delay_10ms(200);
                delay_10ms(200);

                lcdClear();                                                           //清屏

                delay_10ms(10);                                                   //利用定点显示字符函数全屏显示
                dispSting(0,0,"床前明月光,");
                delay_10ms(10);
                dispSting(1,0,"疑是地上霜。");
                delay_10ms(10);   //
                dispSting(2,0,"举头望明月,");
                delay_10ms(10);
                dispSting(3,0,"低头思故乡!");
                delay_10ms(200);          
                delay_10ms(200);  
                       
                lcdClear();                                                                 //清屏
                   lcdinit_str();                                                         //显示字符和ASICⅡ码

                Lcd_wrnum(3,4,LCD_data4);                                 //第 行第 列显示字符串(定点显示字符串)
                delay_10ms(200);          
                delay_10ms(200);

                lcdClear();                                                                 //清屏

               
                lcdinit_str();                                                         //显示字符和ASICⅡ码
                delay_10ms(10);   
                lcd_mesg(LCD_data2);
                delay_10ms(200);
                delay_10ms(200);

                Lcd12864_ClrGdRam();                                         //全屏显示人物图片
            lcdClear();                                                                                 
                delay_10ms(10);       
                lcdinit_pic();                                                        
                delay_10ms(10);
                disppicture(LCD_picture1);
                delay_10ms(500);

                delay_10ms(10);
                disppicture(LCD_picture2);                                  //显示“梦回广德”艺术字
                delay_10ms(500);

                Lcd12864_ClrGdRam();                                         
            lcdClear();       

                delay_10ms(10);                                                                //显示两幅图片
                Lcd12864_anti_nor_2pic (1,0);
                delay_10ms(100);
                Lcd12864_anti_nor_2pic(1,1);
                delay_10ms(1000);                                  

                Lcd12864_ClrGdRam();                                            //字符汉字一块显示
            lcdClear();       
                lcdinit_str();        
                delay_10ms(1);
                lcd_mesg(LCD_data3);             
                               
                delay_10ms(10);       
                disppicture1();       
                delay_10ms(2000);

                Lcd12864_ClrGdRam();                                                //显示四副图片
            lcdClear();                                                                                 
       
                delay_10ms(10);       
                Lcd12864_anti_nor_4pic(1,0);
                delay_10ms(100);
                Lcd12864_anti_nor_4pic(1,1);
                delay_10ms(100);
                Lcd12864_anti_nor_4pic(1,2);
                delay_10ms(100);
                Lcd12864_anti_nor_4pic(1,3);
                delay_10ms(1000);


                Lcd12864_ClrGdRam();                                           //显示六副图片
            lcdClear();                                                                                 
       
                delay_10ms(10);       
                Lcd12864_anti_nor_pic(1,0);
                delay_10ms(100);
                Lcd12864_anti_nor_pic(1,1);
                delay_10ms(100);
                Lcd12864_anti_nor_pic(1,2);
                delay_10ms(100);
                Lcd12864_anti_nor_pic(1,3);
                delay_10ms(100);
                Lcd12864_anti_nor_pic(1,4);
                delay_10ms(100);
                Lcd12864_anti_nor_pic(1,5);
                delay_10ms(100);   
                delay_10ms(12200);   
                while(1);                       
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-12-12 20:34:21 | 显示全部楼层
太好了!学习一下!谢谢分享!!

出0入0汤圆

发表于 2012-8-6 13:00:55 | 显示全部楼层
太好了!学习一下!谢谢分享!!

出0入0汤圆

发表于 2012-8-6 13:32:50 | 显示全部楼层
mark!留着学习!

出0入0汤圆

发表于 2012-8-6 13:48:04 | 显示全部楼层
不错                                                                                                      

出0入0汤圆

发表于 2012-8-6 14:14:27 | 显示全部楼层
不错,谢谢

出0入0汤圆

发表于 2012-8-6 21:53:28 | 显示全部楼层
大家都说好
可惜看不懂~~~~~~~~~~~

出0入0汤圆

发表于 2012-8-7 13:29:40 | 显示全部楼层
貌似没有画任意两点直线~
还可以加清除指定区域的函数

出0入0汤圆

发表于 2012-8-7 15:37:35 来自手机 | 显示全部楼层
mark       ,

出0入0汤圆

发表于 2012-8-7 16:29:02 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2012-8-7 17:33:05 | 显示全部楼层
留着备用

出0入0汤圆

发表于 2012-8-8 07:29:55 来自手机 | 显示全部楼层
多谢楼主,收藏学习

出0入0汤圆

发表于 2012-8-8 07:44:30 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-8-8 08:27:33 | 显示全部楼层
嗯,蛮好的,准备去买一个12864学习一下

出0入0汤圆

发表于 2012-8-8 08:28:52 | 显示全部楼层
st7920,还用并行,浪费,

出0入0汤圆

发表于 2012-8-8 17:33:51 | 显示全部楼层
我想让12864显示温度要怎么做呢?

出0入0汤圆

发表于 2012-8-8 17:35:25 | 显示全部楼层
楼主考虑的果然是很周到啊,谢谢了

出0入0汤圆

发表于 2012-8-8 18:18:34 | 显示全部楼层
收藏了  谢楼主

出0入0汤圆

发表于 2012-8-9 22:51:20 | 显示全部楼层
这还不够呢。。。   绘图模式下,什么画圆之类的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 22:10

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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