LCD1602和LCD12864的函数库,包括并行与串行
lcd12864 带中文字库的128X64 是一种具有4 位/8 位并行、2 线或3 线串行多种接口方式,内部含有国标一级、二级简体 中文字库的点阵图形液晶显示模块;其显示分辨率为128×64, 内置8192 个16*16 点汉字,和128 个16*8 点ASCII 字符 集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示8×4 行16×16 点 阵的汉字. 也可完成图形显示.低电压低功耗是其又一显著特点。由该模块构成的液晶显示方案与同类型的图形点阵液晶 显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。 LCD1602
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。 1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
LCD1602基础驱动函数#ifndef __LCD1602_JCK_C__
#define __LCD1602_JCK_C__
/************************************************
** **
** 六哥LCD1602基础函数库 **
** **
**************************************************/
//使用请注意定义引脚
#include"yscx.c"
/*****************************************************************
LCD1602判忙函数
******************************************************************/
void LCD1602_PM(void)
{
unsigned char temp1;//状态信息(判断是否忙)
LCD1602_SJ=0xFF;//记得在包含该头文件前,定义引脚
LCD1602_RS=0; //记得在包含该头文件前,定义引脚
LCD1602_RW=1; //记得在包含该头文件前,定义引脚
LCD1602_E=1; //记得在包含该头文件前,定义引脚
do
{temp1 = LCD1602_SJ;//记得在包含该头文件前,定义引脚
LCD1602_SJ=0xFF;
}
while(temp1&0x80);
LCD1602_E=0;//记得在包含该头文件前,定义引脚
YS_us(1); //
}
/*------------------------------------------------
LCD1602写入命令函数
------------------------------------------------*/
void LCD1602_XZL(unsigned char ml)
{
LCD1602_PM(); //忙则等待
LCD1602_RS= 0; //记得在包含该头文件前,定义引脚
LCD1602_RW= 0; //记得在包含该头文件前,定义引脚
LCD1602_E = 1;//记得在包含该头文件前,定义引脚
LCD1602_SJ=ml; //记得在包含该头文件前,定义引脚
YS_us(1);//稍作延时给LCD反应的时间
LCD1602_E = 0;//记得在包含该头文件前,定义引脚
if(ml==0x01|ml==0x02) YS_ms(2);//清屏和地址归位大概需2ms时间处理
YS_us(35);//其他指令大概需35us
}
/*------------------------------------------------
LCD1602写入数据函数
------------------------------------------------*/
void LCD1602_XSJ(unsigned char sj)
{
LCD1602_PM(); //忙则等待
LCD1602_RS=1; //记得在包含该头文件前,定义引脚
LCD1602_RW=0; //记得在包含该头文件前,定义引脚
LCD1602_E= 1;//记得在包含该头文件前,定义引脚
LCD1602_SJ=sj; //记得在包含该头文件前,定义引脚
YS_us(1);//稍作延时给LCD反应的时间
LCD1602_E= 0;//记得在包含该头文件前,定义引脚
}
/*------------------------------------------------
LCD1602初始化函数
------------------------------------------------*/
void LCD1602_CSH(void)
{
LCD1602_XZL(0x38); /*显示模式设置*/
LCD1602_XZL(0x08); /*显示光标移动设置*/
LCD1602_XZL(0x01); /*显示开及光标设置*/
LCD1602_XZL(0X06);
LCD1602_XZL(0X0c);
}
#endif
LCD1602显示函数
#ifndef __LCD1602_XSK_C__
#define __LCD1602_XSK_C__
/************************************************
******* *********
******* 六哥LCD1602显示函数库 *********
******* *********
************************************************/
#include"yscx.C"
#include"LCD1602_JCK_cx.C"
//为保证显示数制时的运行效率,制作了0—9,A—F的ascll码表
unsigned char code ascll1602[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
/******************************************************
***************LCD1602数制显示(十或十六)************
*******************************************************
sj:需要显示的数据
ml:显示地址设定
xsfs:显示方式,进制和小数点的判断依据,
*/
void LCD1602_SZXS(signed long sj,unsigned char xsfs,ml)///wei为1输出十六进制,否则输出十进制
{
unsigned long xc; //显示缓存
unsigned char a;
bit xsd,fs,bf=0;
xsd=0;
fs=0;
LCD1602_XZL(0x04);//设置光标向左移
LCD1602_XZL(ml);
if(xsfs>10)
{a=16; //输出十六进制
LCD1602_XSJ(0x48);//显示H
xsfs=0;} //
else
{a=10; //否则输出十进制
if(xsfs!=0) xsd=1;//显示小数点使能
if(sj<0)
{sj=~sj+1;
fs=1;} //显示负号使能
}
xc=sj;
if(xc!=0) //显示数据不为0;则显示
{while(xsd) //判是否需要显示小数
{if(xc!=0) //是否还需要计算
{ml=xc%a;
if(bf|ml!=0) //小数部分为0不需要显示
{LCD1602_XSJ(ascll1602[ml]); //取数的ascll码并显示
bf=1; //小数部分不为0标志,小数部分数字有效
}
xc/=a; //取剩下的数
}
else if(bf) LCD1602_XSJ(0x30);//判是否需要补0
else; //小数部分无效,不需要补0
xsfs--;
if(xsfs==0) //小数点位数减一
{xsd=0; //小数计算部分结束标志
if(bf) LCD1602_XSJ(0x2e); //小数部分存在有效数字则显示小数点
}
}
}
////////////整数显示部分////////////////////////////////////////////
do
{LCD1602_XSJ(ascll1602[xc%a]); //取数的ascll码并显示
xc/=a;
}
while(xc!=0);
if(fs) LCD1602_XSJ(0x2d);//判是否需要显示负号
LCD1602_XZL(0x06);//还原光标移动方向
}
/********************************
LCD1602LCD1602字符显示程序
*********************************/
void LCD1602_ZFXS(unsigned char *SJ,t,ml)/*h:行,SJ:字符串指针,t:间隔时间*/
{
LCD1602_XZL(ml); //写指令
while(*SJ)//是否显示完
{
LCD1602_XSJ(*SJ);//写数据
SJ++; //取下一个字符
YS_ms(t); //延时
}
}
#endif
LCD12864基础驱动函数—并行
#ifndef __LCD12864_JCK_C__
#define __LCD12864_JCK_C__
/************************************************
** **
** 六哥LCD12864基础函数库 **
** **
**************************************************/
//使用请注意定义引脚
//通讯方式为并口PSB=1,在设计电路时就把PSB端焊好,节省I/O
#include"yscx.c"
/********************测忙碌**********************/
//测忙碌子程序
//RS=0,RW=1,E=H,D0-D7=状态字
/************************************************/
void LCD12864_PM(void)
{
unsigned char temp1;//状态信息(判断是否忙)
LCD12864_RS=0; // 记得在包含该头文件前,定义引脚
LCD12864_RW=1; // 记得在包含该头文件前,定义引脚
LCD12864_E=1; //记得在包含该头文件前,定义引脚
do
{temp1 = LCD12864_SJ;//记得在包含该头文件前,定义引脚
LCD12864_SJ=0xFF;
}
while(temp1&0x80);
LCD12864_E=0; //记得在包含该头文件前,定义引脚
YS_us(1); //
}
/********************写命令**********************/
//写命令子程序
//
/************************************************/
void LCD12864_XZL(unsigned char ml)/*写命令*/
{
LCD12864_PM();
LCD12864_RS=0; //记得在包含该头文件前,定义引脚
LCD12864_RW=0; //记得在包含该头文件前,定义引脚
LCD12864_E=1; //记得在包含该头文件前,定义引脚
LCD12864_SJ=ml;//记得在包含该头文件前,定义引脚
YS_us(0);//稍作延时给LCD反应的时间
LCD12864_E=0; //记得在包含该头文件前,定义引脚
if(ml==0x01|ml==0x02) YS_ms(3);//清屏和地址归位大概需3ms时间处理
YS_us(50);//其他指令大概需50us
}
/********************写数据**********************/
//写数据子程序
//
/************************************************/
void LCD12864_XSJ(unsigned char sj)
{
LCD12864_PM();
LCD12864_RS=1; //记得在包含该头文件前,定义引脚
LCD12864_RW=0; //记得在包含该头文件前,定义引脚
LCD12864_E=1; //记得在包含该头文件前,定义引脚
LCD12864_SJ=sj;//记得在包含该头文件前,定义引脚
YS_us(0);//稍作延时给LCD反应的时间
LCD12864_E=0; //记得在包含该头文件前,定义引脚
}
/********************初始化**********************/
//复位、通讯方式选择
/************************************************/
void LCD12864_CSH(void)
{
//通讯方式为并口PSB=1,在设计电路时就把PSB端焊好,节省I/O
//LCD12864_XZL(0x34); //34H--扩充指令操作
LCD12864_XZL(0x30); //功能设置,一次送8位数据,基本指令集
LCD12864_XZL(0x0C); //0000,1100 整体显示,游标off,游标位置off
LCD12864_XZL(0x01); //0000,0001 清DDRAM
LCD12864_XZL(0x02); //0000,0010 DDRAM地址归位
LCD12864_XZL(0x80); //1000,0000 设定DDRAM 7位地址000,0000到地址计数器AC
LCD12864_XZL(0x06);
}
#endif
LCD12864基础驱动函数—串行
#ifndef __LCD12864_JCK_CX_C__
#define __LCD12864_JCK_CX_C__
/************************************************
** **
** 六哥LCD12864基础函数库 **
** 串行 **
**************************************************/
//使用请注意定义引脚
//通讯方式为串行通信PSB=0,在设计电路时就把PSB端焊好,节省I/O
#include"yscx.c"
/*******************串行通信*********************
分别发送三个字节,11111AB0,DDDD0000,SSSS000,
A:即表示并行的RW,1为读,0为写
B:即表示并行的RS,1为数据,0为指令
D:即表示并行的高四位数据
S:即表示并行的低四位数据
注:串行要把PSB端为低电平
*************************************************/
void LCD12864_CXTX(unsigned char fs,sj)
{
unsigned char i;
LCD12864_E=0;//时钟SCLK
LCD12864_RS=1;///CS片选
do ////LCD判忙=============
{
for(i=0;i<8;i++)
{
YS_us(1);//MCU与LCD速率匹配
if(i<6) LCD12864_RW=1;//读LCD数据,前6位为1;后两位为0
else LCD12864_RW=0;//命令格式11111100B,0xfc
YS_us(1);//MCU与LCD速率匹配
LCD12864_E=1;//时钟SCLK
YS_us(1);//MCU与LCD速率匹配
LCD12864_E=0;//时钟SCLK
}
YS_us(5);//给LCD反应的时间
LCD12864_E=1;//时钟SCLK
YS_us(1); //给LCD反应的时间
}
while(LCD12864_RW);//判忙只需要取最高位,而不管后面7位
LCD12864_E=0;//时钟SCLK
LCD12864_RS=0;///CS片选
YS_us(1);//给LCD反应的时间
LCD12864_RS=1;///CS片选
for(i=0;i<24;i++)//、、、、送3字节
{
LCD12864_RW=fs&0x80;//数据SID
fs<<=1;
YS_us(1); //MCU与LCD速率匹配
LCD12864_E=1; //时钟SCLK
YS_us(1); //MCU与LCD速率匹配
if(i==7) fs=sj&0xf0; //取数据高四位
if(i==15) fs=sj<<4; //取数据低四位
LCD12864_E=0; //时钟SCLK
YS_us(1); //MCU与LCD速率匹配
}
LCD12864_RS=0;///CS片选
LCD12864_E=1;//恢复高电平不影响其他用途
LCD12864_RW=1;//恢复高电平不影响其他用途
}
/********************写命令**********************/
void LCD12864_XZL(unsigned char ml)/*写命令*/
{
LCD12864_CXTX(0xf8,ml);//命令格式11111000B,0xf8
if(ml==0x01|ml==0x02) YS_ms(4);//清屏和地址归位大概需4ms时间处理
YS_us(50);//其他指令大概需50us
}
/********************写数据**********************/
void LCD12864_XSJ(unsigned char sj)
{
LCD12864_CXTX(0xfa,sj);//命令格式11111010B,0xfa
}
/********************初始化**********************/
//复位、通讯方式选择
/************************************************/
void LCD12864_CSH(void)
{
//LCD12864_XZL(0x34);//34H--扩充指令操作
LCD12864_XZL(0x30); //功能设置,一次送8位数据,基本指令集
LCD12864_XZL(0x0C); //0000,1100 整体显示,游标off,游标位置off
LCD12864_XZL(0x01); //0000,0001 清DDRAM
LCD12864_XZL(0x80); //1000,0000 设定DDRAM 7位地址000,0000到地址计数器AC
LCD12864_XZL(0x06);
}
#endif
LCD12864显示函数
#ifndef __LCD12864_XSK_C__
#define __LCD12864_XSK_C__
/************************************************
******* *********
******* 六哥LCD12864显示函数库 *********
******* *********
************************************************/
//使用请注意定义引脚
#include"LCD12864_JCK_cx.C"//包含基础库
//为保证显示数制时的运行效率,制作了0—9,A—F的ascll码表
unsigned char code ascll12864[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
/*****************************************************
**********LCD12864设置显示地址函数*********************
******************************************************/
unsigned char LCD12864_SZDZ(unsigned char x,y)//
{
switch(y)
{case 0:x|=0x80;break;
case 1:x|=0x90;break;
case 2:x|=0x88;break;
case 3:x|=0x98;break;
default:;
}
return(x);
}
/*****************************************************
**********LCD12864数制显示函数************************
******************************************************
sj:需要显示的数据,取值范围:十进制:-2147483648-2147483647,十六进制:0H-7FFFFFFFH
xsfs:显示方式,进制和小数点的判断依据,
x:显示列,取值范围0-7
y:显示行,取值范围0-3
*/
void LCD12864_SZXS(signed long sj,unsigned char xsfs,x,y)
{
unsigned long xc; //显示缓存
unsigned char d[13];
bit xsd,fs,bf=0;
xsd=0;
fs=0;
LCD12864_XZL(0x04);//设置光标左移
LCD12864_XZL(LCD12864_SZDZ(x,y));//写入显示地址
y=0;
if(xsfs>10)
{x=16; //输出十六进制
d[y]=0x48; //十六进制显示H
y++;
} //
else
{if(sj<0) //十进制正负数判断
{sj=~sj+1;
fs=1;} //负号显示使能
if(xsfs!=0) xsd=1;//小数点显示使能
x=10;
} //
xc=sj;
if(xc!=0) //显示数据不为0;则显示
{while(xsd) //判是否需要显示小数
{if(xc!=0) //是否还需要计算
{sj=xc%x;
if(bf|sj!=0) //小数部分为0不需要显示
{d[y]=ascll12864[xc%x];
y++; //取数的ascll码并显示
bf=1; //小数部分不为0标志,小数部分数字有效
}
xc/=x; //取剩下的数
}
else if(bf)
{d[y]=0x30; //判是否需要补0
y++;}
else; //小数部分无效,不需要补0
xsfs--;
if(xsfs==0) //小数点位数减一
{xsd=0; //小数计算部分结束标志
if(bf)
{d[y]=0x2e; //小数部分存在有效数字则显示小数点
y++;}
}
}
}
do
{d[y]=ascll12864[xc%x]; //取数的ascll码
y++;
xc/=x;
}
while(xc!=0);
if(fs)
{d[y]=0x2d; //取负号ascll码
y++;}
if(y&&0x01) //如果显示的位数为奇数
{d[y]=0x20; //显示一个空格
y++;}
x=y;
y=1;
///////////////显示数据//////////////
do
{
LCD12864_XSJ(d[y]);//显示一个地址的前一个字符
y--;
LCD12864_XSJ(d[y]);//显示一个地址的后一个字符
y+=3; //跳到下一个要显示的两个字符
}
while(y<x); //判断是否显示完毕
LCD12864_XZL(0x06);//设置光标右移
}
/*****************************************************
**********LCD12864字符显示函数************************
******************************************************
*zfc:需要显示的字符串指针,字符数不得超过64个
x:显示列,取值范围0-7
y:显示行,取值范围0-3
*/
void LCD12864_ZFXS(unsigned char *zfc,x,y)
{
unsigned char k1,k2,k3;
k3=x*2;
k1=16-k3;
k2=32-k3;
k3=48-k3;
switch(y) //设置显示地址x和换行标志y
{case 0:x|=0x80;y=0;break;
case 1:x|=0x90;y=16;break;
case 2:x|=0x88;y=32;break;
case 3:x|=0x98;y=48;break;
default:;}
LCD12864_XZL(x);//写显示地址
while(*zfc)
{
if(y==k1) LCD12864_XZL(0X90);//换行判断
else if(y==k2) LCD12864_XZL(0X88);//换行判断
else if(y==k3) LCD12864_XZL(0X98);//换行判断
else;
LCD12864_XSJ(*zfc);//写显示数据
y++;
/////////////判中文字符/////////
if(*zfc>0x7f) zfc++;
else
{zfc++;
if(*zfc>0x7f && y&0x01)
{LCD12864_XSJ(0x20);
y++;}
}
}
}
#endif
延时函数
#ifndef __yscx_C__
#define __yscx_C__
#include<intrins.h>
/*晶振频率33Mhz的stc15系列1T单片机适用*/
/**************************************************
x*us延时函数
精度极高,几乎可以忽略延时误差
***************************************************/
void YS_us(unsigned char t)
{
for( ;t>0;t--)
{
_nop_();//16*nop
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();//16*nop
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();//16*nop
}
_nop_();//12*nop
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();//12*nop
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();//12*nop
}
/*---------------------------------------------------
x*1ms延时函数
----------------------------------------------------*/
void YS_ms(unsigned char t)
{
for( ;t>0;t--)
{
YS_us(250);
YS_us(250);
YS_us(250);
YS_us(249);
}
}
#endif
|