自制单片机之五……LCD12864的驱动

时间:2021-01-31 05:31:29

LCD12864的驱动LCD12864在市面上主要分为两种,一种是采用st7920控制器的,它一般带有中文字库字模,价格略高一点。另一种是采用KS0108控制器,它只是点阵模式,不带字库。很可惜,我的这块就是KS0108控制器不带汉字库的,不过不打算用它专门显示文本,也就无所谓了。自制单片机之五……LCD12864的驱动

LCD12864模块的20个引脚定义如下:1。Vss      逻辑电源地
2。VDD 逻辑电源正 5v
3。V0  LCD驱动电压
4。RS  数据/指令选择:高电平为数据,低电平为指令
5。R/W 读/写选择:高电平为读数据,低电平为写数据
6。E  读写使能,高电平有效,下降沿锁定数据
7。DB0 数据输入输出引脚
8。DB1 数据输入输出引脚
9。DB2 数据输入输出引脚
10。DB3 数据输入输出引脚
11。DB4 数据输入输出引脚
12。DB5 数据输入输出引脚
13。DB6 数据输入输出引脚
14。DB7 数据输入输出引脚
15。CS1 片选择号,低电平时选择前64列
16。CS2 片选择号,低电平时选择后64列
17。RET 复位信号,低电平有效。
18。VEE 输出-15v电源给V0提供驱动电源
19。A  背光电源LED正极
20。K  背光电源LED负极

具体电路图如下:

自制单片机之五……LCD12864的驱动

制做如下:自制单片机之五……LCD12864的驱动接口说明:自制单片机之五……LCD12864的驱动装上12864自制单片机之五……LCD12864的驱动

具体的电路还是两个电阻。一个背光限流电阻。一个液晶驱动电压调节电阻。背光电阻还是任何时候在19、20脚与电源之间串上个100欧电位器接上电源。调节电位器到合适亮度。具体值最好是到调试完程序能够正常显示后再将阻值确定换成固定电阻。液晶驱动电压的调整在数据线、电源线接好的前提下是在Vee(-15v)和地之间接一个电位器。中间接V0,通过调节电位器来调节V0上的电压。当V0上为-15V时为全暗(液晶显示为全黑)。当V0为0V时为全亮。调节电位器使屏幕从全暗刚好变到亮时,便可进行程序的调试。待屏幕显示正常后,进行对比度的细调,然后测量这两边的阻值在地和V0之间、V0和Vee之间换成两个固定电阻焊上就好了。注意在V0的电压是在一个很小的范围有效。我的就是在-2.2——-2.5这个范围。仔细调节V0和地之间的电阻使V0上的电压在2.3V。自制单片机之五……LCD12864的驱动

更换为固定电阻后的装配图:

自制单片机之五……LCD12864的驱动

下面说说具体的驱动:先来了解一下LCD12864的内部控制结构:见图

自制单片机之五……LCD12864的驱动

可以看出12864屏是分为左、右两块控制的。所有对屏幕的操作要受片选CS1、CS2来控制。
我们再来看一看对屏幕操作数据与屏幕点阵的排布关系:见下图。

自制单片机之五……LCD12864的驱动
从上图可以看出数据按字节在屏幕上是竖向排列的。上方为低位,下方为高位。因此在横向上(也就是Y)就一共是128列数据。分为CS1和CS2两个64列来写入。在竖方向上(也就是X)一字节数据显示8个点,竖向64个点分为8个字节,称做8页(X=0-7)。了解这些后我们就知道要满屏显示一张图就要从y=0…127、X=0…7一共写128×8=1024个字节的数据。同样在AT89S51中存一张图就要1024个字节的空间。
好!下面我们来了解对LCD12864进行操作的一些指令。

自制单片机之五……LCD12864的驱动

下面对上图的指作解释:
1.显示开关控制(DISPLAY ON/OFF)

自制单片机之五……LCD12864的驱动

