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

📄 lcm_drive.c

📁 * 功能:DP_51PRO实验仪图形液晶显示实验。在屏幕上半部分显示一幅图片 * 在屏幕下半部分显示“重庆科技学院”等
💻 C
字号:
/***********************************************************************
* 文件名:LCM_DRIVE.C
* 功能:图形液晶TG12864B-2驱动程序。
* 说明:在LCM_DRIVE.H文件中定义了LCM操作地址,左半屏的写命令操作地址为2004H,写
*      数据操作地址为2005H,右半屏的写命令操作地址为2000H,写数据操作地址为2001H;
*      由于GRAPHICS.C中使用了disp_buf作为作图缓冲区,所以LCM_WriteByte()、LCM_
*      DispFill()均要更新disp_buf。
***********************************************************************/
#include  "CONFIG.H"
uint8 xdata  disp_buf[LCM_YMAX/8][LCM_XMAX];

/* LCM复位控制脚定义 */
sbit	LCM_RST		= P1^0;			

/***********************************************************************
* 名称:LCM_Wr1Command()
* 功能:写命令子程序,所选屏为左半屏(CS1)。
* 入口参数:command  	要写入LCM的命令字
***********************************************************************/
#define	LCM_Wr1Command(command)		LCMCS1W_COM = command

/***********************************************************************
* 名称:LCM_Wr2Command()
* 功能:写命令子程序,所选屏为右半屏(CS2)。
* 入口参数:command  	要写入LCM的命令字
***********************************************************************/
#define	LCM_Wr2Command(command)		LCMCS2W_COM = command

/***********************************************************************
* 名称:LCM_Wr1Data()
* 功能:写数据子程序,所选屏为左半屏(CS1)。
* 入口参数:wrdata  	要写入LCM的数据
***********************************************************************/
#define LCM_Wr1Data(wrdata) 		LCMCS1W_DAT = wrdata

/***********************************************************************
* 名称:LCM_Wr2Data()
* 功能:写数据子程序,所选屏为右半屏(CS2)。
* 入口参数:wrdata  	要写入LCM的数据
***********************************************************************/
#define LCM_Wr2Data(wrdata) 		LCMCS2W_DAT = wrdata


/***********************************************************************
* 名称:LCM_DispIni()
* 功能:LCM显示初始化。使能显示,设置显示起始行为0并清屏。
* 入口参数:无
* 出口参数:无
***********************************************************************/
void  LCM_DispIni(void)
{  uint16  i;

   LCM_RST = 0;				// 复位驱动芯片
   for(i=0; i<500; i++);
   LCM_RST = 1;    

   LCM_Wr1Command(LCM_DISPON);		// 打开显示
   LCM_Wr1Command(LCM_STARTROW);	// 设置显示起始行为0
   LCM_Wr2Command(LCM_DISPON);	
   LCM_Wr2Command(LCM_STARTROW);		
   LCM_DispClr();			// 清屏
        
   LCM_Wr1Command(LCM_ADDRSTRY+0);	// 设置页(8个行)地址
   LCM_Wr1Command(LCM_ADDRSTRX+0);	// 设置列地址,即列
   LCM_Wr2Command(LCM_ADDRSTRY+0);
   LCM_Wr2Command(LCM_ADDRSTRX+0);
}

/***********************************************************************
* 名称:LCM_DispFill()
* 功能:向显示屏填充数据
* 入口参数:filldata  	要写入LCM的填充数据
* 出口参数:无
* 说明:会更新disp_buf相应存储单元
***********************************************************************/
void  LCM_DispFill(uint8 filldata)
{  uint8  x, y;
	
   LCM_Wr1Command(LCM_STARTROW);	// 设置显示起始行为0
   LCM_Wr2Command(LCM_STARTROW);	

   for(y=0; y<8; y++)
   {  LCM_Wr1Command(LCM_ADDRSTRY+y);	// 设置页(8个行)地址
      LCM_Wr1Command(LCM_ADDRSTRX); 	// 设置列地址
      LCM_Wr2Command(LCM_ADDRSTRY+y);
      LCM_Wr2Command(LCM_ADDRSTRX);
   
      for(x=0; x<64; x++)
      {  LCM_Wr1Data(filldata);
         LCM_Wr2Data(filldata);
         disp_buf[y][x] = filldata;
         disp_buf[y][x+64] = filldata;
      }	
   }
}


