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

📄 lcmdrv.c

📁 LCD液晶的驱动程序
💻 C
字号:
/****************************************************************************
* 文件名:LCMDRV.C
* 功能:MG12864图形液晶模块驱动程序。使用LPC2131的GPIO口控制操作。
*       用于ZLG/GUI用户图形界面。
* 液晶模块与LPC2131的连接如下所示:
*	D0 (7)	--		P0.4
*	.		--		.
*	.		--		.
*	.		--		.
*	D7 (14)	--		P0.11
*
*  	CS1		--		P0.12
*	CS2		--		P0.13
*	
*   RST     --      P0.14
*	D/I		--		P0.15
*	R/W		--		GND
*	E		--		P0.16
*
*  R/W为0进行写操作,为1时进行读操作;
*  D/I为1表示数据传送, 为0表示命令传送;
*  E读写脉冲;
*  CS1和CS2为左右半屏选择,高电平选中;
*  RST为复位控制,低电平复位。
*  
*  作者:黄绍斌
*  日期:2005/3/7
****************************************************************************/
#include "config.h"


/* 定义显示缓冲区 */
TCOLOR  gui_disp_buf[GUI_LCM_YMAX/8][GUI_LCM_XMAX];

const uint32 RES    =     0x00000200; //p0.9
const uint32 CS     =     0x00000100; //p0.8
const uint32 SCK    =     0x00001000; //p0.12 
const uint32 SDA    =     0x00002000; //p0.13
const uint32 A0     =     0x00000400; //p0.10

const uint32 MASK_RES   =    0xFFFFFdFF;
const uint32 MASK_CS    =    0xFFFFFeFF;
const uint32 MASK_SCK   =    0xFFFFeFFF;
const uint32 MASK_SDA   =    0xFFFFdFFF;
const uint32 MASK_A0    =    0xFFFFFbFF; 

/* 以下为LCM的驱动层,主要负责发送NT7532的各种命令,操作模式:先命令,后数据 */

/* NT7532 命令定义 */

#define  DISP_ON          0xaf
#define  DISP_OFF         0xae
#define  START_Y          0x60 //Y坐标起使点从0开始,反方向增加坐标时用减法
#define  START_PAGE       0xb0 //0~7
#define  START_X          0x00
#define  XDIR_NORMAL      0xa0 //SEG0---SEG127 ADC Direction Normal
#define  XDIR_REVERSE     0xa1 //SEG127---SEG0 ADC Direction Reverse
#define  YDIR_REVERSE     0xc8 //COM1--COM64 Direction Reverse      
#define  YDIR_NORMAL      0xc0 //COM1--COM64 Direction Normal
#define  LCD_BIAS         0xa3 //LCD Bias 1/9
#define  LCD_VOLUME       0x81 //Electronic Volume 调节对比度,双命令;
#define  LCD_RATIO        0x26 //V0 Voltage Regulator Internal Resistor Ratio   
#define  LCD_PWR_CTL      0x2f //Set Power Control

#define  CMD_SET_PADDR	  0xb0
#define  CMD_SET_CADDR_H  0x10	//设置列地址高4位
#define  CMD_SET_CADDR_L  0x00
#define  CMD_RD_WR		  0xe0	//读-修改-写
#define  CMD_RD_WR_END	  0xee	//读-修改-写结束

uint8  Volume   =  0x00; //亮度对比度值 


/*********************************************************************************
* 名称:DELAY5()
* 功能:软件延时函数。用于LCM显示输出时序控制。
* 入口参数:无
* 出口参数:无
**********************************************************************************/
void delay(uint32 dly)
{ 
    uint32 i;
	for ( ; dly>0; dly--)
		for (i=50000; i>0; i--);
}