D=1:开显示(DISPLAY ON)    意即显示器可以进行各种显示操作 
D=0:关显示(DISPLAY OFF) 意即不能对显示器进行各种显示操作

2.设置显示起始行(DISPLAY START LINE)

自制单片机之五……LCD12864的驱动

前面在Z地址计数器一节已经描述了显示起始行是由Z地址计数器控制的。A5~A0    6位地址自动送入Z地址计数器,起始行的地址可以是0~63的任意一行。 
例如: 选择A5~A0是62,则起始行与DDRAM行的对应关系如下: 
DDRAM 行:62 63    0    1    2    3 ·················28 29 
屏幕显示行: 1    2    3     4    5    6················· 31 32

3.设置页地址(SET PAGE “X ADDRESS”)

自制单片机之五……LCD12864的驱动

所谓页地址就是DDRAM的行地址,8行为一页,模块共64行即8页,A2~A0表示0~7页。读写数据对地址没有影响,页地址由本指令或RST信号改变复位后页地址为0。页地址与DDRAM的对应关系见DDRAM地址表。

4.设置Y地址(SET Y ADDRESS)

自制单片机之五……LCD12864的驱动

此指令的作用是将A5~A0送入Y地址计数器,作为DDRAM的Y地址指针。在对DDRA M进行读写操作后,Y地址指针自动加1,指向下一个DDRAM单元。 
5.读状态(STATUS READ)

自制单片机之五……LCD12864的驱动

当R/W=1    D/I=0时,在E信号为“H”的作用下,状态分别输出到数据总线(DB7~DB0)的相应位。

BF:       前面已叙述过(见BF标志位一节)。 ON/OFF: 表示DFF触发器的状态(见DFF触发器一节)。

RST:      RST=1表示内部正在初始化,此时组件不接受任何指令和数据。

6.写显示数据(WRITE DISPLAY DATE)

自制单片机之五……LCD12864的驱动

D7~D0为显示数据,此指令把D7~D0写入相应的DDRAM单元,Y地址指针自动加1。

7.读显示数据(READ DISPLAY DATE)

自制单片机之五……LCD12864的驱动

此指令把DDRAM的内容D7~D0读到数据总线DB7~DB0,Y地址指针自动加1。 再帖一下接口时序图1.写操作时序

自制单片机之五……LCD12864的驱动 
2.读操作时序

自制单片机之五……LCD12864的驱动

时序参数表:

自制单片机之五……LCD12864的驱动

又帖了这么多指令呀时序图什么的,看了就头晕。我也和你一样不爱看这些枯燥的东西。下面实际写些程序让屏幕亮起来。
运行:

自制单片机之五……LCD12864的驱动

不要走开哦!我会不断补全的。。。

//LCD12864
//**********************************************************
//连线表: CPU=89C51    SysClock=12MHz                     *
//RS=P1.0   R/W=P1.1    E=P1.2    CS1=P1.3    CS2=P1.4     *
//DB0-DB7=P0.0-P0.7       /Reset=InBoard                   *
//**********************************************************
#include <reg52.h>
#include <stdlib.h>
#include <intrins.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
/********************引脚定义********************/
#define DataPort P3     //LCD128*64 I/O 信号管脚
sbit    RS =P2^;      //数据指令
sbit    RW =P2^;      //读写
sbit    E   =P2^;      //使能
sbit    CSL =P2^;      //左片选
sbit    CSR =P2^;      //右片选
uchar Page;             //页 地址
uchar Col;              //列 地址
uchar code BMP1[];      //一幅图
uchar code HZK_12[];    //12×12阵点字模
uchar code ASC_5x7[];   //5×7阵点字模
uchar str[];
/********************函数定义*******************/
void BusyL(void);          //左屏检测忙
void BusyR(void);          //右屏检测忙
void CheckBusy(void);      //读取忙信号
void Delay(uint MS);       //延时
void Locatexy(void);       //将屏幕横向0-12纵向0-7转换成左、右屏的的X、Y
void WriteCommandL( uchar CommandByte );    //向左屏写入指令
void WriteCommandR( uchar CommandByte );    //向右屏写入指令
uchar ReadData( void );       //读数据
void WriteData( uchar DataByte );    //写数据
void LcmClear( void );       //清屏
void LcmInit( void );        //初始化
void LcmPutBMP( uchar *puts );      //显示一幅图
void LcmReverseBMP( void );         //将整屏反显
void LcmPutHZ_12( uchar x,uchar y,uchar HZcode ); //在屏幕上任意点显示一个12×12汉字
uchar * uchartostr(unsigned char unm);            //将值转成字符串
void LcmPutAsc( uchar asc );     //显示一个5×7的ASC字符
void LcmPutstr( uchar row,uchar y,uchar * str );       //在设定位置显示字符串
void LcmPutpoint( uchar ro,uchar lie,uchar colour );   //在设定位置显示一个点