/* ASCII码对应的点阵数据表 */
uint8 code  ASCII_TAB20[80] = { 0x00, 0x00, 0x00, 0x00, 0x00,
			 	0x00, 0x00, 0x9e, 0x00, 0x00,
                         	0x00, 0x0e, 0x00, 0x0e, 0x00,
                         	0x28, 0xfe, 0x28, 0xfe, 0x28,
                         	0x48, 0x54, 0xfe, 0x54, 0x24,
                         	0x46, 0x26, 0x10, 0xc8, 0xc4,
                         	0x6c, 0x92, 0xaa, 0x44, 0xa0,
                         	0x00, 0x0a, 0x06, 0x00, 0x00,
			 	0x00, 0x38, 0x44, 0x82, 0x00,
			 	0x00, 0x82, 0x44, 0x38, 0x00,
			 	0x28, 0x10, 0x7c, 0x10, 0x28,
			 	0x10, 0x10, 0x7c, 0x10, 0x10,
			 	0x00, 0xa0, 0x60, 0x00, 0x00,
			 	0x10, 0x10, 0x10, 0x10, 0x10,
			 	0x00, 0xc0, 0xc0, 0x00, 0x00,
			 	0x40, 0x20, 0x10, 0x08, 0x04
		               };

uint8 code  ASCII_TAB30[80] = { 0x7C, 0xA2, 0x92, 0x8A, 0x7C,	//'0'		
				0x00, 0x84, 0xFE, 0x80, 0x00,					//'1'
/*
	0x00, 0x84, 0xFE, 0x80, 0x00,对应1-5列	  
	   显示 ' 1 '
	  0 1 2 3 4 5 6 7 
	7 .	. .	. .	. .	.
	6 .	. .	1 .	. .	.
	5 .	. 1	1 .	. .	.
	4 .	. .	1 .	. .	.
	3 .	. .	1 .	. .	.
	2 .	. .	1 .	. .	.
	1 .	. .	1 .	. .	.
	0 .	. 1	1 1	. .	.
*/

				0x84, 0xC2, 0xA2, 0x92, 0x8C,					//'2'
				0x42, 0x82, 0x8A, 0x96, 0x62,					//'3'
				0x30, 0x28, 0x24, 0xFE, 0x20,					//'4'
				0x4E, 0x8A, 0x8A, 0x8A, 0x72,					//'5'
				0x78, 0x94, 0x92, 0x92, 0x60,					//'6'
				0x02, 0xE2, 0x12, 0x0A, 0x06,					//'7'
				0x6C, 0x92, 0x92, 0x92, 0x6C,					//'8'
 				0x0C, 0x92, 0x92, 0x52, 0x3C,					//'9'
				0x00, 0x6C, 0x6C, 0x00, 0x00,			
				0x00, 0xAC, 0x6C, 0x00, 0x00,			
				0x10, 0x28, 0x44, 0x82, 0x00,			
				0x28, 0x28, 0x28, 0x28, 0x28,			
				0x00, 0x82, 0x44, 0x28, 0x10,			
				0x04, 0x02, 0xA2, 0x12, 0x0C
		       	       };			

uint8 code  ASCII_TAB40[80] = { 0x64, 0x92, 0xF2, 0x82, 0x7C,			
				0xFC, 0x22, 0x22, 0x22, 0xFC,			
		 		0xFE, 0x92, 0x92, 0x92, 0x6C,			
				0x7C, 0x82, 0x82, 0x82, 0x44,			
				0xFE, 0x82, 0x82, 0x44, 0x38,		
				0xFE, 0x92, 0x92, 0x92, 0x82,		
				0xFE, 0x12, 0x12, 0x12, 0x02,			
				0x7C, 0x82, 0x92, 0x92, 0xF4,			
				0xFE, 0x10, 0x10, 0x10, 0xFE,		
				0x00, 0x82, 0xFE, 0x82, 0x00,		
				0x40, 0x80, 0x82, 0x7E, 0x02,			
				0xFE, 0x10, 0x28, 0x44, 0x82,			
				0xFE, 0x80, 0x80, 0x80, 0x80,		
				0xFE, 0x04, 0x18, 0x04, 0xFE,			
				0xFE, 0x08, 0x10, 0x20, 0xFE,			
				0x7C, 0x82, 0x82, 0x82, 0x7C
		       	       };

uint8 code  ASCII_TAB50[80] = { 0xFE, 0x12, 0x12, 0x12, 0x0C,
				0x7C, 0x82, 0xA2, 0x42, 0xBC,
				0xFE, 0x12, 0x32, 0x52, 0x8C,			
				0x8C, 0x92, 0x92, 0x92, 0x62,			
				0x02, 0x02, 0xFE, 0x02, 0x02,	
				0x7E, 0x80, 0x80, 0x80, 0x7E,
				0x3E, 0x40, 0x80, 0x40, 0x3E,
				0x7E, 0x80, 0x70, 0x80, 0x7E,
				0xC6, 0x28, 0x10, 0x28, 0xC6,
				0x0E, 0x10, 0xE0, 0x10, 0x0E,
				0xC2, 0xA2, 0x92, 0x8A, 0x86,
				0x00, 0xFE, 0x82, 0x82, 0x00,
				0x04, 0x08, 0x10, 0x20, 0x40,
				0x00, 0x82, 0x82, 0xFE, 0x00,
				0x08, 0x04, 0x02, 0x04, 0x08,
				0x80, 0x80, 0x80, 0x80, 0x80
		      	       };

