原创 12864液晶显示资料及程序

2007-7-26 11:26 12012 11 21 分类: MCU/ 嵌入式

    今天终于完成了12864带字库液晶模块的图象和中英文字母显示,图象显示显示了自己的一副照片,呵呵,还认得出是自己,开心啊。。。硬件连接方式是:并口直接访问。


这是汉字显示程序:


#include<reg51.h>
#include<absacc.h>


#define uchar unsigned char


#define datawr 0x1200           //写数据通道
#define comwr 0x1000            //写控制命令通道
#define datare 0x1300           //读数据通道
#define comre 0x1100            //读忙通道


uchar code disp_data[]={"    浙江大学    "      //第一行,第一页
                        "04级通信工程一班"      //第三行
                        "  宁波理工学院  "      //第二行
                        "    竞赛小组    "      //第四行
                        "128X64液晶显示器"      //第一行,第二页
                        "    测试程序    "      //第三行
                        "  07年07月25日  "      //第二行
                        "    Tornado     "};    //第四行


void set12864();
void write_command(uchar command);
void write_page(uchar data_add);
void read_page(uchar data_add);
void delays(uchar cont);


void main()
{
    while(1)
    {
        set12864();             //初始化12864
        write_page(0);          //写入一页数据
        read_page(0x30);        //读出一页数据到内部RAM
        delays(2);              //延时2s
        write_page(64);         //写入下一页数据
        delays(2);              //延时2s
    }
}


//初始化12864子程序
void set12864()
{
    write_command(0x30);        //功能设定控制字
    write_command(0x0c);        //显示开关控制字
    write_command(0x01);        //清除屏幕控制字
    write_command(0x06);        //进入设定点控制字
}


//写控制命令子程序
void write_command(uchar command)
{
    bit flag="1";                 //12864空闲标志位
    while(flag)                 //检查12864是否空闲
        flag="XBYTE"[comre]&0x80;
    XBYTE[comwr]=command;       //空闲传送控制字
}


//写一页子程序
void write_page(uchar data_add)
{
    bit flag="1";                 //12864空闲标志位
    uchar num="64";               //64个循环,连续写入32个汉字或是64个西文字符
    write_command(0x80);
    for(;num>0;num--)
    {
        while(flag)             //检查12864是否空闲
            flag="XBYTE"[comre]&0x80;
        XBYTE[datawr]=disp_data[data_add++]; //空闲传送数据
    }
}


//读一页子程序
void read_page(uchar data_add)
{
    bit flag="1";                 //12864空闲标志位
    uchar num="64";               //64个循环,连续写入32个汉字或是64个西文字符
    write_command(0x80);
    for(;num>0;num--)
    {
        while(flag)             //检查12864是否空闲
            flag="XBYTE"[comre]&0x80;
        DBYTE[data_add++]=XBYTE[datare]; //空闲传送数据
    }
}


//延时cont秒子程序
void delays(uchar count)
{
    unsigned char h,i,j,k;
    do
    {
    for(h=5;h>0;h--)
    for(i=4;i>0;i--)
    for(j=116;j>0;j--)
    for(k=214;k>0;k--);
    }while(--count);
}


这是图象显示程序:


#include<reg51.h>
#include<absacc.h>


#define uchar unsigned char
#define uint unsigned int


#define datawr 0x1200           //写数据通道
#define comwr 0x1000            //写控制命令通道
#define datare 0x1300           //读数据通道
#define comre 0x1100            //读忙通道


