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

📄 lcd12864.c

📁 AD采集和液晶显示模块程序
💻 C
字号:
//用户版
//描述: LCD12864液晶显示模块,对于芯片KS0108(HD61202)驱动程序.
//编写:微控设计网 DC版主 日期:2007.9.
//编译环境:IAR EW430 V3.42A
//验证平台: www.microcontrol.cn MC430F14+开发板 V1.0
//声明:此程序只供微控用户使用.在未得到DC版主的许可请勿将资料外公开和用于商业用途.
//******************************************************************************
#include "lcd12864.h"

extern unsigned char ASCII86[][6];
//******************************************************************************
//LCD12864函数声明

void Lcd12864delay();                           //延时
void CheckState();                              //忙状态检查
void WriteByte(unsigned char dat);              //写显示数据
void SEdCommandToLCD(unsigned char command);    //向LCD发送命令
void SetLine(unsigned char line);               //设定行地址(页)--X 0-7
void SetColumn(unsigned char column);           //设定列地址--Y 0-63
void SetOnOff(unsigned char onoff);             //开关显示
void SetStartLine(unsigned char startline);     //设定显示开始行--XX
void ClearScreE(unsigned char screE);           //清屏
void SelectScreE(unsigned char screE);          //选择屏幕
unsigned char ReadByte();                       //读显示数据
//显示8*6字符串	
void ShowString86(unsigned char lin,unsigned char column, unsigned char *string);
//反显一个8*6字块
void ReverseShow86(unsigned char lin,unsigned char column);
//反显某行某几个字符
void ReverseLinChar(unsigned char lin,unsigned char startcolumn,unsigned char ShowQuantity);
void InitLCD(void);                             //初始化LCD
//******************************************************************************

//初级函数列表
//******************************************************************************
//延时
void Lcd12864delay()
{
unsigned int i=500;
while(i--) {;}
}

void LcdDelay()
{
unsigned int i=2;
while(i--) {;}
}

//******************************************************************************
//忙状态检查(已整理)
void CheckState()
 {
  MCU_BUS_DIR_IN;      //设置BUS口为输入
  LVC4254_5Vto3V;      //LVC4254数据方向为5V往3V
  RS0;
  RW1;  
  E1;
  while(BUSIN & busy) _NOP();  //等待LCD_DB7为0
  E0;                  //重设E=0
  MCU_BUS_DIR_OUT;     //设置BUS口为输出
  LVC4254_3Vto5V;      //LVC4254数据方向为3V往5V
}

//******************************************************************************
//写显示数据(已整理)
//dat:显示数据
void WriteByte(unsigned char dat)
{
 CheckState();          //忙状态检查
 RS1;
 RW0;
 BUSOUT = dat;          //写向数据口
 E1;
 LcdDelay();
 E0;
}

//******************************************************************************
//向LCD发送命令(已整理)
//command :命令
void SEdCommandToLCD(unsigned char command)
 {
   CheckState();			 //忙状态检查
   RS0;
   RW0;
   BUSOUT = command;		          //写入
   E1;
   LcdDelay();
   E0;
}

//******************************************************************************
//清屏(已整理)
//screE:1-左屏,2-右
//每个屏的显示RAM共64行,分8页,每页8行(一行对相一个字节)
void ClearScreE(unsigned char screE)
{ 
  unsigned char i,j;
  SelectScreE(screE);                     //选择指定屏
  for(i=0;i<8;i++)                        //共8页(每页8行*64列)
   { SetLine(i);                          //选择某一页
     for(j=0;j<64;j++)                    //每一页全送0x00为清屏
       {
        WriteByte(0x00);                  //一个数据对应8行,8*64=1页,64*8页
       }
   }
}

//******************************************************************************
//开关显示(已整理)
//onoff=1开,onoff=0为关
//当DB0=1时LCD显示RAM中的内容DB0=0时关闭显示
void SetOnOff(unsigned char onoff)
{
 onoff=0x3e | onoff; 			//0011 111x
 SEdCommandToLCD(onoff);		//发命令到LCD
}