uint8 code  ASCII_TAB60[80] = { 0x00, 0x02, 0x04, 0x08, 0x00,
				0x40, 0xA8, 0xA8, 0xA8, 0xF0,
				0xFE, 0x90, 0x88, 0x88, 0x70,
				0x70, 0x88, 0x88, 0x88, 0x40,
				0x70, 0x88, 0x88, 0x90, 0xFE,
				0x70, 0xA8, 0xA8, 0xA8, 0x30,
				0x10, 0xFC, 0x12, 0x02, 0x04,
				0x18, 0xA4, 0xA4, 0xA4, 0x7C,
				0xFE, 0x10, 0x08, 0x08, 0xF0,
				0x00, 0x88, 0xFA, 0x80, 0x00,
				0x40, 0x80, 0x88, 0x7A, 0x00,
				0xFE, 0x20, 0x50, 0x88, 0x00,
				0x00, 0x82, 0xFE, 0x80, 0x00,
				0xF8, 0x08, 0x30, 0x08, 0xF8,
				0xF8, 0x10, 0x08, 0x08, 0xF0,
				0x70, 0x88, 0x88, 0x88, 0x70
		               };

uint8 code  ASCII_TAB70[80] = { 0xF8, 0x28, 0x28, 0x28, 0x10,
				0x10, 0x28, 0x28, 0x30, 0xF8,
				0xF8, 0x10, 0x08, 0x08, 0x10,
				0x90, 0xA8, 0xA8, 0xA8, 0x40,
				0x08, 0x7E, 0x88, 0x80, 0x40,
				0x78, 0x80, 0x80, 0x40, 0xF8,
				0x38, 0x40, 0x80, 0x40, 0x38,
				0x78, 0x80, 0x60, 0x80, 0x78,
				0x88, 0x50, 0x20, 0x50, 0x88,
				0x18, 0xA0, 0xA0, 0xA0, 0x78,
				0x88, 0xC8, 0xA8, 0x98, 0x88,
				0x00, 0x10, 0x6C, 0x82, 0x00,
				0x00, 0x00, 0xFE, 0x00, 0x00,
				0x00, 0x82, 0x6C, 0x10, 0x00,
				0x10, 0x10, 0x54, 0x38, 0x10,
				0x10, 0x38, 0x54, 0x10, 0x10
		       	       };
