打印
[STC单片机]

LCD12864液晶显示器的并行驱动(4位)

[复制链接]
1587|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhangjw258|  楼主 | 2018-3-17 09:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhangjw258 于 2018-3-17 11:46 编辑

LCD12864液晶显示器的并行驱动(4位)

这个帖子是对前一篇的补充。

1.  什么叫二值图象?
    通俗点说就是黑白图象.图象是由象素点组成的,描述图象的每一个象素点只用一个位(bit)就够了,非1即0,这样的图象就是二值图象.特点是图形文件占用空间少,图象只有黑白两色。
2.  前文中曾提到并口方式有两种, 一种是8位数据口,一种是4位数据口.
    对于总线方式的单片机,或者对于接口资源丰富的单片机来说,8位数据口既方便数据传输速度又快.程序编写也简单.但如果又想传输速度快,又不能使用8位或者想节约数据口的情况下,用4位数据口也是一个不错的选择.只要将功能设定中的DL位置0即可.下面的程序代码就是使用4位并口设计的.原代码中相同的地方就不贴了,免得浪费大家时间,只补充不同的部分.只有12864.h和12864.c以及main.c文件有变化.

//12864.h文件
#ifndef __12864_H__
#define __12864_H__

#include <reg52.h>
#include "ZhangType.h"
#include "fun.h"

#define    SETMODE8           0x30     //并口8位数据接口,DL = 1,基本指令
#define    SETMODE8_OFF   0x34     //并行8位数据接口,DL = 1,绘图OFF
#define    SETMODE8_ON    0x36     //并行8位数据接口,DL = 1,绘图ON
#define    SETMODE4           0x20     //并行4位数据接口,DL = 0,基本指令
#define    SETMODE4_OFF   0x24     //并行4位数据接口,DL = 0,绘图OFF
#define    SETMODE4_ON    0x26     //并行4位数据接口,DL = 0,绘图ON
#define    DISOPEN              0x0C    //显示开,不显示光标,光标不闪烁
#define    DISMODE              0x06    //读写字符后地址加1,屏显不移动
#define    SETADDR1            0x80    //设置数据地址指针第一行
#define    SETADDR2            0x90    //设置数据地址指针第二行
#define    SETADDR3            0x88    //设置数据地址指针第三行
#define    SETADDR4            0x98    //设置数据地址指针第四行
#define    CLEAR                   0x01    //清屏,数据指针清零
#define    RET                        0x02    //回车,数据指针清零

sbit RS  = P2^0;                                 //注意这三行
sbit RW = P2^1;                                 //说明下面用P2数据口传输数据不会影响低4位
sbit E    = P2^2;

void Init12864();
void Write12864_Com(uint8 com);
void Write12864_Dat(uint8 dat);
void CheckBusy(void);                      //检查忙

#endif

//12864.c文件
#include "12864.h"
void Init12864()
{
   CheckBusy();
   Write12864_Com(SETMODE4);      //并行4位数据接口
   CheckBusy();
   Write12864_Com(DISOPEN);
   CheckBusy();
   Write12864_Com(CLEAR);
}

void Write12864_Com(uint8 com)       //写命令
{
   uint8 tmp;

   RS = 0;
   RW = 0;

   tmp = com;
   tmp &= 0xF0;                                    //先传高4位
   P2 &= 0x0F;                                      //保护P2低4位
   P2 |= tmp;

   E = 0;
   E = 1;
   E = 0;

   com <<= 4;                                         //再传低4位
   P2 &= 0x0F;
   P2 |= com;

   E = 0;
   E = 1;
   E = 0;
}

void Write12864_Dat(uint8 dat)             //写数据
{
   uint8 tmp;

   RS = 1;
   RW = 0;

   tmp = dat;
   tmp &= 0xF0;
   P2 &= 0x0F;
   P2 |= tmp;

   E = 0;
   E = 1;
   E = 0;

   dat <<= 4;   
   P2 &= 0x0F;
   P2 |= dat;

   E = 0;
   E = 1;
   E = 0;
}

void CheckBusy(void)                             //检查忙
{
   uint8 tmp;

   RS = 0;
   RW = 1;
   E = 0;

   while(1)                                                //一次循环内同样要读两次
   {
      P2 |= 0xF0;
      E = 1;
      tmp = (P2 & 0xF0);

      E =0;

      P2 |= 0xF0;
      E = 1;
      tmp |= (P2 >> 4);                              //合并成一个字节
      E =0;

      if((tmp & 0x80) == 0)                       //不忙
        break;  
   }
}

//main.c文件
#include "12864.h"

uint8 codedis1[] = "胜日寻芳泗水滨,";
uint8 codedis2[] = "无边光景一时新.";
uint8 codedis3[] = "等闲识得东风面,";
uint8 codedis4[] = "万紫千红总是春.";

/*--  图像宽度x高度 = 128x64  --*/
uint8 code **[1024] =
{
//********************************************************
//内容同前
//********************************************************
};

void Disp(uint8*pic)                                          //显示Gdram内容(显示图片)
{
   uint8 x, y, i;

   CheckBusy();
   Write12864_Com(SETMODE4_OFF);              //切换到扩充指令,绘图OFF
   for(i = 0; i <= 8; i += 8)                                    //画上下两屏
   {
      for(y = 0; y < 32; y++)                                  //每行32个象素点
      {
        for(x = 0; x < 8; x++)                                  //每半屏写8列,每列2字节
        {
           CheckBusy();
           Write12864_Com(0x80 + y);                   //行地址
           CheckBusy();
           Write12864_Com(0x80 + x + i);              //列地址
           CheckBusy();
           Write12864_Dat(*pic++);                        //写数据 D15-D8
           CheckBusy();
           Write12864_Dat(*pic++);                        //写数据 D7-D0
        }
      }
   }
   CheckBusy();
   Write12864_Com(SETMODE4_ON);               //打开图形显示,绘图ON
}

void main()
{
   uint8 len, max, t;

   Init12864();
   CheckBusy();
   Write12864_Com(SETADDR1);
   max = strlen(dis1);
   for(len = 0; len < max; len++)
   {
      CheckBusy();
      Write12864_Dat(dis1[len]);
   }
   CheckBusy();
   Write12864_Com(SETADDR2);
   for(len = 0; len < max; len++)
   {
      CheckBusy();
      Write12864_Dat(dis2[len]);
   }
   CheckBusy();
   Write12864_Com(SETADDR3);
   for(len = 0; len < max; len++)
   {
      CheckBusy();
      Write12864_Dat(dis3[len]);
   }
   CheckBusy();
   Write12864_Com(SETADDR4);
   for(len = 0; len < max; len++)
   {
      CheckBusy();
      Write12864_Dat(dis4[len]);
   }

    for(t = 0; t < 30; t++) Delay(50000);
   CheckBusy();
   Write12864_Com(CLEAR);
   Disp(**);                                                     //填充图形
   while(1);
}

/******************************The End***********************************************
注:试验结果完全同前,图形图片可参考前一篇帖子.下一篇:12864的串行驱动
***************************************************************************************/


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

8

帖子

0

粉丝