uchar code disp_data[] =        // 数据表
{
      0x00,0x01,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,
      0x00,0x01,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,
      0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x00,
      0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,
      0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,
      0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x00,
      0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,
      0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x80,0x00,0x00,0x00,
      0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
      0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x07,0xFF,0xFF,
      0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x0B,0xFF,
      0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x1F,
      0x01,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,
      0x01,0xFF,0xFF,0xFF,0xF3,0x79,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,
      0x03,0xFF,0xFF,0xFF,0xE6,0x62,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x60,0x00,0x68,
      0x01,0xFF,0xFF,0xFE,0x00,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x00,0x00,0x0E,
      0x01,0xFF,0xFF,0xF8,0x00,0x4B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x8E,0x08,0x79,
      0x07,0xFF,0xFF,0xF0,0x00,0x41,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0xC0,0x07,0x61,
      0xC3,0xFF,0xFE,0xC0,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xEF,0x3F,
      0x83,0xFF,0xFE,0x60,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xC0,0xFF,0xFD,0xFC,0x6C,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xF0,0x7F,0xF3,0xFF,0xFE,0x60,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xF3,0xFF,0xFF,0x50,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,
      0xFB,0xFF,0xF1,0xF8,0x8C,0xD8,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x6F,0xD9,
      0xC2,0x3F,0xF8,0x40,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xDF,0x1E,0xFF,
      0xFF,0x7F,0xFC,0x38,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0x64,0x2F,0x6F,0xFF,
      0xFD,0x7B,0xFC,0x1F,0xE0,0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0x5F,0x7C,0xEE,0xFF,
      0xC7,0xFF,0xBC,0x0F,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFE,0xEF,0xFF,
      0xFF,0xE7,0xDC,0x07,0xE7,0xF8,0x12,0x7F,0xFF,0xFF,0xFF,0xFF,0x47,0xFF,0xFF,0xFF,
      0xFF,0xE7,0x80,0x03,0xF4,0x00,0x00,0x5F,0xFF,0xFF,0xFE,0xFE,0xE3,0xFF,0xFF,0xFF,
      0xFF,0xFE,0xC0,0x01,0xC0,0x00,0x00,0x1B,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x7F,0xEE,0xC0,0x00,0xC0,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFE,0x98,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x20,0x0E,0x60,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x8F,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x05,0x80,0xE0,0x00,0x00,0x00,0x00,0x01,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x09,0x80,0xA0,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x85,0x2A,0xC0,0x00,0x00,0x00,0x00,0x01,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
      0xBF,0xF3,0xC0,0x00,0x00,0x00,0x00,0x00,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,
      0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x01,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,
      0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xC0,0x1F,
      0xFF,0xFF,0x80,0x00,0x40,0x00,0x00,0x00,0xFF,0x80,0xFF,0xFF,0xFF,0x80,0x07,0xFF,
      0xFF,0xFF,0xC0,0x00,0xC0,0x00,0x00,0x01,0xFF,0x01,0xFF,0xFF,0xF8,0x00,0xFF,0xFF,
      0xFF,0xFF,0xE0,0x63,0x80,0x00,0x00,0x01,0xFE,0x01,0xFF,0x18,0x00,0x3F,0xFF,0xFF,
      0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x01,0xCC,0x01,0xFE,0x00,0x07,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x07,0xA0,0x03,0xFC,0x00,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x05,0xC0,0x03,0xC8,0x00,0x7F,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x19,0x00,0x00,0x88,0x0C,0x07,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFC,0x00,0x0C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xC0,0x7F,0xFF,0xFF,
      0xFF,0xFF,0xF8,0x07,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x0F,0xFF,0xFE,
      0xFF,0xFF,0xD0,0x07,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x03,0xFF,0xF8,
      0xFF,0xFC,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xC0,
      0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0xFF,0xF8,
      0xFF,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x1F,0xFE,
      0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x78,0x02,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,
      0xFF,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x02,0xFF,
      0xFE,0x00,0x00,0x00,0x00,0x00,0x1F,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,
      0xF0,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,
      0xE0,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,
      0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,
      0xC0,0x00,0x00,0x00,0x00,0x00,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
      0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
      0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
};


void set12864();
void setxy(uchar x,uchar y);
void write_command(uchar command);
void write_16byte(uint data_add);
void delays(uchar count);