uint8 code word[48]=
{0x00,0x00,0x30,0x04,0xCC,0x07,0x48,0x04,0xF8,0x7F,0x48,0x04,0x48,0x04,0x08,0x04,//"年",0
0x00,0x00,0x00,0x60,0xF8,0x1F,0x48,0x02,0x48,0x02,0x48,0x42,0xF8,0x7F,0x00,0x00, //"月",1
0x00,0x00,0x00,0x00,0xF8,0x7F,0x08,0x11,0x08,0x11,0x08,0x11,0xF8,0x3F,0x00,0x00};/*"日",2*/
/* (8 X 16 , 华文细黑 ) */
void LCM_DispWord(uint8 disp_cy, uint8 disp_cx,char dispdata) 
{  uint8  code  *pchardata;
   uint8  i;
    // 参数过滤
   disp_cy = disp_cy&0x07;	//行	
   disp_cx = disp_cx&0x0f;	//列
   
   pchardata = &word[dispdata];			
   
 
   if( (disp_cx&0x08) == 0 )				    // 选择液晶控制芯片(即CS1--控制前8个字符,CS2--控制后8个字符)
   {  i = disp_cx<<3;							// 当前要写8列的首地址(把64列分为8个8列)
      LCM_Wr1Command(LCM_ADDRSTRX+i);			// 设置当前列地址,即列0x40(64)+i
      LCM_Wr1Command(LCM_ADDRSTRY+disp_cy);		// 设置当前页地址,即8行0xb8(8*23=184)+disp_cy
      
      for(i=0; i<5; i++);				//延时

      for(i=0; i<8; i++)				//发送5列数据
      {  LCM_Wr1Data(*pchardata);		// 发送数据									*/
         pchardata++; pchardata++;
      }
   }
   else
   {  i = (disp_cx&0x07)<<3;				// 若Y>7,则选取用CS2并且地址值要先减去8,再乘以8
      LCM_Wr2Command(LCM_ADDRSTRX+i);
      LCM_Wr2Command(LCM_ADDRSTRY+disp_cy);		// 设置当前页地址,即8行
      
      for(i=0; i<5; i++);

      for(i=0; i<8; i++)
      {  LCM_Wr2Data(*pchardata);		// 发送数据									*/
         pchardata++; pchardata++;
      }
   }
}       	       		       	  

	       	       
/***********************************************************************
* 名称:LCM_DispChar()
* 功能:指定地址显示字符。
* 入口参数:disp_cy		显示行值(0-7)	
*	   disp_cx		显示列值(0-15)
*	   dispdata		所要显示的字符(ASCII码)
* 注:支持显示字符0-9、A-Z、a-z及空格,字符显示格式为5*7,模为8*8,所以
*     屏幕显示为8*16(共8行,每行16个字符)。
***********************************************************************/
void LCM_DispChar(uint8 disp_cy, uint8 disp_cx, char dispdata) 
{  uint8  code  *pchardata;
   uint8  i;
    // 参数过滤
   disp_cy = disp_cy&0x07;	//行	
   disp_cx = disp_cx&0x0f;	//列
   
   /* 先要找出显示数据的类型,并设置相应的点阵数据表,然后设置指针,以取得对应的点阵数据。 */      			
   switch(dispdata&0xf0)
   {  case 0x20:
  	   dispdata = (dispdata&0x0f)*5;
           pchardata = &ASCII_TAB20[dispdata];
           break;

      case 0x30:
  	   dispdata = (dispdata&0x0f)*5;
           pchardata = &ASCII_TAB30[dispdata];
           break;

      case 0x40:
	   dispdata = (dispdata&0x0f)*5;
           pchardata = &ASCII_TAB40[dispdata];
           break;

      case 0x50:
	   dispdata = (dispdata&0x0f)*5;
           pchardata = &ASCII_TAB50[dispdata];
           break;

      case 0x60:
	   dispdata = (dispdata&0x0f)*5;
           pchardata = &ASCII_TAB60[dispdata];
           break;

      case 0x70:
	   dispdata = (dispdata&0x0f)*5;
           pchardata = &ASCII_TAB70[dispdata];
           break;
	    
      default:
	   pchardata = &ASCII_TAB20[0];
	   break;
   } // end of switch(dispdata&0xf0)...
   
   
   if( (disp_cx&0x08) == 0 )				    // 选择液晶控制芯片(即CS1--控制前8个字符,CS2--控制后8个字符)
   {  i = disp_cx<<3;							// 当前要写8列的首地址(把64列分为8个8列)
      LCM_Wr1Command(LCM_ADDRSTRX+i);			// 设置当前列地址,即列0x40(64)+i
      LCM_Wr1Command(LCM_ADDRSTRY+disp_cy);		// 设置当前页地址,即8行0xb8(8*23=184)+disp_cy
      
      for(i=0; i<5; i++);				//延时
      LCM_Wr1Data(0x00);				// 显示一列空格
      for(i=0; i<5; i++)				//发送5列数据
      {  LCM_Wr1Data(*pchardata);		// 发送数据									*/
         pchardata++;
      }
      LCM_Wr1Data(0x00);				// 显示一列空格
      for(i=0; i<5; i++);               //延时
      LCM_Wr1Data(0x00);				// 显示一列空格
   }
   else
   {  i = (disp_cx&0x07)<<3;				// 若Y>7,则选取用CS2并且地址值要先减去8,再乘以8
      LCM_Wr2Command(LCM_ADDRSTRX+i);
      LCM_Wr2Command(LCM_ADDRSTRY+disp_cy);		// 设置当前页地址,即8行
      
      for(i=0; i<5; i++);
      LCM_Wr2Data(0x00);				// 显示一列空格
      for(i=0; i<5; i++)
      {  LCM_Wr2Data(*pchardata);		// 发送数据									*/
         pchardata++;
      }
      LCM_Wr2Data(0x00);	
      for(i=0; i<5; i++);
      LCM_Wr2Data(0x00);	
   }
}       	       		       	  


/***********************************************************************
* 名称:LCM_DispStr()
* 功能:字符串显示输出。
* 入口参数:disp_cy 	显示起始行(0-7)
*	   disp_cx      显示起始列(0-15)
*	   disp_str	字串指针
* 出口参数:无
* 注:支持显示字符0-9、A-Z、a-z及空格,字符显示格式为5*7,模为8*8,所以屏幕显示
*     为8*16(共8行,每行16个字符)。
***********************************************************************/
void  LCM_DispStr(uint8 disp_cy, uint8 disp_cx, char *disp_str) 
{  while( *disp_str != '\0')
   {  	// 参数过滤
      disp_cy = disp_cy&0x07;	//行		
      disp_cx = disp_cx&0x0f;	//列
      LCM_DispChar(disp_cy, disp_cx, *disp_str); 	// 显示字符
   	
      disp_str++;					// 指向下一字符数据
      disp_cx++;
      if(disp_cx>15) disp_cy++;				// 指向下一显示行
   }
}
   




⌨️ 快捷键说明

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