⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qh12864.txt

📁 QH12864驱动程序,可以显示汉字和图片
💻 TXT
字号:
[转帖]QH12864液晶显示器驱动及单片机间通信程序


/************************************************************/
/*********  QH12864液晶显示器驱动及单片机间通信程序  ***********/
/*********          Author: xieqin               ************/
/********         CopyRight:10/03/2004            ***********/
/**   本程序具有一次接收数据数可变和自动消隐两大扩展功能   **/
/**    本程序具有汉字编码和西文编码自动搜索功能            **/
/****  本程序发串行通信用定时器为T2,选用AT89C52单片机   ****/
/************************************************************/
#include<absacc.h>
#include<reg52.h>
#include<string.h>
#include<stdio.h>
#include<stdarg.h>

#define D_ADD XBYTE[0x0000]    //数据口
#define C_ADD XBYTE[0x0100]    //地址口

unsigned char GetData[64]={0x01,0x02,0x03,0x04,0x05,0x06};
unsigned char NUM=5;//接收数据位数存放单元
unsigned char NZNUM=5;//消隐处理后有效数据位数存放单元

struct ENode{              //西文显示结点结构体声明
          const char ch;
          unsigned char dat;
};

struct CNode{            //汉字显示结点结构体声明
         char  ch[2];//字体存放单元
         unsigned char  dat[32];//汉字字模存放单元
};
struct ENode code newchar[]={//西文字符库
' ',0x00,'!',0x01,'"',0x02,'#',0x03,'$',0x04,'%',0x05,'&',0x06,//''',0x07,
'(',0x08,')',0x09,'*',0x0a,'+',0x0b,',',0x0c,'-',0x0d,'.',0x0e,'/',0x0f,
'0',0x10,'1',0x11,'2',0x12,'3',0x13,'4',0x14,'5',0x15,'6',0x16,'7',0x17,'8',0x18,'9',0x19,':',0x1a,';',0x1b,'<',0x1c,'=',0x1d,'>',0x1e,'?',0x1f,
//'',0x20,
'A',0x21,'B',0x22,'C',0x23,'D',0x24,'E',0x25,'F',0x26,'G',0x27,'H',0x28,'I',0x29,'J',0x2a,'K',0x2b,'L',0x2c,'M',0x2d,'N',0x2e,'O',0x2f,
'P',0x30,'Q',0x31,'R',0x32,'S',0x33,'T',0x34,'U',0x35,'V',0x36,'W',0x37,'X',0x38,'Y',0x39,'Z',0x3a,//0x3b,0x3c,0x3d,0x3e,0x3f,
'`',0x40,'a',0x41,'b',0x42,'c',0x43,'d',0x44,'e',0x45,'f',0x46,'g',0x47,'h',0x48,'i',0x49,'j',0x4a,'k',0x4b,'l',0x4c,'m',0x4d,'n',0x4e,'o',0x4f,
'p',0x50,'q',0x51,'r',0x52,'s',0x53,'t',0x54,'u',0x55,'v',0x56,'w',0x57,'x',0x58,'y',0x59,'z',0x5a,'{',0x5b,'|',0x5c,'}',0x5d,'~',0x5e,' ',0x5f
//0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
//0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,

};
struct CNode code newhanzi[]={//中文汉字库

//因版面大小所限,中文字库内容被删去,大家可以用相关软件自造汉字库,模式如下所示
"中",
/*--  文字:  中    0 --*/
/*--  黑体11;  此字体下对应的点阵为:宽x高=14x14   --*/
/*--  宽度不是8的倍数,现调整为:宽度x高度=16x14  --*/
0x00,0x00,0x03,0x00,0x03,0x00,0x3F,0xF0,0x23,0x10,0x23,0x10,0x23,0x10,0x23,0x10,
0x3F,0xF0,0x23,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,


};


void delay(unsigned char times)      //延时子程序
{
unsigned char data i,j,k;
for(i=0;i<times;i++)
   for(j=0;j<times;j++)
     for(k=0;k<10;k++);
}

void test01(void)
{                                    //读写指令与读写数据状态子程序
  do{
   ACC=C_ADD;
      }while(ACC&0x03!=0x03);

}

void test2(void)
{                                    //数据自动读状态子程序
  do{              //read_prepare
    ACC=C_ADD;
      }while(ACC&0x04!=0x04);
}

void test3(void)
{                                    //数据自动写状态子程序
  do{               //write_prepare
    ACC=C_ADD;
      }while(ACC&0x08!=0x08);
}


void write_c_0(unsigned char  com)
{                                    //写无参数指令子程序
   test01();
   C_ADD=com;
}

void write_c_1(unsigned char dat1,unsigned char com)
{                                   //写单参数指令子程序
   test01();
   D_ADD=dat1;
   C_ADD=com;
}


void write_c_2(unsigned char dat1,unsigned char  dat2,unsigned char  com)
{                                  //写双参数指令子程序
   test01();
   D_ADD=dat1;
   D_ADD=dat2;
   C_ADD=com;
}