/***********************************************************************
* 名称:LCM_WrCommand()
* 功能:写命令子程序
* 入口参数:command  	要写入LCM的命令字
* 注:数据口为P0口(作IO口)
***********************************************************************/
void LCM_WrCommand(uint8 command) 
{   
    uint8 cnt=8;
    uint32  byte1;
	byte1 = command;
    FIO0DIR = (FIO0DIR & MASK_SDA) | SDA;
    FIO0MASK = MASK_A0;
    FIO0CLR = A0;//A0=0;
        
    while(cnt--)
    {
        FIO0MASK = MASK_SDA;
        FIO0PIN = (byte1 & 0x00000080)<<6;//SDA=(bit)(0x80&com);
        FIO0MASK = MASK_SCK;
        FIO0CLR = SCK;//SCK=0;
         
        FIO0MASK = MASK_SCK;
        FIO0SET = SCK;//SCK=1
        
        byte1 = (byte1 << 1);//com=com<<1;
    }     
}


/***********************************************************************
* 名称:LCM_WrData()
* 功能:写数据子程序
* 入口参数:wrdata  	要写入LCM的数据
***********************************************************************/
void LCM_WrData(uint8 wrdata) 
{   
    uint8 cnt=8;
    uint32  byte1;
	byte1 = wrdata;
    FIO0DIR = (FIO0DIR & MASK_SDA) | SDA;
    FIO0MASK = MASK_A0;
    FIO0SET = A0;//A0=1;
        
    while(cnt--)
    {
        FIO0MASK = MASK_SDA;
        FIO0PIN = (byte1 & 0x00000080)<<6;//SDA=(bit)(0x80&dat);
        FIO0MASK = MASK_SCK;
        FIO0CLR = SCK;//SCK=0;
        FIO0MASK = MASK_SCK;
        FIO0SET = SCK;//SCK=1;
        byte1 = (byte1 << 1);//dat=dat<<1;
    }           
}


/***********************************************************************
* 名称:LCM_WriteByte()
* 功能:向指定点写数据(一字节)。
* 入口参数:x 		x坐标值(0-127)
*	    	y       y坐标值(0-63)
*           wrdata	所要写的数据
* 说明:会重新设置CS1/CS2,及其内部指针
***********************************************************************/
void LCM_WriteByte(uint8 x, uint8 y, uint8 wrdata) 
{ 
    uint16 i;
	uint8 temp;
	x = x&0x7f;				// 参数过滤
    y = y&0x3f;
	//更新显示缓冲区
	y = y>>3;
    gui_disp_buf[y][x] = wrdata;
	
	if(x==0)
	{
	   LCM_WrCommand(0xb0 + y);
  	   LCM_WrCommand(0x10 + (x >> 4));
	   LCM_WrCommand(0x00 + (x & 0x0f));

       LCM_WrData(wrdata);
       LCM_WrData(wrdata);	
	}
	else
	{
	   LCM_WrCommand(0xb0 + y);
  	   LCM_WrCommand(0x10 + (x >> 4));
	   LCM_WrCommand(0x00 + (x & 0x0f));

       LCM_WrData(wrdata);
	}
	
	

}


/***********************************************************************
* 名称:LCM_ReadByte()
* 功能:读取指定点上的数据。
* 入口参数:x 	  x坐标值(0-127)
*	   	    y     y坐标值(0-63)
* 出口参数:返回该点上的字节数据。
***********************************************************************/
uint8  LCM_ReadByte(uint8 x, uint8 y)
{ 
  x = x&0x7f;				// 参数过滤
  y = y&0x3f;

  y = y>>3;
  return(gui_disp_buf[y][x]);
}



/////////////////////////////////////////////////////////////////////////