void main()
{
    uchar x,y,i;
    while(1)
    {
        y="0x80";                     //设置液晶上半部分坐标
        x="0x80";
        delays(2);                  //延时2s
        set12864();                 //初始化12864
        delays(2);
        for(i=0;i<32;i++)           //写入液晶上半图象部分
        {                           //写入坐标
            setxy(x,y);
            write_16byte(i*16);     //连续写入16字节数据
            y++;                    //y轴地址加1
        }                          
        y="0x80";                     //设置液晶下半部分坐标
        x="0x88";
        for(i=0;i<32;i++)           //写入液晶下半图象部分
        {
            setxy(x,y);             //写入坐标
            write_16byte((32+i)*16);//连续写入16字节数据
            y++;                    //y轴地址加1
        }
        write_command(0x34);        //写入扩充指令命令
        write_command(0x36);        //显示图象
    }
}


//初始化12864子程序
void set12864()
{
    write_command(0x30);        //功能设定控制字
    write_command(0x0c);        //显示开关控制字
    write_command(0x01);        //清除屏幕控制字
    write_command(0x06);        //进入设定点控制字
}


//设置绘图坐标
void setxy(uchar x,uchar y)
{                              
    write_command(0x34);        //写入扩充指令命令
    write_command(y);           //写入y轴坐标
    write_command(x);           //写入x轴坐标
    write_command(0x30);        //写入基本指令命令
}


//写控制命令子程序
void write_command(uchar command)
{
    bit flag="1";                 //12864空闲标志位
    while(flag)                 //检查12864是否空闲
        flag="XBYTE"[comre]&0x80;
    XBYTE[comwr]=command;       //空闲传送控制字
}


void write_16byte(uint data_add)
{
    bit flag="1";                 //12864空闲标志位
    uchar num="16";               //16个循环,连续写入16个字节
    for(;num>0;num--)
    {
        while(flag)             //检查12864是否空闲
            flag="XBYTE"[comre]&0x80;
        XBYTE[datawr]=disp_data[data_add++]; //空闲传送数据
    }
}


//延时count秒子程序
void delays(uchar count)
{
    unsigned char h,i,j,k;
    do
    {
    for(h=5;h>0;h--)
    for(i=4;i>0;i--)
    for(j=116;j>0;j--)
    for(k=214;k>0;k--);
    }while(--count);
}


这是CM12864-20SLYA芯片资料pdf,这是汉字图象取模软件rar

文章评论10条评论)

登录后参与讨论

用户227870 2011-7-27 09:48

还有DBYTE[data_add++]=XBYTE[datare]; //空闲传送数据, 您这个数据是读到哪里去了,您用DBYTE来干什么,按您的程序来看是把数据读到了内部RAM 30H开始的地址处,这个函数有什么意义呢??抱歉,打扰了。我也是一个单片机初学者,看到您的程序,感觉比一般按照时序写的程序要高效,所以希望探讨一下!!忘指教!!

用户227870 2011-7-27 09:39

还有一个问题就是你的flag="XBYTE"[comre]&0x80;这句话,XBYTE为什么要打上双引号,而XBYTE[datawr]=disp_data[data_add++]; //空闲传送数据,而这句话的XBYTE却没有双引号,对于外部寻址中的关键字XBYTE打双引号与不打双引号有什么区别呢????

用户227870 2011-7-27 09:35

您好,对于你的这个程序我有几个问题请教一下!! 您这个程序应该是采用一种类似外部RAM扩展的方式来读写12864的吧!!这样的话是不是P0口不能够接上拉电阻,您电路中有没有接上拉电阻?上拉电阻会不会影响到数据读写。 还有就是您既然是外部扩展方式,P0口始终是作为数据/地址复用总线使用的(本来应该是通过ALE进行选择的,但是您的电路中P0口没有充当地址功能,但是在写入地址的时候P0口是不是还是会有数据送出的),当写入地址的时候P0口的数据对12864没有影响吗?? 外部RAM扩展方式的读写操作还应该受单片机的读写使能RD/WR控制的,而实际上您的电路应该没有受RD/WR控制,这样对读写数据没有影响吗?? 12864时序图中的数据读或写都是通过E的下降沿有效的(在下降沿的时候数据读入或者写出),而看您的程序应该一直是吧E引脚对应的地址为写1,这样可以吗?? 我测试您的程序好像没有显示,但是我感觉这种方式操作12864应该比传统时序控制方式更高效,特由此疑问,忘指导!!!