void init_LCD(void)
{                                  //LCD初始化子程序
   write_c_2(0x00,0x00,0x40);//0x40文本区首址
   write_c_2(0x20,0x00,0x41);//0x41文本区宽度
   write_c_2(0x00,0x08,0x42);//0x42图形区首址
   write_c_2(0x20,0x00,0x43);//0x43图形区宽度
   write_c_0(0xa7);//0xa7光标形状设置
   write_c_0(0x80);//0x80显示方式逻辑或
   write_c_0(0x9c);//0x9c显示开关设置

}
void cls(void)
{                                  //LCD清屏子程序
    unsigned int data i;
    write_c_2(0x00,0x00,0x24);//置RAM地址指针到(0,0)
    write_c_0(0xb0);//设置自动写
    for(i=8192;i>0;i--)

      {
         test3();
         D_ADD=0x00;
      }
    write_c_0(0xb2);//自动写与读结束

}
void set_cgram(unsigned char code *ch)
{                                  //建立CGRAM子程序
   unsigned int  i,n=0;
   write_c_2(0x03,0x00,0x22);//CGRAM地址设置
   write_c_2(0x00,0x1c,0x24);
   write_c_0(0xb0);

   for(i=224;i>0;i--)
     {
        test3();
        D_ADD=ch[n];
        n++;
   }
   write_c_0(0xb2);
}


void write_zifu(unsigned char o_x,unsigned char o_y,unsigned char daima,unsigned char attr)
{                               //固定格式的西文编码写入子程序
   unsigned int add;
   unsigned char dat1,dat2;
   add=(unsigned int)(o_y*16+o_x);
   dat1=(unsigned char)add&0xff;
   dat2=(unsigned char)((add>>8)&0xff);
   write_c_2(dat1,dat2,0x24);
   write_c_1(daima,0xc4);
   dat2+=0x08;
   write_c_2(dat1,dat2,0x24);
   //write_c_1(attr,0xc4);
}

void new_write_zifu(unsigned char o_x,unsigned char o_y,char c,unsigned char attr)
{                         //具有自动搜索西文编码功能的西文编码写入子程序
   unsigned int add;
   unsigned char dat1,dat2,k,size;
   add=(unsigned int)(o_y*16+o_x);

    for(k=0,size=(sizeof(newchar)/sizeof(newchar[0]));k<size;k++)
     {//在字库中查询该字符
       if(newchar[k].ch==c)
       break;//找到该字符则跳出
       }
     if(k>=(sizeof(newchar)/sizeof(newchar[0])))
     //return;//判断是已经找到该字还是在整个字库中未发现该字符
     k=0;


   dat1=(unsigned char)add&0xff;
   dat2=(unsigned char)((add>>8)&0xff);
   write_c_2(dat1,dat2,0x24);
   write_c_1(newchar[k].dat,0xc4);
   dat2+=0x08;
   write_c_2(dat1,dat2,0x24);
   //write_c_1(attr,0xc4);
}


void new_write_under_picture(unsigned char  o_x,unsigned char o_y,char cch[2])
{                        //具有自动搜索汉字编码功能的在图形方式下汉字编码写入程序
   unsigned int data add;
   unsigned char data dat1,dat2,i,j,size,k=0;
   add=(unsigned int)(o_y*32+o_x)+0x0800;

  for(k=0,size=(sizeof(newhanzi)/sizeof(newhanzi[0]));k<size;k++)
     {//在字库中查询该字
       if((newhanzi[k].ch[0]==cch[0])&&(newhanzi[k].ch[1]==cch[1]))
       break;//找到该字则跳出
       }
     if(k>=(sizeof(newhanzi)/sizeof(newhanzi[0])))
     return;//判断是已经找到该字还是在整个字库中未发现该字
  for(i=16,j=0;i>0;i--,j+=2)
   {
     dat1=(unsigned char)add&0xff;
     dat2=(unsigned char)((add>>8)&0xff);
     write_c_2(dat1,dat2,0x24);//设置RAM地址指针

     write_c_1(newhanzi[k].dat[j],0xc0);//写入左部分字模数据
     write_c_1(newhanzi[k].dat[j+1],0xc0);//写入右部分字模数据
    add+=32;//置偏移地址为16
   }
}

/*
void print(unsigned char o_x,unsigned char o_y,char *format,...)
{  //本子程序目前尚不能调用,但具有自动写入汉字功能的可扩展性
va_list arg_ptr;
char temp[64];
unsigned char  i,str_len;
va_start(arg_ptr,format);
// str_len=(unsigned char)vsprintf(temp,format,arg_ptr);
str_len=sizeof(format)/sizeof(format[0]);
sprintf(temp,format);
va_end(arg_ptr);
}
*/

void initport()    //串行通信初始化子程序
{
  EA=1;//开CPU中断
  TH2=0XFF;  //设置波特率11.0592M 为9600
  TL2=0XDC;//选用定时/计数器2为波特率发生器
  RCAP2H=0xFF;//对PCAP寄存器存入初始值
  RCAP2L=0xDC;
  T2CON=0X34;//定时/计数器2控制寄存器参数设置
  SCON=0X50;//串行口控制寄存器参数设置(方式1)
}

