📄 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 + -