LCD12864Code.docx
《LCD12864Code.docx》由会员分享,可在线阅读,更多相关《LCD12864Code.docx(27页珍藏版)》请在冰豆网上搜索。
![LCD12864Code.docx](https://file1.bdocx.com/fileroot1/2022-11/27/8cdb648c-a531-4c8b-b0b3-7a529d7c0525/8cdb648c-a531-4c8b-b0b3-7a529d7c05251.gif)
LCD12864Code
/**********************************************************
*@Filename->lcd12864.c
*@Version->V1.1.2
*@Date->11-30-2013
*@Brief->LCD12864驱动函数
*
V1.1
*@Revise->A、修正操作命令宏定义。
*@->B、增加串口、并口转换宏定义,增加对高速度MCU控制通讯频率延时函数
*@->C、显示字符串函数增加显示长度选择,即显示多少个ASCII可显示字符,汉字x2即可
*@->D、去掉显示数组函数,合并在字符串显示里
V1.1.1
*@Revise->增加字符串显示函数,可以从要显示的数组中任意位置显示一定长度字符串
V1.1.2
*@Revise->A、增加对低速晶振系统的MCU通讯频率是否使用的宏定义
*@->B、增加在检测液晶忙超时退出,预防死循环
**********************************************************/
#include"lcd12864.h"
/**********************************************************
自定义显示字符
**********************************************************/
#defineCGRAM_Value64//写入CGRAM数量
u8codeCGROM_Code[]={
//天线图形
0xff,0xff,0x80,0x01,0xbf,0xfd,0xdf,0xfb,0xec,0x37,0xf6,0x6f,0xfb,0xdf,0xfd,0xbf,
0xfe,0x7f,0xfe,0x7f,0xfe,0x7f,0xfe,0x7f,0xfe,0x7f,0xfe,0x7f,0xfe,0x7f,0xff,0xff,
//摄氏图形
//0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x70,0x14,0xd8,0x1d,0x88,0x01,0x80,0x01,0x80,
//0x01,0x80,0x01,0x80,0x01,0x88,0x00,0xc8,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,
//蓝牙图形
0x07,0xe0,0x0e,0x70,0x1e,0xb8,0x3e,0xdc,0x36,0xec,0x3a,0xdc,0x3c,0xbc,0x3e,0x7c,
0x3e,0x7c,0x3c,0xbc,0x3a,0xdc,0x36,0xec,0x3e,0xdc,0x1e,0xb8,0x0e,0x70,0x07,0xe0,
//CD图形
0xff,0xff,0xff,0xff,0xff,0xff,0xe3,0x07,0xc9,0xb3,0x9d,0xb9,0x9f,0xb9,0x9f,0xb9,
0x9f,0xb9,0x9f,0xb9,0x9d,0xb9,0xc9,0xb3,0xe3,0x07,0xff,0xff,0xff,0xff,0xff,0xff,
//右指向手型
0x00,0x00,0x1e,0x00,0x12,0x00,0x73,0xfc,0x52,0x02,0x52,0x1c,0x53,0xe0,0x52,0x10,
0x53,0xe0,0x52,0x10,0x53,0xe0,0x52,0x10,0x73,0xe0,0x12,0x00,0x1e,0x00,0x00,0x00
};
//=========================================================
#ifdefLCD_Work_Mode//如果定义了,则使用并口工作模式
//=========================================================
/**********************************************************
*函数功能--->LCD12864判断忙
*入口参数--->none
*返回数值--->none
*功能说明--->none
**********************************************************/
voidLCD_Check_Busy(void)
{
staticu16busytimeout;//忙超时
//=====================================================
#ifdefLCD_USE_DELAY/*定义了则使用延时调整通讯频率*/
//=====================================================
ktdata=0xf0;//数据口全部置位
do
{
busytimeout++;
if(busytimeout>300)break;
LCD_RS=0;
LCD_Delay();
LCD_RW=1;
LCD_Delay();
LCD_EN=1;
LCD_Delay();
}while(ktdata&LCD_Busy==LCD_Busy);//等待LCD忙完
LCD_EN=0;
//=====================================================
#else/*没定义则不使用*/
//=====================================================
ktdata=0xf0;//数据口全部置位
do
{
busytimeout++;
if(busytimeout>300)break;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
//LCD_Delay();
}while(ktdata&LCD_Busy==LCD_Busy);//等待LCD忙完
LCD_EN=0;
//=====================================================
#endif
//=====================================================
if(busytimeout>=300)printf("LCDBusyTimeOut...\r\n");
busytimeout=0;
}
/**********************************************************
*函数功能--->LCD写入一个字节命令或者数据,判断忙标志(8位数据一次发送完毕)
*入口参数--->dat:
要写入的字节
*ord:
判断dat是命令还是数据依据,“0”为命令,“1”为数据
*返回数值--->none
*功能说明--->none
**********************************************************/
voidLCD_Write_Byte(u8dat,u8ord)
{
//=====================================================
#ifdefLCD_USE_DELAY/*定义了则使用延时调整通讯频率*/
//=====================================================
LCD_Check_Busy();//判断是否在忙?
LCD_EN=0;
LCD_Delay();
LCD_RW=0;
LCD_Delay();
if(ord&0x01)LCD_RS=1;//放上数据或者命令判断位
elseLCD_RS=0;
LCD_EN=1;
LCD_Delay();
ktdata=dat;//放入数据
LCD_Delay();
LCD_EN=0;
//=====================================================
#else/*没定义则不使用*/
//=====================================================
LCD_Check_Busy();//判断是否在忙?
LCD_EN=0;
LCD_RW=0;
if(ord&0x01)LCD_RS=1;//放上数据或者命令判断位
elseLCD_RS=0;
LCD_EN=1;
ktdata=dat;//放入数据
LCD_EN=0;
//=====================================================
#endif
//=====================================================
}
//=========================================================
#else//没定义则使用串口通讯模式
//=========================================================
/**********************************************************
*函数功能--->LCD启动字节
*入口参数--->dt:
传输的字节,高5位在函数内部设定为1
*只是确定RW和RS为,最后那位也是内部确定
*返回数值--->none
*功能说明--->首先传送一个启动字节,送入连续5个“1”用来启
*动一个周期,此时传输计数被重置,并且串行传输
*被同步,紧接着的两个位指定传输方向(R/W,确
*定是读还是写)和传输性质(RS,确定是命令寄存
*器还是数据寄存器),最后的第八位是一个“0”
**********************************************************/
voidLCD12864_Start(u8dt)
{
u8dat,j;
dat=dt|0xf8;//高5位设定为“1”,第八位设定为“0”
LCD_SCL=0;
LCD_Delay();LCD_Delay();
LCD_CS=1;//选中显示屏,高电平有效
for(j=0;j<8;j++)
{
if(dat&0x80)LCD_SDA=1;//放数据到数据线
elseLCD_SDA=0;
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SCL=1;//发送数据,上升沿有效
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SCL=0;
dat<<=1;//左移一位,先发的是高位
}
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SCL=0;
LCD_Delay();LCD_Delay();LCD_Delay();//等待硬件反应(等待数据发送完全)
}
/**********************************************************
*函数功能--->LCD写入一个字节命令或者数据
*入口参数--->dat:
要写入的命令或者数据
*ord:
命令或者数据判断为。
0为命令,1为数据
*返回数值--->none
*功能说明--->none
**********************************************************/
voidLCD_Write_Byte(u8dat,u8ord)
{
u8tem;
u8i,j;
tem=dat&0xf0;//先发送高4位
LCD12864_Start((ord<<1)|0xf0);//置RW为“0”、RS为“ord”并启动串行传输为数据格式
for(j=0;j<2;j++)//一个字节数据或者命令分两次发送
{
LCD_SCL=0;//允许数据线电平变化
LCD_Delay();LCD_Delay();LCD_Delay();
for(i=0;i<8;i++)
{
if(tem&0x80)LCD_SDA=1;//放上数据,屏蔽低4位
elseLCD_SDA=0;
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SCL=1;//发送数据,上升沿有效
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SCL=0;
tem<<=1;//左移一位,先发的是高位
}
tem=(dat<<4)&0xf0;//发完高4位,再次发送低4位
}
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SDA=0;
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_SCL=0;
LCD_Delay();LCD_Delay();LCD_Delay();
LCD_CS=0;
LCD_Delay();LCD_Delay();LCD_Delay();//等待硬件反应(等待数据发送完全)
}
//=========================================================
#endif
//=========================================================
/**********************************************************
*函数功能--->设置LCD显示位置
*入口参数--->x:
行,取值范围:
1~4
*y:
列,取值范围:
0~7
*返回数值--->none
*功能说明--->none
**********************************************************/
voidLCD_Set_xy(u8x,u8y)
{
switch(x)
{
case1:
LCD_Write_Byte((One_LineAddress+y),0);//写入操作地址
break;
case2:
LCD_Write_Byte((Two_LineAddress+y),0);//写入操作地址
break;
case3:
LCD_Write_Byte((Three_LineAddress+y),0);//写入操作地址
break;
case4:
LCD_Write_Byte((Four_LineAddress+y),0);//写入操作地址
break;
default:
LCD_Write_Byte((One_LineAddress+y),0);//写入操作地址
break;
}
}
/**********************************************************
*函数功能--->写入自定义字符到LCD的CGRAM
*入口参数--->*data_code:
写入的数组
*返回数值--->none
*功能说明--->none
**********************************************************/
voidLCD_Write_CGRAM(u8*data_code)
{
u8i;
LCD_Write_Byte(0x34,0);//打开字符扩展指令
LCD_Write_Byte(0x02,0);//SR=0,允许输入
LCD_Write_Byte(0x30,0);//恢复基本指令
LCD_Write_Byte(0x40,0);//CGRAM地址
for(i=0;i{
LCD_Write_Byte(data_code[i*2],1);
LCD_Write_Byte(data_code[i*2+1],1);
}
}
/**********************************************************
*函数功能--->显示一个CGRAM内容
*入口参数--->x:
行
*y:
列
**str为要显示的字符串
*add_h:
CGRAM高位地址
*add_l:
CGRAM低位地址
*返回数值--->none
*功能说明--->none
**********************************************************/
voidDisplay_CGRAM(u8x,u8y,u8add_h,u8add_l)
{
LCD_Set_xy(x,y);//设置显示地址
LCD_Write_Byte(add_h,1);
LCD_Write_Byte(add_l,1);
}
/**********************************************************
*函数功能--->LCD显示字符串
*入口参数--->x:
行
*y:
列
**str:
要显示的字符串
*len:
显示的长度
*返回数值--->none
*功能说明--->只能从数组的开头开始显示len长度字符串
**********************************************************/
voidDisplay_String(u8x,u8y,u8*str,u8len)
{
LCD_Set_xy(x,y);//设置显示地址
while(len--)
{
LCD_Write_Byte(*str,1);
str++;
}
}
/**********************************************************
*函数功能--->LCD显示字符串
*入口参数--->x:
行
*y:
列
**str:
要显示的字符串
*len:
显示的长度
*返回数值--->none
*功能说明--->可以从显示数组的任意位置starsum开始显示len长度的字符串
**********************************************************/
voidDisplay_String1(u8x,u8y,u8*str,u8starsum,u8len)
{
u8i;
LCD_Set_xy(x,y);//设置显示地址
for(i=starsum;i{
LCD_Write_Byte(str[i],1);
}
}
/**********************************************************
*函数功能--->LCD写入GDRAM绘图
*入口参数--->x:
行
*y:
列
*width:
显示图片的宽度
*hieght:
显示图片的高度
**bmp:
要显示的字符串
*dis_mode:
显示模式,是半屏显示还是全屏显示
*0:
半屏显示。
1:
全屏显示
*返回数值--->none
*功能说明--->none
**********************************************************/
voidDisplay_GDRAM(u8x,u8y,u8width,u8height,u8*bmp,u8dis_mode)
{
u8i,j,k;
u8base_x,base_y;//起始坐标
/******全屏绘图显示******/
if(dis_mode)
{
switch(x)
{
case1:
base_y=One_LineAddress+y;
break;
case2:
base_y=Two_LineAddress+y;
break;
case3:
base_y=Three_LineAddress+y;
break;
case4:
base_y=Four_LineAddress+y;
break;
default:
break;
}
LCD_Write_Byte(MPU_8bit_Expansion_Draw_Close,0);//扩充指令
LCD_Write_Byte(MPU_8bit_Expansion_Draw_Open,0);//打开绘图功能
for(j=0;j{
LCD_Write_Byte(base_y+j,0);//写入行号,即第几行开始
LCD_Write_Byte(One_LineAddress,0);//横坐标的第几个字节开始写
for(i=0;i{
LCD_Write_Byte