void receive_port(unsigned char *dat)//串行口数据接收子程序
{
unsigned char sign,number,i;
do{
   while(RI==0);RI=0;sign=SBUF;
   if(sign==0xff)break;
  }while(1);
while(RI==0);RI=0;number=SBUF;
for(i=0;i<number;i++)
{
  while(RI==0);RI=0;dat[i]=SBUF;
}
NUM=number;
}

void control_NZNUM()//消隐处理子程序
{
unsigned char i;
NZNUM=2;
for(i=2;i<NUM;i++)
   {
     if(GetData[i]>0)NZNUM=i+1;
     }
}

void write_number(unsigned char o_x,unsigned char o_y,unsigned char dat)
{                   //接收数据送LCD显示,数字编码写入子程序
                    //(本子程序也具有西文编码写入功能)
   unsigned int add;
   unsigned char dat1,dat2;
   add=(unsigned int)(o_y*16+o_x);

   dat1=(unsigned char)add&0xff;
   dat2=(unsigned char)((add>>8)&0xff);
   write_c_2(dat1,dat2,0x24);
   write_c_1(dat,0xc4);
   dat2+=0x08;
   write_c_2(dat1,dat2,0x24);
   //write_c_1(attr,0xc4);
}


void main(void)   //T6963液晶显示驱动与串行数据接收主程序
{
   unsigned char x,y,i,last_number;//坐标
   unsigned char dat[]={'2','0','0','8','.','0','m','V'};
   init_LCD();
   cls();
   x=0;y=25;
   new_write_under_picture(x+=2,y,"中");
   new_write_under_picture(x+=2,y,"国");
   new_write_under_picture(x+=2,y,"地");
   new_write_under_picture(x+=2,y,"质");
   new_write_under_picture(x+=2,y,"大");
   new_write_under_picture(x+=2,y,"学");
   x=1;
   new_write_zifu(x++,10,'w',0);
   new_write_zifu(x++,10,'w',0);
   new_write_zifu(x++,10,'w',0);
   new_write_zifu(x++,10,'.',0);
   new_write_zifu(x++,10,'c',0);
   new_write_zifu(x++,10,'u',0);
   new_write_zifu(x++,10,'g',0);
   new_write_zifu(x++,10,'.',0);
   new_write_zifu(x++,10,'e',0);
   new_write_zifu(x++,10,'d',0);
   new_write_zifu(x++,10,'u',0);
   new_write_zifu(x++,10,'.',0);
   new_write_zifu(x++,10,'c',0);
   new_write_zifu(x++,10,'n',0);

   delay(255);delay(255);
   cls();
   x=0;y=25;
   new_write_under_picture(x+=1,y,"测");
   new_write_under_picture(x+=2,y,"控");
   new_write_under_picture(x+=2,y,"技");
   new_write_under_picture(x+=2,y,"术");
   new_write_under_picture(x+=2,y,"与");
   new_write_under_picture(x+=2,y,"仪");
   new_write_under_picture(x+=2,y,"器");
   delay(255);  delay(200);
   cls();
   x=0,y=16;
   new_write_under_picture(x+=1,y,"指");
   new_write_under_picture(x+=2,y,"导");
   new_write_under_picture(x+=2,y,"老");
   new_write_under_picture(x+=2,y,"师");
   new_write_under_picture(x+=2,y,":");
   new_write_under_picture(x+=2,y,"沈");
   new_write_under_picture(x+=3,y,"博");
   x=0;y=32;
   new_write_under_picture(x+=1,y,"ip");
   new_write_under_picture(x+=6,y,"生");
   new_write_under_picture(x+=2,y,":");
   new_write_under_picture(x+=2,y,"谢");
   new_write_under_picture(x+=3,y,"琴");
   delay(255);delay(100);
   cls();
  // }while(1);
   x=0;y=20;
   new_write_under_picture(x+=2,y,"当");
   new_write_under_picture(x+=2,y,"前");
   new_write_under_picture(x+=2,y,"ce");
   new_write_under_picture(x+=2,y,"得");
   new_write_under_picture(x+=2,y,"电");
   new_write_under_picture(x+=2,y,"压");
   new_write_under_picture(x+=2,y,":");
    y=10; x=3;
    new_write_zifu(x++,y,'U',0);
    new_write_zifu(x++,y,'=',0);
    for(i=0;i<8;i++)
    new_write_zifu(x++,y,dat[i],0);
    delay(255);
    initport();
    do{
        receive_port(GetData);//接收数据
        control_NZNUM(); //消隐处理
        x=5; y=10;
        for(i=NZNUM-1;i>0;i--)write_number(x++,y,GetData[i]|0x10);//数据编码写入
        new_write_zifu(x++,y,'.',0);
        write_number(x++,y,GetData[0]|0x10);
        new_write_zifu(x++,y,'m',0);
        new_write_zifu(x++,y,'V',0);
        for(i=0;i<8-NUM;i++)//在显示位数发生变化的情况下,自动擦除过时信息
        write_number(x++,y,0x00);
     }while(1);
          for(;;);


}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -