Lost_boy 发表于 2011-12-8 17:40:43

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

这是用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        codeLCD_data4[];
uchar        code LCD_picture1[];           //人物图
uchar        code LCD_picture2[];          //梦回广德
uchar   code LCD_picture3[];          //小兔子
uchar         code menu_pic[];          //标签图(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 agirl"
                "人生若只如初见?"
                "何事秋风悲画扇!"       
};

uchar        code LCD_data3[] ={

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

uint        codeLCD_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后自动变为00h80h-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);
                                        write_data(~LCD_picture3);
                                }
                        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);
                                write_data(~menu_pic);
                        }
                        else                                       // 正常显示
                        {
                                write_data(menu_pic);
                                write_data(menu_pic);
                        }
                }
                        y++;                                   //24+8=32
//                        if(y==32&&menu_num<3) {x+=8;y=0;}   // 跳入下一屏横坐标地址地址到0x88y 地址变成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);
                                write_data(~menu_pic);
                        }
                        else                                          // 正常显示
                        {
                                write_data(menu_pic);
                                write_data(menu_pic);
                        }
                }
                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);
                                write_data(~menu_pic);
                        }
                        else                                          // 正常显示
                        {
                                write_data(menu_pic);
                                write_data(menu_pic);
                        }
                }
                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);                       
}

dyxganj 发表于 2011-12-12 20:34:21

太好了!学习一下!谢谢分享!!

hlfqzy 发表于 2012-8-6 13:00:55

太好了!学习一下!谢谢分享!!

EBPUN_safan 发表于 2012-8-6 13:32:50

mark!留着学习!

eryueniao 发表于 2012-8-6 13:48:04

不错                                                                                                      

cyq001 发表于 2012-8-6 14:14:27

不错,谢谢

lxa0 发表于 2012-8-6 21:53:28

大家都说好
可惜看不懂~~~~~~~~~~~

lpantonie 发表于 2012-8-7 13:29:40

貌似没有画任意两点直线~
还可以加清除指定区域的函数

liycobl 发表于 2012-8-7 15:37:35

mark       ,

tangzhipeng12 发表于 2012-8-7 16:29:02

{:lol:}学习学习

kxm2008 发表于 2012-8-7 17:33:05

留着备用

actshuishan 发表于 2012-8-8 07:29:55

多谢楼主,收藏学习

司马朝阳007 发表于 2012-8-8 07:44:30

谢谢分享{:smile:}

yzbdzh 发表于 2012-8-8 08:27:33

嗯,蛮好的,准备去买一个12864学习一下

jetli 发表于 2012-8-8 08:28:52

st7920,还用并行,浪费,

pnsyzx20088hlq 发表于 2012-8-8 17:33:51

我想让12864显示温度要怎么做呢?

f43 发表于 2012-8-8 17:35:25

楼主考虑的果然是很周到啊,谢谢了

bg9gas 发表于 2012-8-8 18:18:34

收藏了谢楼主

a312835782 发表于 2012-8-9 22:51:20

这还不够呢。。。   绘图模式下,什么画圆之类的
页: [1]
查看完整版本: 12864液晶屏显示程序(几乎你能用12864干得 我都搞定了 哈哈)