|
//LCD顯示器端口定義
#define LCD_RS P21 // LCD數(shù)據(jù)/命令(H/L)選擇端
#define LCD_RW P22 // LCD讀/寫(H/L)選擇端
#define LCD_EN P23 // LCD使能信號高有效
#define LCD_DATA P0 // LCD并行數(shù)據(jù)線
#define LCD_BUSY P07 // LCD忙信號位
//12864特殊端口
//#define LCD_12864_CSA P24 // LCD12864左半屏選擇端
//#define LCD_12864_CSB P25 // LCD12864右半屏選擇端
//12864基本指令集********************************************************************
#define LCD_12864_CLR 0x01 //清屏,AC、光標(biāo)歸零,DDRAM填滿0x20H
#define LCD_12864_GO_HOME 0x02 //AC、光標(biāo)歸零,DDRAM不改變
//輸入方式設(shè)置
#define LCD_12864_AC_AUTO_INCREMENT 0x06 //數(shù)據(jù)讀、寫操作后,AC自動增一
#define LCD_12864_AC_AUTO_DECREASE 0x04 //數(shù)據(jù)讀、寫操作后,AC自動減一
#define LCD_12864_MOVE_ENABLE 0x05 //數(shù)據(jù)讀、寫操作,畫面平移
#define LCD_12864_MOVE_DISENABLE 0x04 //數(shù)據(jù)讀、寫操作,畫面不動
//設(shè)置顯示、光標(biāo)及閃爍開、關(guān)
#define LCD_12864_DISPLAY_ON 0x0C //顯示開
#define LCD_12864_DISPLAY_OFF 0x08 //顯示關(guān)
#define LCD_12864_CURSOR_ON 0x0A //光標(biāo)顯示
#define LCD_12864_CURSOR_OFF 0x08 //光標(biāo)不顯示
#define LCD_12864_CURSOR_BLINK_ON 0x09 //光標(biāo)閃爍
#define LCD_12864_CURSOR_BLINK_OFF 0x08 //光標(biāo)不閃爍
//光標(biāo)、畫面移動,不影響DDRAM
#define LCD_12864_LEFT_MOVE 0x18 //LCD顯示(整屏)左移一位 0x05
#define LCD_12864_RIGHT_MOVE 0x1C //LCD顯示(整屏)右移一位 0x07
#define LCD_12864_CURSOR_LEFT_MOVE 0x10 //光標(biāo)左移一位
#define LCD_12864_CURSOR_RIGHT_MOVE 0x14 //光標(biāo)右移一位
//指令集設(shè)置
#define LCD_12864_BASIC_INSTRUCTION 0x30 //使用基本指令集
#define LCD_12864_EXPAND_INSTRUCTION 0x34 //使用擴(kuò)充指令集
//地址設(shè)定
#define LCD_12864_BASIC_CGRAM 0x40 //設(shè)定CGRAM地址到地址計數(shù)器(AC)64X256 點(diǎn)陣顯示RAM(GDRAM)。
#define LCD_12864_BASIC_DDRAM 0x80 //設(shè)定DDRAM地址到地址計數(shù)器(AC)
//12864擴(kuò)充指令集********************************************************************
#define LCD_12864_ORDER 0x01 //待命模式將DDRAM 填滿“ 20H ”, 并且設(shè)定DDRAM 的地址計數(shù)器(AC)到“00H”
#define LCD_12864_IRAM_ON 0x02 //允許輸入IRAM地址
#define LCD_12864_VERTICAL_ADDRESS_ON 0x03 //允許輸入垂直卷動地址
//反白顯示
#define LCD_12864_UP_ONE 0x04 //第一行反白顯示
#define LCD_12864_UP_TWO 0x05 //第二行反白顯示
#define LCD_12864_UP_THREE 0x06 //第三行反白顯示
#define LCD_12864_UP_FOUR 0x07 //第四行反白顯示
//睡眠模式
#define LCD_12864_SLEEP_ON 0x08 //進(jìn)入睡眠模式
#define LCD_12864_SLEEP_OFF 0x0c //脫離睡眠模式
//在擴(kuò)充指令集時的指令選擇
#define LCD_12864_BASIC_INSTRUCTION 0x30 //基本指令集
#define LCD_12864_EXPAND_INSTRUCTION 0x34 //擴(kuò)充指令集
#define LCD_12864_DRAW_OFF 0x34 //繪圖顯示關(guān)
#define LCD_12864_DRAW_ON 0x36 //繪圖顯示開
//地址設(shè)定
#define LCD_12864_EXPAND_IRAM 0x40 //SR=1:AC5—AC0 為垂直卷動地址SR=0:AC3—AC0 為ICON IRAM 地址
#define LCD_12864_EXPAND_CGRAM 0x80 //設(shè)定CGRAM 地址到地址計數(shù)器(AC)
//LCD函數(shù)聲明*************************************************************************
void LCD_Delay_us(unsigned int us); //LCD延時微秒級
unsigned char LCD_BUSY_Bit(void); //解決忙問題
void LCD_Write_Instruction(unsigned char byteData); //寫指令
void LCD_Write_DATA(unsigned char byteData); //寫數(shù)據(jù)
unsigned char LCD_Read_Data(); //從內(nèi)部RAM讀取數(shù)據(jù)
void LCD_12864_Initialization(void); //12864初始化
void LCD_12864_bitInitialization(void); //圖形初始化
void LCD12864_WH_String(unsigned char x,unsigned char y,unsigned char *s);
void LCD_Read_dat_I(unsigned char *xp,unsigned char *yp);
void cls_lcd();
void xx_lcd(unsigned char xp,unsigned char yp);
//寫入字符串到第x(1,2,3,4)行y(1,16)列 //中間可以有漢字,并自動插入空格
//void LCD_12864_DRAW_CGRAM(UCHAR x,UCHAR *ZOON_CHAR) ;/*CGRAM.x (0-15)的分區(qū)數(shù)據(jù)寫入 */
/***************************************************************************************
** 函數(shù)名稱: LCD_Delay_us(unsigned int us)
** 功能描述: 微秒延時
****************************************************************************************/
void LCD_Delay_us(unsigned int us)
{
while(us--);
}
/***************************************************************************************
** 函數(shù)名稱: void LCD_12864_bitInitialization(void)
** 功能描述: 初始化函數(shù)
** 調(diào)用模塊: LCD_Write_Instruction();
****************************************************************************************/
void LCD_12864_bitInitialization(void)
{
LCD_Write_Instruction(0x34);
LCD_Write_Instruction(0x03);
LCD_Write_Instruction(0x01);//清屏
LCD_Write_Instruction(0x36);
//LCD_Write_Instruction(0x3f);
//LCD_Write_Instruction(LCD_12864_AC_AUTO_INCREMENT); //數(shù)據(jù)讀、寫操作后,AC自動增一,畫面不動
//LCD_Write_Instruction(LCD_12864_DISPLAY_ON|LCD_12864_CURSOR_OFF); //顯示開光標(biāo)不顯示光標(biāo)不閃爍
LCD_Write_Instruction(LCD_12864_CLR);//清屏
}
/***************************************************************************************
** 函數(shù)名稱: void LCD_12864_Initialization(void)
** 功能描述: 初始化函數(shù)
** 調(diào)用模塊: LCD_Write_Instruction();
****************************************************************************************/
void LCD_12864_Initialization(void)
{
LCD_Write_Instruction(LCD_12864_BASIC_INSTRUCTION); //使用基本指令集
LCD_Write_Instruction(LCD_12864_AC_AUTO_INCREMENT); //數(shù)據(jù)讀、寫操作后,AC自動增一,畫面不動
LCD_Write_Instruction(LCD_12864_DISPLAY_ON|LCD_12864_CURSOR_OFF); //顯示開光標(biāo)不顯示光標(biāo)不閃爍
LCD_Write_Instruction(LCD_12864_ORDER);//清屏
}
/***************************************************************************************
** 函數(shù)名稱: unsigned char LCD_BUSY_Bit(void)
** 功能描述: 解決忙問題,等待DB07為空
** 說 明:返回當(dāng)前AC地址
****************************************************************************************/
unsigned char LCD_BUSY_Bit(void)
{
bit byteData;
do
{ //循環(huán)開始
LCD_EN = 0; //使能關(guān)
LCD_RS = 0; //1數(shù)據(jù)0指令
LCD_RW = 1; //1讀0寫
LCD_DATA = 0xff; //拉高數(shù)據(jù)口電位
LCD_EN = 1; //使能開
byteData = LCD_BUSY; //取狀態(tài)字DB07的結(jié)果
}while(byteData); //循環(huán)終點(diǎn) 讀到 忙位為0退出,否則繼續(xù)讀忙。
return((LCD_DATA&0x7F)+0x80); //返回AC的值
LCD_EN = 0; //使能關(guān)
}
/***************************************************************************************
** 函數(shù)名稱: void LCD_Write_Instruction(unsigned char byteData)
** 功能描述: 寫指令
** 輸 入: unsigned char byteData 寫指令
** 調(diào)用模塊: LCD_BUSY_Bit();
****************************************************************************************/
void LCD_Write_Instruction(unsigned char byteData)
{
LCD_BUSY_Bit(); //讀忙
LCD_EN = 0; //使能關(guān)
LCD_RS = 0; //指令方式
LCD_RW = 0; //寫LCD
LCD_DATA = byteData; //指令寫入數(shù)據(jù)口
LCD_EN = 1; //使能開
LCD_Delay_us(4); //微秒延時
LCD_EN = 0; //使能關(guān)
}
/***************************************************************************************
** 函數(shù)名稱: void LCD_Write_DATA(unsigned char byteData)
** 功能描述: 寫數(shù)據(jù)
** 輸 入: unsigned char byteData 寫數(shù)據(jù)
** 調(diào)用模塊: LCD_BUSY_Bit(); LCD_Delay_us();
****************************************************************************************/
void LCD_Write_DATA(unsigned char byteData)
{
LCD_BUSY_Bit(); //讀忙
LCD_EN = 0; //使能關(guān)
LCD_RS = 1; //數(shù)據(jù)方式
LCD_RW = 0; //寫LCD
LCD_DATA = byteData; //數(shù)據(jù)寫入數(shù)據(jù)口
LCD_EN = 1; //使能開
LCD_Delay_us(4); //微秒延時
LCD_EN = 0; //使能關(guān)
}
/***************************************************************************************
** 函數(shù)名稱: unsigned char LCD_Read_Data()
** 功能描述: 讀取并返回AC指向的數(shù)據(jù)
** 說 明: 函數(shù)外設(shè)定AC地址,第一次試讀讀出高位,第二次會再次讀出高位,第三次讀出低位,
** 然后AC自動加一,在接下來的讀取中,只要不再次指定AC,可按AC順序讀取
****************************************************************************************/
unsigned char LCD_Read_Data()
{
LCD_BUSY_Bit();
LCD_EN = 0; //使能關(guān)
LCD_RS = 1; //數(shù)據(jù)方式
LCD_RW = 1; //讀LCD
LCD_DATA = 0xFF; //數(shù)據(jù)寫入數(shù)據(jù)口
LCD_EN = 1; //使能開
LCD_Delay_us(4); //微秒延時
return(LCD_DATA); //返回AC地址數(shù)據(jù)
}
/***************************************************************************************
** 函數(shù)名稱: void LCD12864_WH_String(unsigned char x,unsigned char y,unsigned char *s)
** 功能描述: 寫入字符串到第x(1,2,3,4)行y(1,16)列
** 輸 入: unsigned char x,unsigned char y,unsigned char *s
** 輸 出: 無
** 全局變量: 無
** 調(diào)用模塊: LCD_BUSY_Bit();LCD_Read_DATA();LCD_Write_Instruction();LCD_Write_DATA();
**設(shè)定起始行列數(shù)和字符數(shù)組,將在12864中順序顯示,在遇到漢字時如果是在地址低位,將在地址低位插入
**一個空格
****************************************************************************************/
void LCD12864_WH_String(unsigned char x,unsigned char y,unsigned char *s)
{
unsigned char Tempi=0; //循環(huán)行計次變量
unsigned char TempAC=0; //返回的DDRAM地址變量
unsigned char TempData=0; //返回的DDRAM高字節(jié)數(shù)據(jù)
bit test0=1; //判斷是否在第一行
bit test1=0; //標(biāo)準(zhǔn)ASCII碼數(shù)量的奇偶標(biāo)記
--y; //輸入y下標(biāo)為1,統(tǒng)一運(yùn)算y最低為0
for(Tempi=x;Tempi<5;Tempi++)
{ //行掃描循環(huán)
switch(Tempi)
{ //強(qiáng)制指定正確的行地址起點(diǎn)
case 1:x=0x80;break; //第一行光標(biāo)位置
case 2:x=0x90;break; //第二行光標(biāo)位置
case 3:x=0x88;break; //第三行光標(biāo)位置
case 4:x=0x98;break; //第四行光標(biāo)位置
default: break;
}
if(test0)
{ //如果這是第一行
LCD_Write_Instruction(x+(y>>1)); //寫入坐標(biāo)位置
if(y%2)
{ //如果y起點(diǎn)在AC地址低位
TempAC=LCD_BUSY_Bit(); //取當(dāng)前AC地址
LCD_Write_Instruction(TempAC); //重置當(dāng)前AC地址
LCD_Read_Data(); //讀AC地址高位數(shù)據(jù)
TempData= LCD_Read_Data(); //讀AC地址高位數(shù)據(jù)
LCD_Write_Instruction(TempAC); //再次重置當(dāng)前AC地址
LCD_Write_DATA(TempData); //重寫地址高位數(shù)據(jù)(只有重寫地址原來高位數(shù)據(jù),才能在此地址順利寫入低位數(shù)據(jù))
if(*s>127)
{ //如果首字是漢字且起點(diǎn)占據(jù)了奇數(shù)位
test1=1; //告訴下面的程序在首字插入一個空格
}
else
{ //如果首字是標(biāo)準(zhǔn)ASCII碼(這行可以不寫)
test1=0;
}
}
test0=0; //首行定位完成,告訴下輪循環(huán)從新的地址開始,4輪循環(huán)下3次循環(huán)都不需要再計算首行起點(diǎn)
}
else
{ //這是4輪循環(huán)中的后3輪循環(huán)
y=0; //列地址始終從0開始
LCD_Write_Instruction(x); //寫入新行首列AC地址
}
for(y;y<16;y++)
{ //列循環(huán)掃描
if(*s)
{ //如果字符數(shù)組沒有到最后一位空數(shù)據(jù)
if(*s<128)
{ //如果當(dāng)前字符數(shù)組數(shù)據(jù)是標(biāo)準(zhǔn)ASCII碼
test1=~test1; //奇偶翻轉(zhuǎn)
LCD_Write_DATA(*s++); //向LCD寫入當(dāng)前字符后,指針自加1
}
else
{ //如果當(dāng)前字符數(shù)組數(shù)據(jù)是擴(kuò)展ASCII碼
if(test1)
{ //如果已經(jīng)寫入了奇數(shù)個標(biāo)準(zhǔn)ASCII碼
LCD_Write_DATA(' '); //插入一個空格,湊齊偶數(shù)個標(biāo)準(zhǔn)ASCII碼
test1=0; //清空奇偶判斷位成偶數(shù)標(biāo)記
}
else
{ //如果先前已經(jīng)湊齊偶數(shù)個標(biāo)準(zhǔn)ASCII碼
LCD_Write_DATA(*s++); //寫入擴(kuò)展ASCII碼
}
}
}
}
}
}
/***************************************************************************************
** 函數(shù)名稱: void LCD_12864_DRAW_CGRAM(UCHAR x,UCHAR *ZOON_CHAR)
** 功能描述: CGRAM.x (0-15)的分區(qū)數(shù)據(jù)寫入
** 輸 入: UCHAR x,UCHAR *ZOON_CHAR
** 輸 出: 無
** 全局變量: 無
** 調(diào)用模塊: 無
****************************************************************************************/
/*
void LCD_12864_DRAW_CGRAM(UCHAR x,UCHAR *ZOON_CHAR)
{
UCHAR i;
LCD_Write_Instruction(LCD_12864_EXPAND_INSTRUCTION | LCD_12864_DRAW_OFF| LCD_12864_BASIC_INSTRUCTION); //擴(kuò)充指令集開
LCD_Write_Instruction(LCD_12864_DRAW_OFF); //圖形顯示關(guān)
LCD_Write_Instruction(x+0x80); //輸入X的坐標(biāo)
LCD_Write_Instruction(0x80); //輸入Y的坐標(biāo)
for(i=0;i<32;i++) //寫了一塊分區(qū)
{
LCD_Write_DATA(ZOON_CHAR[i*2+1]); //數(shù)據(jù)的格式為將D15——D8 ,D7——D0 寫入到RAM 中
LCD_Write_DATA(ZOON_CHAR[i*2 ]);
} 4
LCD_Write_Instruction(LCD_12864_DRAW_ON); //圖形顯示開
LCD_Write_Instruction(LCD_12864_BASIC_INSTRUCTION | LCD_12864_DRAW_ON); //設(shè)置為基本指令集
}
*/
void cls_lcd()
{
unsigned char i,j,k;
LCD_Write_Instruction(0x34);
LCD_Write_Instruction(0x36);
for(i=0;i<2;i++)
{
for(j=0;j<32;j++)
{
LCD_Write_Instruction(0x80+j);
if(i==0)
{
LCD_Write_Instruction(0x80);
}
else
{
LCD_Write_Instruction(0x88);
}
for(k=0;k<16;k++)
{
LCD_Write_DATA(0x00);
}
}
}
}
void xx_lcd(unsigned char xp,unsigned char yp)
{
unsigned char xd,rx,ry;
xd=xp/0x10; //計算橫坐標(biāo)
xp%=0x10; //計算位地址偏移
if(yp>31)
{//選下半屏
yp-=32;
yp+=128;
xd+=8;
xd+=128;
}
else
{//選上半屏
yp+=128;
xd+=128;
}
rx=xd;ry=yp;
LCD_Write_Instruction(ry);
LCD_Write_Instruction(rx);
LCD_Read_dat_I(&rx,&ry);
LCD_Write_Instruction(yp);
LCD_Write_Instruction(xd);
if(xp>8)
{
LCD_Write_DATA(rx);
LCD_Write_DATA(ry|(0x01<<(15-xp)));
}
else
{
LCD_Write_DATA(rx|(0x01<<(7-xp)));
LCD_Write_DATA(ry);
}
}
void LCD_Read_dat_I(unsigned char *xp,unsigned char *yp)
{
LCD_Write_Instruction(*yp); //豎坐標(biāo)(0x80-0x9f)
LCD_Write_Instruction(*xp); //橫坐標(biāo) 上半屏(0x80-0x87) 下半屏(0x88-0x90)
LCD_Read_Data();
*xp=LCD_Read_Data();
*yp=LCD_Read_Data();
}
|
|