//******************************************************************************
//选择屏幕(已整理)
//screE: 0-全屏,1-左屏,2-右屏
void SelectScreE(unsigned char screE)
{ //MSC-G12864DYSY-2N:选中高电平
 switch(screE)
 { case 0: //开全屏
    CS1_1;
    _NOP();
    CS2_1;
    _NOP();

    break; 
  case 1: //开左屏
   CS1_0; 
   _NOP(); 
   CS2_1; //关右屏
   _NOP(); 

   break;
  case 2: 
    CS1_1;//关左屏
    _NOP();
    CS2_0;//开右屏
    _NOP();
   break;
 }
}

//******************************************************************************
//设定行地址(页,也就是字行)--X 0-7(已整理)
void SetLine(unsigned char line)
{
 line=line & 0x07; 			//保证在 0<=line<=7
 line=line|0xb8; 			//1011 1xxx,
 SEdCommandToLCD(line);                 //设定指定页
}

//******************************************************************************
//设定列地址--Y 0-63(已整理)
void SetColumn(unsigned char column)
{
 column=column &0x3f; 			//0=<column<=63
 column=column | 0x40; 			//01xx xxxx
 SEdCommandToLCD(column);               //指定列
}

//******************************************************************************
//设定显示开始行--XX(已整理)
//0--63
void SetStartLine(unsigned char startline) 
{
 startline=startline & 0x07;            //保证 0<=startline<8
 startline=startline|0xc0; 		//1100 0000(显示起始行ROW设置指令)
 SEdCommandToLCD(startline);           //指定行
}
//******************************************************************************
//初始化LCD   (已整理)
void InitLCD(void) 		
{ 
  LVC4254_DIR0;        //MCU对LVC4254 DIR控制端IO方向设为0
 LVC4254_3Vto5V;      //LVC4254方向为3V转5V,DIR=0
 MCU_BUS_DIR_OUT;     //MCU总线方向为输出
 
 LCDCTL_RSRWE_DIR;    //MCU对LCD 控制组端IO方向设为
 LCDCTL_CS1CS2_DIR;   //    
 
 Lcd12864delay();
 SelectScreE(0);       //选择屏
 SetOnOff(0); 	      //关显示
 ClearScreE(1);	      //清屏1
 ClearScreE(2);       //清屏2
 SelectScreE(0);
 SetOnOff(1); 	      //开显示
 SelectScreE(0);
 SetColumn(0);        //开始列:0
 SetStartLine(0);     //开始行:0
 ClearScreE(0);
}

//******************************************************************************
//读显示数据(已整理)
unsigned char ReadByte(void)
  {unsigned int i;
   unsigned char dat;
   CheckState();
   RS1;
   RW1;
   MCU_BUS_DIR_IN;      //设置BUS口为输入
   LVC4254_5Vto3V; 
   E1;
   for(i=0;i<10;i++);   //这个延时是不同MCU速度而不同
   dat=BUSIN;		//读入,(原文件是没有此句的)
   E0;
   MCU_BUS_DIR_OUT;     //设置BUS口为输出
   LVC4254_3Vto5V;
   return(dat);
}

