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

📄 lcd.c

📁 LCD显示模块 带多种画图方式
💻 C
字号:
/**************************************************
 *           液晶显示模块
 *适用于KS0108系列液晶控制器,点阵数由用户设定。

 **************************************************/

 /*---------------------------------------------------x---->
   |
   |
   |
   y
   |
   V                                                       */

#ifndef LCD_C
	#define	LCD_C
#endif

#include <reg52.h>
#include "..\include\ASCII.h"
#include "..\include\lcd.h"

/*********液晶命令定义************************/

#define	    DISP_ON    		0x3f	   	//显示ON
#define	    DISP_OFF	   	0x3e	   	//显示OFF
#define	    DISP_FIRST	 	0xc0	   	//显示起始行定义,从第零行显示
#define	    SETX 	      	0x40	   	//定位X方向指令(列)
#define	    SETY		  	0xb8	   	//定位Y方向指令(行)
#define	    LCD_BUSY   		0x80	    //LCM忙判断位


/***********内部变量定义****************************/


sbit   LCD_RST = P2^5;					//复位线占用的引脚
static uchar code Findbit[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

/***************************************************
 *函数性质:私有
 *入口:无   出口:无
 *功能:短延时
 ***************************************************/
static void Delay5nop()
{
	//uchar i = 10;
	;//while (i--);
}


/**************************************************
 *函数性质:私有
 *入口:待选择的端口号  出口;无
 *功能:选择给定的液晶模块
 **************************************************/
 static void SelectLcd(uchar cPart)
{
   if (cPart == SEL_LEFT)
   {
      LCD_CS1 = TRUE;
      LCD_CS2 = FALSE;
   }
   else
   {
     LCD_CS1 = FALSE;
     LCD_CS2 = TRUE;
   }
}



/***************************************************
 *函数性质:私有
 *入口:无  出口:忙标志
 *功能:判忙
 ***************************************************/
static bool  LcdBusy()
{
   	LCD_E  = FALSE;
   	LCD_RS = FALSE;
   	LCD_RW = TRUE;
   	LCD_DATA = 0XFF;
   	Delay5nop();
   	LCD_E =  TRUE;
   	Delay5nop();
	while (LCD_DATA & LCD_BUSY);
   	return TRUE;
}


/***************************************************
 *函数性质:私有
 *入口:待送入的命令。出口;无
 *功能:发送命令入液晶模块
 ***************************************************/
static  void  WrComToLcd( uchar cCommand)
{
    LcdBusy();     //判忙
    LCD_E   = FALSE;
    LCD_RS  = FALSE;
    LCD_RW  = FALSE;
    LCD_DATA =cCommand;
    Delay5nop();
    LCD_E  = TRUE;
    Delay5nop();
    LCD_E  =FALSE;
}


/**************************************************
 *函数性质:私有
 *入口:待写入的数据。  出口:无
 *功能:写数据进LCD
 **************************************************/
static void WrDataLcd(uchar cData)
{
   LcdBusy();     //判忙
    LCD_E   = FALSE;
    LCD_RS  = TRUE;
    LCD_RW  = FALSE;
    LCD_DATA =cData;
    Delay5nop();
    LCD_E  = TRUE;
    Delay5nop();
    LCD_E  = FALSE;
}


/***************************************************
 *函数性质:私有
 *入口:待定位的X,Y坐标,  出口:无
 *功能:设定光标到指定的位置
 ***************************************************/
static void SetLcdCur(uchar x, uchar y)
{
   uchar x1;
   uchar y1;
   if (x >= MAX_XSIZE/2)
   {
      x1= x-MAX_XSIZE/2;
      SelectLcd(SEL_RIGHT);
   }
   else
   {
      x1= x;
      SelectLcd(SEL_LEFT);
   }
   y1 = y/8;
   WrComToLcd(SETX | x1);
   WrComToLcd(SETY | y1);
}


/***************************************************
 *函数性质:私有
 *入口:x,y坐标  出口:读得的数据
 *功能:从LCD里读出一个字节的数据
 ***************************************************/
 static uchar  ReadLcdByte(uchar x, uchar y)
{
   uchar  cbyte;

   SetLcdCur(x,y);
   LCD_DATA  = 0xff;
   LCD_E     = FALSE;
   LCD_RS    = TRUE;
   LCD_RW    = TRUE;
   Delay5nop();
   LCD_E     = TRUE;
   Delay5nop();//延时必须足够长
   cbyte     =  LCD_DATA;//假读一次数据。
   LCD_E     = FALSE;

   SetLcdCur(x,y);
   LCD_DATA  = 0xff;
   LCD_E     = FALSE;
   LCD_RS    = TRUE;
   LCD_RW    = TRUE;
   Delay5nop();
   LCD_E     = TRUE;
   Delay5nop();
   cbyte     =  LCD_DATA;//第二次读的才是真正的数据。
   LCD_E     = FALSE;
   return cbyte;
}


/*************************************************
 *函数性质:私有
 *入口:指定的X,Y坐标  出口:无
 *功能:在指定的X,Y坐处画一点
 *************************************************/
 static void LcdDrawPoint(uchar x, uchar y, uchar Color)
{
   uchar temp;
   uchar cbyte;

   cbyte = Findbit[ y%8];
   temp=ReadLcdByte(x,y);
   if (Color == WHITE)
   {
     cbyte  = ~cbyte;
     temp  &= cbyte;
   }
   else
   {
     temp |=cbyte;
   }
   SetLcdCur(x,y);
   WrDataLcd(temp);
}


/**********************************************
 *函数性质:公共
 *入口:无   出口:无
 *功能:清屏
 **********************************************/
 void LCD_LcdClr()
{
   uchar i;
   uchar j;
   for (j=0; j < MAX_YSIZE; j+=8)
   {
      for (i=0; i < MAX_XSIZE; i++)
      {
         SetLcdCur(i,j);
         WrDataLcd(0);
      }
   }
}




/**********************************************
 *函数性质:公共
 *入口:无,出口:无
 *功能:关闭液晶端口。
 **********************************************/
 void LCD_DisbLcdSel()
{
   LCD_CS1 = TRUE;
   LCD_CS2 = TRUE;
}


/******************************************************
 *函数性质:公共
 *入口:给定的坐标及待显示的数据样式。出口:无
 *功能:按给定的坐标在屏幕上显示图片,同时,图片
 *具有反白及图片隐藏功能,图片的宽度及高度在字模的头两个字节里。
 ******************************************************/
void LCD_lcdDisp(uchar *cCode, uchar x, uchar y , uchar color)
{
   uchar i;
   uchar idata temp_x,bmpwidth,bmphigh;
   bmpwidth = *cCode++;      //从字模里取出图片的高度及宽度
   bmphigh  = (*cCode)/8;
   cCode++;
   temp_x = x;
   while (bmphigh--)
   {
      x=temp_x;
      for (i=0; i < bmpwidth; i++)
      {
         SetLcdCur(x,y);
         if (color == WHITE)
         {
            WrDataLcd(~(*cCode));//反色显示
         }
         else if (color == BLACK)
         {
            WrDataLcd(*cCode); //正常显示
         }
         else if (color == HIDE)
         {
           WrDataLcd(0); //隐藏当前显示的图片。
         }
         cCode++;
         x++;
      }
      y+=8;
   }
   LCD_DisbLcdSel();                 //在每一次写入LCD后关闭片选,是为了别的操作不影响液晶显示。
}


/**********************************************
 *函数性质:公共
 *入口:起始点的X,Y坐标及长度,方向,出口:无
 *功能:从给定的起始点开始,按给定的长度及方向
 *划一直线。不支持斜线,划线方向以X、Y的增量方向
 *为基准。
 **********************************************/
 void LCD_DrawLine(uchar start_x,uchar start_y,uchar Line_Len,
                   uchar Flag,uchar Color)
{
    while (Line_Len--)
    {
       LcdDrawPoint(start_x,start_y,Color);
       if (Flag == X_FLAG)
       {
          start_x++;
       }
       else
       {
         start_y++;
       }
    }
    LCD_DisbLcdSel();
}


/******************************************************
 *函数性质:公共
 *入口:对应的ASCII码字符及坐标、颜色(是否要反色显示)
 *出口:无
 *功能:在给定的坐标显示ASCII字符串。
 ******************************************************/
 void LCD_LcdDispASCII(uchar *Ascii, uchar x,uchar y,uchar color_char)
{
   uchar temp;
   uchar i=0;
   while(*(Ascii+i) != '\0')
   {
      temp=*(Ascii+i)-32;//将ASCII转换成实际值"!"的ASCII为33。
      if (i == color_char || color_char == ALL_WHITE)  //当前的字符需要反色显示
      {
         LCD_lcdDisp(cAscii+temp*ASCII_SIZE,x,y,WHITE);
      }
      else
      {
         LCD_lcdDisp(cAscii+temp*ASCII_SIZE,x,y,BLACK);
      }
      x+=ASCII_WIDTH;
      i++;
   }
}



/*
 *函数性质:公共
 *入口:无
 *出口:无
 *功能:初始化液晶
 */
void LCD_LcdIni()
{
   SelectLcd(SEL_LEFT);
   WrComToLcd(DISP_OFF);
   WrComToLcd(DISP_ON);
   WrComToLcd(DISP_FIRST);

   SelectLcd(SEL_RIGHT);
   WrComToLcd(DISP_OFF);
   WrComToLcd(DISP_ON);
   WrComToLcd(DISP_FIRST);
   LCD_LcdClr();
   LCD_DisbLcdSel();
}


/**************************************************************
 *函数性质:公共
 *入口:无,  出口:无
 *功能:开启液晶背光
 **************************************************************/
 void LCD_OpenLED()
{
   LED_CTL  = FALSE;
}


/**************************************************************
 *函数性质:公共
 *入口:无   出口:无
 *功能:关闭液晶背光。
 **************************************************************/
 void LCD_CloseLED()
{
	LED_CTL = TRUE;
}


/*
 *函数性质:公共
 *入口:无
 *出口:无
 *功能:复位液晶。
 */
void LCD_Rst(void)
{
	uint i = 0xffff;
	LCD_RST = FALSE;
	while (i--);
	LCD_RST = TRUE;
}

⌨️ 快捷键说明

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