//================================================ //功能:LCD_12864 驱动程序 //作者:L.sen
//芯片:PIC16F877A ST7920 //晶振:4 MHz //时间:2011.07.30 //介绍:
//================================================ //防止被重复定义
#ifndef __LCD_12864_H__ #define __LCD_12864_H__ //所需头文件
#define uchar unsigned char #define uint unsigned int
#define _XTAL_FREQ 4000000 //PIC.H
//============================================= //接口定义
//============================================= //#define CS RC5 //#define CS3 0x08 #define SID RB4 #define CLK RB5
//============================================= //LCD延时函数
//============================================= /*void Delay_LCD(void) { uchar k; for(k=50;k>0;k--); }*/
//============================================= //12864串口模式,发送单字节函数
//============================================= void Send_byte(uchar d_byte) { uchar j; TRISB4=0; //设为输出口 for(j=8;j>0;j--) { CLK=0; d_byte=d_byte<<1;
SID=CARRY; CLK=1; } }
//============================================= //读一个字节
//============================================= uchar Receive_Byte(void) { uchar i,temp=0; TRISB4=1; //设为输入口 //CS=1; //片选拉高有效 for(i=4;i>0;i--) { CLK=0; __delay_us(1); CARRY=SID; temp<<1; CLK=1; //上升沿读走数据 } for(i=4;i>0;i--) { CLK=0; __delay_us(1); CLK=1; } for(i=4;i>0;i--) { CLK=0; __delay_us(1); CARRY=SID; temp<<1; CLK=1; //上升沿读走数据 } for(i=4;i>0;i--) { CLK=0; __delay_us(1); CLK=1; } //CS=0; return(temp); }
//============================================= //LCD忙检测
//============================================= void Check_Busy(void) { do(Send_byte(0xFC)); //11111,RW(1)读操作,RS(0),0 while(0x80&Receive_Byte()); //为0为不忙 }
//============================================= //LCD忙检测写指令
//============================================= void Write_Cmd(uchar cmd) { //CS=1; Check_Busy(); //忙检测 Send_byte(0XF8); //11111,RW(0),RS(0),0 Send_byte(0XF0&cmd); //发送高四位 Send_byte((0x0f&cmd)<<4); //发送低四位 //CS=0; }
//============================================= //LCD写数据
//============================================= void Write_Date(uchar date) { //CS=1; Check_Busy(); //忙检测 Send_byte(0XFA); //11111,RW(0),RS(1),0 Send_byte(0XF0&date); //发送高四位 Send_byte((0x0f&date)<<4); //发送低四位 //CS=0; }
//============================================= //设置LCD显示模式
//============================================= #define LCD_SHOW 0x04 //显示开 #define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标 #define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动 #define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(uchar DisplayMode) { Write_Cmd(0x08|DisplayMode); }
//============================================= //写字符串到LCD指定位置
//============================================= void GotoXY(uchar y, uchar x,uchar const *s) {
Check_Busy(); //忙检测 if(y==1)
Write_Cmd(0x80|x); if(y==2)
Write_Cmd(0x90|x); if(y==3)
Write_Cmd(0x88|x); if(y==4)
Write_Cmd(0x98|x); while(*s) { Write_Date(*s); s++; }
Write_Cmd(0x02); //把 DDRAM 位址计数器调整为“00H” ,游标回原点,该功能不影响显示 DDRAM }
//============================================= //LCD绘图
//============================================= void Draw_Photo(uchar bmp[][16]) { uchar i,j,k;
Check_Busy(); //忙检测 Write_Cmd(0x34); //打开高级指令集,关闭绘图显示功能 for(i=0;i<32;i++) //显示图形上半部分 { Write_Cmd(0x80+i); //输入Y坐标 Write_Cmd(0x80); //输入X坐标 for(j=0;j<16;j++) Write_Date(bmp[i][j]); //输入图形上半数据 __delay_us(10); }
for(i=0,k=32;i<32,k<64;i++,k++) //显示下半部分图片 { Write_Cmd(0x80+i); //输入Y轴坐标 Write_Cmd(0x88); //输入X轴坐标 for(j=0;j<16;j++) Write_Date(bmp[k][j]); //输入图形下半数据 __delay_us(10); }
Write_Cmd(0x36); //打开绘图功能,显示所绘图片 }
//============================================= //LCD初始化
//============================================= void Init_LCD(void) { Write_Cmd(0x20); //打开基本指令集 Write_Cmd(0x02); //地址归位 Write_Cmd(0x0c); //开显示,开游标,游标反白(0,0,0,0,1,D,C,B) Write_Cmd(0x06); //指定在数据的读取及写入时,设定游标的移动方向及指定显示的移位 //每写进一个数据AC加1
Write_Cmd(0x01); //清除显示,并把AC设为00H }
//============================================= //清除GDRAN内容
//=============================================
void Clear_GDRAM(void) // 清屏 ,清除GDRAM中的数据 ,及向GDRAM中全写0 { uchar i,j,k; Write_Cmd(0x34); //打开扩展指令集,关闭绘图显示 i = 0x80; for(j=0;j<32;j++) //清上半屏 {
Write_Cmd(i++); Write_Cmd(0x80); for(k=0;k<16;k++) { Write_Date(0x00); } } i = 0x80;
for(j=0;j<32;j++) //清下半屏 {
Write_Cmd(i++);
Write_Cmd(0x88); for(k=0;k<16;k++) { Write_Date(0x00); } } Write_Cmd(0x20); //回到基本指令集 }
//================================================= #endif