//******************************************************************************
//显示8*6点阵,如显ASCII86[][6],字符(已整理)
//旋转90度:字模被竖着切分
//lin:字行(0-7), column: 字列(0-31)                                                      
//address : 字模区首地址  由Microcontrol dc 编写
void Show86(unsigned char lin,unsigned char column, unsigned char *address)
 { 
   unsigned char i,j=0;
   if(column>31)                        		//列地址大于31返回
     {return;}
     //第0-9个字列
   else if(column<=9) 
	 {SelectScreE(1);
	  SetLine(lin);  
	  SetColumn((column<<3)-(column<<1));         //计算列地址,以6为倍数.每6列显示一个字符.
	  for(i=0;i<6;i++)
	   WriteByte(address[i]); 
	  }
    //第10个字列
   else if(column==10)							
     { j=(column<<3)-(column<<1);
	    if(j<=63)					//第10个字列的前4列
	      { SelectScreE(1);
		    SetLine(lin); 
		    SetColumn(j);
		    for(i=0;i<4;i++)
		     { WriteByte(address[i]); 
		       j++;
			  }
		   }
	    if(j>=64)
		  { SelectScreE(2);			//第10个字列的后2列
		    j=j-64;
		    SetLine(lin); 
		    SetColumn(j);
		    for(i=4;i<6;i++)                    //在12864中第10个字列的最后两个字节
		     {WriteByte(address[i]); 
			  }
		  }
	  }
  //第11-20个字列	  
else if(10<column&&column<21)							
     { column=column-11;
	   SelectScreE(2); 							
	   SetLine(lin);    
	   SetColumn((column<<3)-(column<<1)+2);
	   for(i=0;i<6;i++)
		 WriteByte(address[i]); 
	 }
  //第21个字列
else  if(column==21)					//第21个字列
     {  j=(column<<3)-(column<<1);
	    if(j<128)					//第21个字列的前2列
	      { SelectScreE(2);
		    SetLine(lin); 
		    SetColumn(j);
		    for(i=0;i<2;i++)
		     { WriteByte(address[i]); 
		       j++;
			  }
		   }		
		if(j>=128)
		  {	
		    j=j-128;
			SelectScreE(3);			//第21个字列的后4列
		    SetLine(lin); 
		    SetColumn(j);
		    for(i=0;i<4;i++)
		     { WriteByte(address[i]); 
			  }
		  }
	  }
  //第22-31个字列
/* else 							
     { column=column-22;
	   SelectScreE(3); 
	   SetLine(lin);    
	   SetColumn((column<<3)-(column<<1)+4);	    
	   for(i=0;i<6;i++)
		 WriteByte(address[i]);  
	}*/ 	
}

//******************************************************************************
//显示8*6字符串	此字体下对应的点阵为:宽x高=8x6 (已整理)
//!!!只能显示在一行上即: 串长+column <=31  column(为6的字列,左屏前4列和右屏后4列不用作显示,两屏共19字列)
//旋转90度:字模被竖着切分
//lin:字行(0-8), column: 字列(0-31)
// *string :指向字符串的首址.
void ShowString86(unsigned char lin,unsigned char column, unsigned char *string)
{ unsigned char ch;
  unsigned char i=0;
  for(i=0;string[i]!='\0';i++)
    {
	  if(i+column >20)                      //保证字符不会起过可显示长度.
	      break;
	  ch=string[i]-0x20;                    //将ASC字符从32-127位置移到0-96位置,以对应ASC86.C中位置
	  Show86(lin,i+column,ASCII86[ch]);
	}
}

