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
|