/***********************************************************************
* 名称:LCM_DispFill()
* 功能:向显示缓冲区填充数据
* 入口参数:filldata  	要写入LCM的填充数据
* 注:此函数会设置显示起始行为0,且会自动选中CS1有效
***********************************************************************/
void LCM_DispFill(uint8 filldata)
{ uint8 cnt=8; 
    uint8 cnt1;
     
   for(cnt=0;cnt<9;cnt++) 
        {
  	      LCM_WrCommand(0xb0+cnt);  //Set Page Address 0~7
          LCM_WrCommand(0x10);
          LCM_WrCommand(0x00);
          for(cnt1=0;cnt1<66;cnt1++)
              {
                LCM_WrData(filldata); 
                LCM_WrData(filldata);
               }
        }

}

    
/***********************************************************************
* 名称:LCM_DispIni()
* 功能:LCM显示初始化
* 入口参数:无
* 出口参数:无
* 注:初化显示后,清屏并设置显示起始行为0
*     会复位LCM_DISPCX,LCM_DISPCY.(并会只选中CS1)
***********************************************************************/
void LCM_DispIni(void)
{ 
   SCS = 0x03;
	/*设置GPIO口输入输出方向 1为输出,0为输入*/
	
    FIO0DIR = (FIO0DIR & MASK_RES) | RES; 
	FIO0DIR = (FIO0DIR & MASK_CS) | CS;  
	FIO0DIR = (FIO0DIR & MASK_SCK) | SCK; 
	FIO0DIR = (FIO0DIR & MASK_SDA) | SDA; 
	FIO0DIR = (FIO0DIR & MASK_A0) | A0;  
	
   delay(10);
   FIO0MASK = MASK_CS;
   FIO0CLR = CS;//CS  =0;
  
   FIO0MASK = MASK_RES;
   FIO0CLR = RES;//RES  =0;
  
   delay(10);
   FIO0MASK = MASK_RES;
   FIO0SET = RES;//RES  =1;
   delay(10);
   
   LCM_WrCommand(XDIR_NORMAL);  //  SEG1---SEG132  last bit ADC
   LCM_WrCommand(YDIR_REVERSE); //  COM64--COM1    3 bit
   LCM_WrCommand(LCD_BIAS);     //  select LCD BIAS  1/9
   
   LCM_WrCommand(LCD_PWR_CTL);
   LCM_WrCommand(LCD_VOLUME);
   LCM_WrCommand(Volume);
   LCM_WrCommand(LCD_RATIO);
   LCM_WrCommand(START_Y);  // start line 00
   LCM_WrCommand(DISP_ON);  //Display ON		
}



/////////////////////////////////////////////////////////////////////////////


/****************************************************************************
* 名称:GUI_FillSCR()
* 功能:全屏填充。直接使用数据填充显示缓冲区。
* 入口参数:dat		填充的数据
* 出口参数:无
* 说明:用户根据LCM的实际情况编写此函数。
****************************************************************************/
void  GUI_FillSCR(TCOLOR dat)
{  uint32 i,j;
  
   // 填充缓冲区
   for(i=0; i<(GUI_LCM_YMAX/8); i++)
   {  for(j=0; j<GUI_LCM_XMAX; j++)
      {  gui_disp_buf[i][j] = dat;
      }
   }
   
   // 填充LCM
   LCM_DispFill(dat);
}


/****************************************************************************
* 名称:GUI_Initialize()
* 功能:初始化GUI,包括初始化显示缓冲区,初始化LCM并清屏。
* 入口参数:无
* 出口参数:无
* 说明:用户根据LCM的实际情况编写此函数。
****************************************************************************/
void  GUI_Initialize(void)
{  LCM_DispIni();					// 初始化LCM模块工作模式,纯图形模式
   GUI_FillSCR(0x00);				// 初始化缓冲区为0x00,并输出屏幕(清屏)
}