//******************************************************************************
//反显一个8*6字块 只适合LCD19264屏,芯片KS0108(HD61202)
//lin:行(0-8), column: 列(0-31)
void ReverseShow86(unsigned char lin,unsigned char column)
{ unsigned char i,j=0;
  unsigned char tab[6];
  if(column>31)                        		//列地址大于31返回
     {return;}
  //第0-9个字列
  if(column<=9) 
     {  SelectScreE(1); 			//如果列数(0-9),则写在第一屏上(左屏)
	SetColumn((column<<3)-(column<<1)); 	//计算列地址,以6为倍数.每6列显示一个字符.
	SetLine(lin);				//设置行
	//tab[0]=(ReadByte()); 			//空读!!!!! ,进行读操作前,必须空读一次
        for(i=0;i<6;i++) 			//读6个字节回来
          tab[i]=~(ReadByte());
        SetColumn((column<<3)-(column<<1));	//设回初始列
        for(i=0;i<6;i++) 			//写回来字节
          WriteByte(tab[i]);
    }
  //第10个字列
  else if(column==10)
     { j=(column<<3)-(column<<1);	  	//暂存列值
	    if(j<=63)				//是否为第10个字列的前4列
		  {
		    SelectScreE(1); 		//前4列显示在左屏
			SetColumn(j);
			SetLine(lin);
			//tab[0]=ReadByte(); 			//空读!!!!!
			for(i=0;i<4;i++) 			//读4个字节回来
              {tab[i]=~ReadByte();j++; } 
			SetColumn((column<<3)-(column<<1));
			for(i=0;i<4;i++) 			//写回来字节
               WriteByte(tab[i]); 
		   }
		if(j>=64)
	      {	column=column-10;			 	//为第10个字列的后2列
		 SelectScreE(2);   				//显示在中屏
			SetColumn(column);
			SetLine(lin);
			//tab[0]=ReadByte(); 			//空读!!!!!
			for(i=0;i<2;i++) 			//读6个字节回来
              {tab[i]=~ReadByte();j++;}
			SetColumn((column<<3)-(column<<1));
			for(i=0;i<2;i++) 			//写回来字节
               WriteByte(tab[i]);
		   }
	}
   //第11-20个字列
  else if(10<column&&column<21)
    { SelectScreE(2);						//显示在中屏
	  column=column-11; 					//如果列数(11-20),则写在第一屏上(中屏)
	  SetColumn((column<<3)-(column<<1)+2); 	        //计算列地址,以6为倍数
	  SetLine(lin);
	  //tab[0]=ReadByte(); 					//空读!!!!! ,进行读操作前,必须空读一次
      for(i=0;i<6;i++) 						//读6个字节回来
        tab[i]=~ReadByte();
      SetColumn((column<<3)-(column<<1)+2);		  		
      for(i=0;i<6;i++) 						//写回来字节
          WriteByte(tab[i]);
	} 
  //第21个字列 --对于192*64屏
	else if(column==21)
     { j=(column<<3)-(column<<1);
	    if(j<=127)
		  {
		    SelectScreE(2);
			SetColumn(j);
			SetLine(lin);
			//tab[0]=ReadByte(); 			//空读!!!!!
			for(i=0;i<2;i++) 			//读6个字节回来
              {tab[i]=~ReadByte();j++; } 
			SetLine(lin);
			SetColumn((column<<3)-(column<<1));
			for(i=0;i<2;i++) 					
               WriteByte(tab[i]); 
		   }
		if(j>=128)
	      {	column=column-21;				//计算字列
		    SelectScreE(3);				//显示右屏
			SetColumn(column);
			SetLine(lin);
			//tab[0]=ReadByte(); 			//空读!!!!!
			for(i=0;i<4;i++) 			//读6个字节回来
              {tab[i]=~ReadByte();j++;}
			SetLine(lin);
			SetColumn((column<<3)-(column<<1));
			for(i=0;i<4;i++) 					
                          WriteByte(tab[i]);
		   }
	}
 
/*  //第22-31个字列--对于192*64屏
  else if(21<column&&column<=31)
    { SelectScreE(3);
	  column=column-22; 					
	  SetColumn((column<<3)-(column<<1)+4); 
	  SetLine(lin);
	  tab[0]=ReadByte(); 					
      for(i=0;i<6;i++) 					
        tab[i]=~ReadByte();
      SetLine(lin);			   			
      SetColumn((column<<3)-(column<<1)+4);	
      for(i=0;i<6;i++) 
          WriteByte(tab[i]);
	}
*/  
}
//******************************************************************************
//反显某行某几个字符   LCD19264
//lin:行(0-7), column: 列(0-15)
void ReverseLinChar(unsigned char lin,unsigned char startcolumn,unsigned char ShowQuantity)
 { unsigned char i;
   for(i=0;i<ShowQuantity;i++)
     {if(startcolumn+i>21)        //列地址大于21返回
           return;
	  ReverseShow86(lin,startcolumn+i);
	  }
 }
//******************************************************************************

⌨️ 快捷键说明

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