用户1657917 2008-4-13 13:45

proteus仿真我没试过,实际硬件上我试过,不行的话可以再来找我啊

用户1657917 2008-4-6 11:47

在绘图模式下读数据先设置好x、y轴,再读数据,要先空读一次(就是第一个读的数据是没用的)读的第二个数据才是真正设置好x、y轴地址的那个数据,每读一个数据x轴会自动加一的!最近也在写液晶程序,一直这么用的没问题!

用户9671 2008-3-7 21:08

void read_page(uchar data_add) 这个为什么要读一下呢

用户1657917 2007-8-13 19:03

编译不正确是程序还有问题,首先你要先把我的程序里的“”号去掉。再则,检查你的编译器是否支持c语言,还有什么问题再问我吧。。。

用户1657917 2007-8-11 14:35

这几个是12864的控制命令,就是控制RS、R/W的。最高的半字节因为我的电路P2.4连接一个控制信号是高电平才有效,所以为1。接下来的半字节是P2.1接RS,P2.0接R/W,所以就有0、1、2、3了作用就是注释说的。低字节是P0口接12864的数据口,是用来读写数据的,所以为0、1都无所谓。

简单说就是设置好RS、R/W,其他位都为X就可以了。

用户18333 2007-8-10 14:55

#define datawr 0x1200           //写数据通道
#define comwr 0x1000            //写控制命令通道
#define datare 0x1300           //读数据通道
#define comre 0x1100            //读忙通道

这几句话,究竟怎么分配的啊可以把12864的20个脚和51单片机的I/O说清楚吗

用户1657917 2007-7-26 11:35

哎,又出现了同样的问题,多了好多双引号" "哦,谁有什么办法解决的。先谢下。。。
相关推荐阅读
用户1657917 2008-06-24 15:10
STM32上位机控制演示软件
STM32项目/学习计划表项目名称 STM32上位机控制演示软件请点击以下链接更新您的个人资料(包括“职位,部门,单位名称,地址,邮编,电子邮箱,电话”),以便我们能及时联系您并快速发送开发套件。ht...
用户1657917 2008-04-03 16:27
串口调试软件V1.0
        这两天用VC++写了个串口调试软件,是用MSComm 控件编写的,虽然串口调试的软件多的满天飞,但是本人初涉串口编程,写这么个软件对以以后应用串口编程还是受益匪浅的。        这...
用户1657917 2008-04-01 16:03
关于radio button控件的使用问题
    用过这个控件的都知道他们之间都是互斥的,但是编程是总是找不到属性设置,在网上查找资料,上面说设置成一组就可以了。但是我把他们的GROUP属性选中了,但是运行时还是不行,没有办法再找,终于在一个...
用户1657917 2008-03-31 11:57
学习串口通信编程
    在公司实习也一个多月了,前段时间调好了AIAO板,接下来又有新任务了。。。准备设计编写基于RS485的多主多从协议,类似于IBM的Token Ring协议,先在电脑间联网写个VC程序测试,所以...
用户1657917 2008-02-21 15:05
汉字转Unicode软件
    这是我学了几天C++后所写的第一个软件,目的是出于前段时间学习AT指令时所需,使用AT指令发短信需要用Unicoe码发送汉字。也算是自己学习C++的练手软件,现在发布给有需要的朋友。本人的第一...
用户1657917 2007-09-25 22:35
DIY迷你CPLD核心板
    这两天用敷铜板做了块迷你的CPLD核心板,把所有的IO口全部都引了出来,还引出了几个CLK的脚,到今天为止已经钻孔、焊接、调试成功,正常下载程序了,呵呵,如有什么不足之处请各位大虾指出,不胜感...
我要评论
10
11
关闭 站长推荐上一条 /2 下一条