uint8 const  DEC_HEX_TAB[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
/****************************************************************************
* 名称:GUI_Point()
* 功能:在指定位置上画点。
* 入口参数:x		指定点所在列的位置
*           y		指定点所在行的位置
*           color	显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:返回值为1时表示操作成功,为0时表示操作失败。
* 说明:操作失败原因是指定地址超出缓冲区范围。
****************************************************************************/
uint8  GUI_Point(uint8 x, uint8 y, TCOLOR color)
{  uint8   bak;
   
   // 参数过滤 
   if(x>=GUI_LCM_XMAX) return(0);
   if(y>=GUI_LCM_YMAX) return(0);
   
   // 设置相应的点为1或0 
   bak = LCM_ReadByte(x,y);
   if(0==color)
   {  bak &= (~DEC_HEX_TAB[y&0x07]);
   }
   else
   {  bak |= DEC_HEX_TAB[y&0x07];
   }
  
   // 刷新显示 
   LCM_WriteByte(x, y, bak);
   return(1);
}


/****************************************************************************
* 名称:GUI_ReadPoint()
* 功能:读取指定点的颜色。
* 入口参数:x		指定点所在列的位置
*           y		指定点所在行的位置
*           ret     保存颜色值的指针
* 出口参数:返回0表示指定地址超出缓冲区范围
* 说明:对于单色,设置ret的d0位为1或0,4级灰度则为d0、d1有效,8位RGB则d0--d7有效,
*      RGB结构则R、G、B变量有效。
****************************************************************************/
uint8  GUI_ReadPoint(uint8 x, uint8 y, TCOLOR *ret)
{  uint8  bak;

   // 参数过滤
   if(x>=GUI_LCM_XMAX) return(0);
   if(y>=GUI_LCM_YMAX) return(0);
  
   bak = LCM_ReadByte(x,y);
   if( (bak & (DEC_HEX_TAB[y&0x07])) == 0 ) *ret = 0x00;
     else  *ret = 0x01;
   
   return(1);
}


/****************************************************************************
* 名称:GUI_HLine()
* 功能:画水平线。
* 入口参数:x0		水平线起点所在列的位置
*           y0		水平线起点所在行的位置
*           x1      水平线终点所在列的位置
*           color	显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
* 说明:操作失败原因是指定地址超出缓冲区范围。
****************************************************************************/
void  GUI_HLine(uint8 x0, uint8 y0, uint8 x1, TCOLOR color) 
{  uint8  bak;

   if(x0>x1) 						// 对x0、x1大小进行排列,以便画图
   {  bak = x1;
      x1 = x0;
      x0 = bak;
   }
   
   do
   {  GUI_Point(x0, y0, color);		// 逐点显示,描出垂直线
      x0++;
   }while(x1>=x0);
}


/***********************************************************************
* 名称:GUI_RLine()
* 功能:画竖直线。根据硬件特点,实现加速。
* 入口参数:x0		垂直线起点所在列的位置
*           y0		垂直线起点所在行的位置
*           y1      垂直线终点所在行的位置
*           color	显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:	无
* 说明:操作失败原因是指定地址超出缓冲区范围。
***********************************************************************/
void  GUI_RLine(uint8 x0, uint8 y0, uint8 y1, TCOLOR color) 
{  uint8  bak;
   uint8  wr_dat;
  
   if(y0>y1) 		// 对y0、y1大小进行排列,以便画图
   {  bak = y1;
      y1 = y0;
      y0 = bak;
   }
   
   do
   {  // 先读取当前点的字节数据
      bak = LCM_ReadByte(x0,y0);	
      
      // 进行'与'/'或'操作后,将正确的数据写回LCM
      // 若y0和y1不是同一字节,则y0--当前字节结束,即(y0+8)&0x38,全写1,或者0。
      // 若y0和y1是同一字节,则y0--y1,要全写1,或者0。
      // 方法:dat=0xff,然后按y0清零dat低位,按y1清零高位。
      if((y0>>3) != (y1>>3))		// 竖直线是否跨越两个字节(或以上)
      {  wr_dat = 0xFF << (y0&0x07);// 清0低位
      
         if(color)					
         {  wr_dat = bak | wr_dat;	// 若color不为0,则显示
         }
         else
         {  wr_dat = ~wr_dat;		// 若color为0,则清除显示
            wr_dat = bak & wr_dat;
         }
         LCM_WriteByte(x0,y0, wr_dat);
         y0 = (y0+8)&0x38;
      }
      else
      {  wr_dat = 0xFF << (y0&0x07);
         wr_dat = wr_dat &  ( 0xFF >> (7-(y1&0x07)) );
              
         if(color)					
         {  wr_dat = bak | wr_dat;	// 若color不为0,则显示
         }
         else
         {  wr_dat = ~wr_dat;		// 若color为0,则清除显示
            wr_dat = bak & wr_dat;
         }
         LCM_WriteByte(x0,y0, wr_dat);
         return;
      } // end of if((y0>>3) != (y1>>3))... else...
   }while(y1>=y0);

}




⌨️ 快捷键说明

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