/***************************/
/*检查Busy                 */
/***************************/
void BusyL(void)
{
        CSL= ;
        CSR= ;
        CheckBusy();
}
void BusyR(void)
{
        CSL= ;
        CSR= ;
        CheckBusy();
}
void CheckBusy(void)
{
        RS = ;         //指令
        RW = ;
DataPort= 0xFF;      //输出0xff以便读取正确
        E = ;
        _nop_();
        ); //DataPort & 0x80);    //Status Read Bit7 = BUSY 这地方有点问题,用了while(//DataPort & 0x80)后就一直读不到0了,陷入死循环。当用while(0) 时反而能正常工作,不知道有没有人能解释
        E = ;
        _nop_();
}
/********************************************************/
/*根据设定的坐标数据,定位LCM上的下一个操作单元位置     */
/********************************************************/
void Locatexy(void)
{
        uchar x,y;
        switch (Col&0xc0)       /* col.and.0xC0        */
        {                       /*条件分支执行          */
                :         {BusyL();break;}/*左区 */
                case 0x40:      {BusyR();break;}/*右区 */
        }
        x = Col&0x3F|0x40;      /* col.and.0x3f.or.Set Y Address*/
        y = Page&0x07|0xB8;     /* row.and.0x07.or.set Page     */
        CheckBusy();                /* waitting for enable */
        RS = ;                 //指令
        RW = ;                 //写
        DataPort = y;                 //设置页面地址
        E = ;
        _nop_();
        E = ;
        _nop_();
        CheckBusy();                /* waitting for enable */
        RS = ;
        RW = ;
        DataPort = x;                 //设置列地址
        E = ;
        _nop_();
        E = ;
        _nop_();
}
/***************************/
/*写指令                   */
/***************************/
void WriteCommandL( uchar CommandByte )
{
        BusyL();
        DataPort = CommandByte;
        RS = ;         //指令
        RW = ;
        E = ;
        _nop_();
        E = ;
        _nop_();
}
void WriteCommandR( uchar CommandByte )
{
        BusyR();
        DataPort = CommandByte;
        RS = ;         //指令
        RW = ;
        E = ;
        _nop_();
        E = ;
        _nop_();
}
/***************************/
/*读数据                   */
/***************************/
uchar ReadData( void )
{
        uchar DataByte;
        Locatexy();     /*坐标定位,返回时保留分区状态不变      */
        RS = ;         /*数据输出*/
        RW = ;         /*读入 */
        DataPort = 0xFF;              //输出0xff以便读取正确
        E = ;         /*读入到LCM*/
        _nop_();
        DataByte = DataPort; /*数据读出到数据口P1 */
        E = ;
        _nop_();
        return DataByte;
}
/***************************/
/*写数据                   */
/***************************/
void WriteData( uchar DataByte )
{
        Locatexy();     /*坐标定位,返回时保留分区状态不变      */
        RS = ;         /*数据输出*/
        RW = ;         /*写输出 */
        DataPort = DataByte; /*数据输出到数据口 */
        E = ;         /*写入到LCM*/
        _nop_();
        E = ;
        _nop_();
}
void LcmClear( void )
{
        Page = ;
        Col = ;
        ;Page<;Page++)
                ;Col<;Col++)
                        WriteData();
}
void LcmInit( void )
{
    Delay();     //等待复位
        WriteCommandL(0x3f);    //开显示
        WriteCommandR(0x3f);

        WriteCommandL(0xc0);    //设置起始地址=0
        WriteCommandR(0xc0);
        WriteCommandL(0x3f);    //开显示
        WriteCommandR(0x3f);
        LcmClear();
        Col = ;
        Page= ;
        Locatexy();
}
void LcmPutBMP( uchar *puts )
{
        ;
        Page = ;
        Col = ;
        ;Page<;Page++)
        {
                ;Col<;Col++)
                {
                        WriteData( puts[X] );
                        X++;
                }
        }
}
void LcmReverseBMP( void )
{
        uchar temp;
        Page = ;
        Col = ;
        ;Page<;Page++)
        {
                ;Col<;Col++)
                {
                        temp = ReadData();      //空读一次
                        temp = ReadData();
                        temp = ~temp;
                        WriteData(temp);
                }
        }
}
void LcmPutHZ_12( uchar x,uchar y,uchar HZcode )
{
   uchar offset,Rd,Wt,m,tmp,i;
   uint n;
   &y<) //x为横向起始点数0-117,超过117就显示不全一个汉字了。y同理。
    {
    Page=(y & ; //将竖向的点阵数y转换成页数
   Col=x;                //横向的X就是LCD的列数。
      n = 0x18*HZcode;   //一个汉字24字节(18H),HZcode为字库序号。n就是要显示汉字的起始地址
   offset=y&0x07;    //将显示该页的竖向偏移量。
   )          //如果偏移量小于5,那么在竖向用两个页的范围就可显示出汉字了。
   {
             ;i>;i--)
              {
                 Rd=ReadData();
       Rd=ReadData();            //读出LCD该Page、Col位置的上半个数据。
       m=HZK_12[n];              //读出汉字模第n的数据。
             Wt=Rd&(-offset))|(m<<offset);   //按照上面计算出的偏移量将汉字模数据嵌入LCD读出的数据中。
                 WriteData(Wt);     //再将Wt写回LCD
         Page++;    //页位置移到下半个汉字位置
         n++;
         tmp=m;    //将取得的上半个字模数据交给tmp
         m=HZK_12[n];   //取下半个字模数据
         Rd=ReadData(); //读LCD下半个字模数据
       Rd=ReadData();
         Wt=tmp>>(-offset)|(m<<offset)|(Rd&()));   //将汉字模数据嵌入下半个读出的LCD数据中
                 WriteData(Wt);//再写回LCD
                 Col++;//列数增加一
                 Page--;//将页数返回上半个汉字位置。
       n++;
      }
   }
   else      //如果偏移量大于或等于5,竖向就要用3个页的范围来显示一个汉字了。
   {
       ;i>;i--)
                 {
                   Rd=ReadData();
       Rd=ReadData();      //读取LCD上汉字上部位置的原来数据。
           m=HZK_12[n];   //读取汉字模数据
               Wt=Rd&(-offset))|(m<<offset);//将字模嵌入读出的LCD数据中
                   WriteData(Wt);   //写回
           Page++;   //到下一页即汉字中部位置
           n++;
           tmp=m;   //上半个字模交给tmp
           m=HZK_12[n];   //读取下半个字模
       Wt=tmp>>(-offset)|(m<<offset);   //汉字中间部分的嵌入
       WriteData(Wt);   //写回
       Page++;   //到下一页即汉字下部位置
       n++;
       Rd=ReadData();
       Rd=ReadData();   //读取LCD上汉字下部位置的原来数据
       Wt=m>>(-offset)|(Rd&())); //嵌入
        WriteData(Wt);   //写回
       Page=Page-;//恢复位置
       Col++; //修正下一个汉字的起始位置
       }
        }
   }
}
uchar * uchartostr(uchar unm)
{
uchar x00,xx,x0,x,n;
x00=unm/;
xx=unm%;
x0=xx/;
x=xx%;
n=;
)
{ str[n]=x00+; //值加48即为字符
    n++;
}
&x0==))
{ str[n]=x0+;
    n++;
}
str[n]=x+;
n++;
str[n]='\0';
   return str;
}
void LcmPutAsc( uchar asc )
{
        uchar j;
        uint x;
        x = *(asc-);
            ;j<;j++)
                {
                        WriteData(ASC_5x7[x]);
                        x++;
                        Col++;
                }
            WriteData(0x00);
            Col++;
}
void LcmPutstr( uchar row,uchar y,uchar * str )
{ unsigned char * x;
   x=str;
Page=row;
Col=y;
while(*x!='\0')
{ LcmPutAsc( *x );
    x++;
}
}

void LcmPutpoint( uchar ro,uchar lie,uchar colour )   //画点函数
{
    )&(lie<))
   {
        uchar modbyte,outByte;
        uchar offsetbit;
    Col=lie;                  //列等于lie
        Page=(ro & ;     //页等于行数row与00111000B再右移3位
        offsetbit=ro&0x07;       //偏移量为行数与00000111
        modbyte=;
    modbyte<<= offsetbit;     //输出位的模00000001左移offsetbit位
    outByte=ReadData();
    outByte=ReadData();
    )
    {
          modbyte=~modbyte;
      outByte=modbyte&outByte;     //输出位不影响其它位
    }
    else outByte=modbyte|ReadData();     //输出位不影响其它位
        WriteData(outByte);
   }
}

void Delay(uint MS)
{
        uchar us,usn;
        )
        {
                usn = ;        //for 12M
                )
                {
                        us=0xf6;
                        ){us--;};
                        usn--;
                }
                MS--;
        }
}
void Main( void )
{
        uchar x,i;
        LcmInit();
        LcmClear();
        )
        {
          LcmClear();
              LcmPutBMP(BMP1);
              Delay();
      LcmClear();
              //LcmReverseBMP();
              Delay();
          //LcmClear();
      x=;
      ;i<;i++)
      {
                LcmPutHZ_12(x,i*,i);
      x=x+;
      }
      LcmPutstr( ,,"Hello" );
      LcmPutstr( ,,"World!" );
              Delay();

        }
}
unsigned char code BMP1[]={             //字节倒序
//-- 调入了一幅图像:
//宽度x高度=1264
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x80,0xE0,0xF0,0xFC,0xFE,0xFE,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0x9F,0xCF,0xDF,0x9F,
      0x9E,0x3E,0xFF,0xFE,0xFE,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFA,0xFC,0xF8,0xE0,0xC0,0x80,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x80,0xC0,0xF0,0xF8,0xFC,0xFE,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF,
      0xCF,0xDF,0x9F,0x0F,0x1F,0x7F,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFE,0xFC,0xF0,0xC0,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0xC0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x10,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB,0xFF,
      0xFF,0xFF,0xFF,0xFE,0xF8,0xFE,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0x3F,
      0x37,0x37,0x37,0x27,0x63,0x43,0x03,0x03,
      0x03,0x03,0x03,0x07,0x67,0x27,0x0F,0x0F,
      0x1F,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0x80,0x80,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,
      0x7F,0x7F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
      0x3F,0x3F,0x3F,0x3F,0x3F,0x7F,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x80,0xE0,0xFC,0xFE,0xFE,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xDF,0x0F,0x07,0x07,0x03,
      0x03,0x03,0x03,0x02,0xC0,0xAC,0xBF,0xA0,
      0x80,0x00,0x00,0x00,0x02,0x02,0x06,0x06,
      0x04,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF0,0xE0,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x3F,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xBF,0x3F,0x3F,0x3D,
      0x7D,0xF8,0xF0,0xF0,0xC0,0x00,0x00,0x00,
      0x08,0x8C,0xFC,0xFE,0xEE,0xE6,0xC2,0xC0,
      0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
      0x1F,0x1F,0x87,0x0D,0x7D,0x70,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,
      0xF0,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xE0,0x00,
      0x00,0x00,0x02,0xE7,0xE7,0xE7,0xE7,0xC3,
      0xC3,0xC1,0x82,0x87,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0xE3,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFC,0xF8,0xE0,0xC0,0x80,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
      0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xDF,0x1F,0x1F,0x1F,0x1B,0xF9,
      0xF9,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,
      0x00,0x01,0x01,0x03,0x03,0x83,0x83,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,
      0xF8,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFE,0xFC,0xF8,0xFE,0x8F,0x8F,0x0E,0x06,
      0x0E,0x0C,0x0C,0x00,0x01,0x00,0x00,0x80,
      0xC0,0xF0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,
      0xF8,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,
      0x00,0x03,0x07,0x0F,0x1F,0x1F,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFE,0xFC,0xFC,0xFE,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xCF,0xDE,
      0xD4,0xC2,0x82,0x80,0x80,0x83,0xC7,0xC7,
      0x0F,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
      0xC0,0xF4,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0x7F,0x3F,0x1F,0x1F,0xDF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x1E,
      0x1E,0x0E,0x0C,0x04,0x02,0x06,0x1F,0xFF,
      0xFF,0xCF,0x0F,0x0F,0x0F,0x1F,0x3F,0x7F,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x7F,0x1F,0x1F,0x03,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x80,0xC1,0xE7,
      0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFB,
      0xF3,0xF9,0x71,0x31,0x00,0x00,0x00,0x01,
      0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xFF,
      0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
      0x03,0x07,0x0F,0x1F,0x1F,0x3F,0x3F,0x1F,
      0x1F,0x1F,0x0F,0x4F,0x67,0x27,0x33,0x31,
      0x38,0x38,0x78,0x7C,0x7E,0x7F,0x7F,0x7F,
      0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x7F,0x7F,
      0x7F,0x7F,0x7D,0x79,0x79,0x70,0x70,0x70,
      0x70,0x70,0x70,0x78,0x78,0x3C,0x5E,0x6F,
      0x3F,0x77,0x0F,0x0C,0x7C,0x78,0x78,0x40,
      0x00,0x01,0x01,0x03,0x07,0x0F,0x1F,0x1F,
      0x1F,0x1F,0x1F,0x1F,0x0F,0x07,0x03,0x00,
      0x00,0x00,0x00,0x40,0x60,0x70,0x70,0x78,
      0x78,0x7C,0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,
      0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
      0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7C,
      0x7C,0x7C,0x78,0x78,0x70,0x58,0x00,0x00,
      0x40,0x70,0x78,0x7C,0x7F,0x7F,0x7F,0x7F,
      0x7F,0x7F,0x07,0x07,0x0F,0x1F,0x3F,0x7F
};
//ASCII字符
unsigned char code ASC_5x7[]={
0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x4F, 0x00, 0x00, //
0x00, 0x07, 0x00, 0x07, 0x00, //
0x14, 0x7F, 0x14, 0x7F, 0x14, //
0x24, 0x2A, 0x7F, 0x2A, 0x12, //
0x23, 0x13, 0x08, 0x64, 0x62, //
0x36, 0x49, 0x55, 0x22, 0x50, //
0x00, 0x05, 0x03, 0x00, 0x00, //
0x00, 0x1C, 0x22, 0x41, 0x00, //
0x00, 0x41, 0x22, 0x1C, 0x00, //
0x14, 0x08, 0x3E, 0x08, 0x14, //
0x08, 0x08, 0x3E, 0x08, 0x08, //
0x00, 0x50, 0x30, 0x00, 0x00, //
0x08, 0x08, 0x08, 0x08, 0x00, //
0x00, 0x60, 0x60, 0x00, 0x00, //
0x20, 0x10, 0x08, 0x04, 0x02, //
0x3E, 0x51, 0x49, 0x45, 0x3E, //
0x00, 0x42, 0x7F, 0x40, 0x00, //
0x42, 0x61, 0x51, 0x49, 0x46, //
0x21, 0x41, 0x45, 0x4B, 0x31, //
0x18, 0x14, 0x12, 0x7F, 0x10, //
0x27, 0x45, 0x45, 0x45, 0x39, //
0x3C, 0x4A, 0x49, 0x49, 0x30, //
0x01, 0x01, 0x79, 0x05, 0x03, //
0x36, 0x49, 0x49, 0x49, 0x36, //
0x06, 0x49, 0x49, 0x29, 0x1E, //
0x00, 0x36, 0x36, 0x00, 0x00, //
0x00, 0x56, 0x36, 0x00, 0x00, //
0x08, 0x14, 0x22, 0x41, 0x00, //
0x14, 0x14, 0x14, 0x14, 0x14, //
0x00, 0x41, 0x22, 0x14, 0x08, //
0x02, 0x01, 0x51, 0x09, 0x06, //
0x32, 0x49, 0x79, 0x41, 0x3E, //
0x7E, 0x11, 0x11, 0x11, 0x7E, //
0x41, 0x7F, 0x49, 0x49, 0x36, //
0x3E, 0x41, 0x41, 0x41, 0x22, //
0x41, 0x7F, 0x41, 0x41, 0x3E, //
0x7F, 0x49, 0x49, 0x49, 0x49, //
0x7F, 0x09, 0x09, 0x09, 0x01, //
0x3E, 0x41, 0x41, 0x49, 0x7A, //
0x7F, 0x08, 0x08, 0x08, 0x7F, //
0x00, 0x41, 0x7F, 0x41, 0x00, //
0x20, 0x40, 0x41, 0x3F, 0x01, //
0x7F, 0x08, 0x14, 0x22, 0x41, //
0x7F, 0x40, 0x40, 0x40, 0x40, //
0x7F, 0x02, 0x0C, 0x02, 0x7F, //
0x7F, 0x06, 0x08, 0x30, 0x7F, //
0x3E, 0x41, 0x41, 0x41, 0x3E, //
0x7F, 0x09, 0x09, 0x09, 0x06, //
0x3E, 0x41, 0x51, 0x21, 0x5E, //
0x7F, 0x09, 0x19, 0x29, 0x46, //
0x26, 0x49, 0x49, 0x49, 0x32, //
0x01, 0x01, 0x7F, 0x01, 0x01, //
0x3F, 0x40, 0x40, 0x40, 0x3F, //
0x1F, 0x20, 0x40, 0x20, 0x1F, //
0x7F, 0x20, 0x18, 0x20, 0x7F, //
0x63, 0x14, 0x08, 0x14, 0x63, //
0x07, 0x08, 0x70, 0x08, 0x07, //
0x61, 0x51, 0x49, 0x45, 0x43, //
0x00, 0x7F, 0x41, 0x41, 0x00, //
0x02, 0x04, 0x08, 0x10, 0x20, //
0x00, 0x41, 0x41, 0x7F, 0x00, //
0x04, 0x02, 0x01, 0x02, 0x04, //
0x40, 0x40, 0x00, 0x40, 0x40, //
0x01, 0x02, 0x04, 0x00, 0x00, //
0x20, 0x54, 0x54, 0x54, 0x78, //
0x7F, 0x48, 0x44, 0x44, 0x38, //
0x38, 0x44, 0x44, 0x44, 0x28, //
0x38, 0x44, 0x44, 0x48, 0x7F, //
0x38, 0x54, 0x54, 0x54, 0x18, //
0x00, 0x08, 0x7E, 0x09, 0x02, //
0x0C, 0x52, 0x52, 0x4C, 0x3E, //
0x7F, 0x08, 0x04, 0x04, 0x78, //
0x00, 0x44, 0x7D, 0x40, 0x00, //
0x20, 0x40, 0x44, 0x3D, 0x00, //
0x00, 0x7F, 0x10, 0x28, 0x44, //
0x00, 0x41, 0x7F, 0x40, 0x00, //
0x7C, 0x04, 0x78, 0x04, 0x78, //
0x7C, 0x08, 0x04, 0x04, 0x78, //
0x38, 0x44, 0x44, 0x44, 0x38, //
0x7E, 0x0C, 0x12, 0x12, 0x0C, //
0x0C, 0x12, 0x12, 0x0C, 0x7E, //
0x7C, 0x08, 0x04, 0x04, 0x08, //
0x58, 0x54, 0x54, 0x54, 0x64, //
0x04, 0x3F, 0x44, 0x40, 0x20, //
0x3C, 0x40, 0x40, 0x3C, 0x40, //
0x1C, 0x20, 0x40, 0x20, 0x1C, //
0x3C, 0x40, 0x30, 0x40, 0x3C, //
0x44, 0x28, 0x10, 0x28, 0x44, //
0x1C, 0xA0, 0xA0, 0x90, 0x7C, //
0x44, 0x64, 0x54, 0x4C, 0x44, //
0x00, 0x08, 0x36, 0x41, 0x00, //
0x00, 0x00, 0x77, 0x00, 0x00, //
0x00, 0x41, 0x36, 0x08, 0x00, //
0x02, 0x01, 0x02, 0x04, 0x02, //
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //
};
unsigned char code HZK_12[]={      //字节颠倒
//- 宋体11; 此字体下对应的点阵为:宽x高=11x12
0x42,0x00,0x22,0x00,0x12,0x00,0xFA,0x07,0x4E,0x01,0x4B,0x01,0x4A,0x01,0x4A,0x05,
0xFA,0x07,0x02,0x00,0x02,0x00,0x00,0x00,/*"有",{0}*/
0x42,0x04,0xAE,0x04,0x93,0x04,0x9A,0x02,0xA6,0x01,0xC0,0x00,0xA6,0x04,0x9A,0x04,
0x8A,0x04,0x96,0x03,0x20,0x00,0x00,0x00,/*"努",{1}*/
0x00,0x04,0x08,0x04,0x08,0x02,0x08,0x01,0xC8,0x00,0x3F,0x00,0x08,0x04,0x08,0x04,
0x08,0x04,0xFC,0x03,0x08,0x00,0x00,0x00,/*"力",{2}*/
0x02,0x02,0xFA,0x01,0x4B,0x04,0xCA,0x07,0x7A,0x01,0x02,0x04,0x08,0x03,0xFF,0x00,
0xC8,0x07,0x0E,0x04,0x08,0x07,0x00,0x00,/*"就",{3}*/
0x42,0x00,0x22,0x00,0x12,0x00,0xFA,0x07,0x4E,0x01,0x4B,0x01,0x4A,0x01,0x4A,0x05,
0xFA,0x07,0x02,0x00,0x02,0x00,0x00,0x00,/*"有",{4}*/
0x00,0x04,0xFC,0x03,0x24,0x01,0x24,0x02,0xE4,0x01,0x04,0x04,0x7F,0x02,0x84,0x01,
0x45,0x02,0x36,0x04,0x04,0x07,0x00,0x00,/*"成",{5}*/
0x02,0x01,0x02,0x01,0xFE,0x00,0x82,0x04,0x82,0x04,0x08,0x02,0x88,0x01,0x7F,0x04,
0x08,0x04,0x08,0x04,0xF8,0x03,0x00,0x00,/*"功",{6}*/
0x00,0x00,0x1C,0x00,0x7E,0x03,0x7E,0x03,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00/*"!",{7}*/
};

本程序的实际效果图如下。

自制单片机之五……LCD12864的驱动

自制单片机之五……LCD12864的驱动