📄 lcd.h
字号:
/**************************************************************************************
CSA----选择IC1,低有效 即 (左)64列
CSB----选择IC2,低有效 即 (右)64列
---------------------------------------------------------------------------------------
RS: D/I=H,表示DB7~DB0为显示数据
D/I=L,表示DB7~DB0为指令数据
---------------------------------------------------------------------------------------
R/W: R/W=H,E=H数据被读到DB7~DB0
R/W=L,E信号下降沿,DDRAM数据被写到IR或DR
---------------------------------------------------------------------------------------
E: R/W=L,E信号下降沿锁存DB7~DB0
R/W=H,E=H DDRAM数据读到DB7~DB0
---------------------------------------------------------------------------------------
|DB0-----D7.0 | DB4-----D7.4 | CSA-------P3.2 |
|DB1-----D7.1 | DB5-----D7.5 | CSB-------P3.3 |
|DB2-----D7.2 | DB6-----D7.6 | RS-------P3.4 |
|DB3-----D7.3 | DB7-----D7.7 | RW-------P3.5 |
|17脚---A正电源 18脚----K地 | E-------P3.6 | |
|VO-------0V | |
****************************************************************************************/
#define CSA PTE_PTE3//片选信号 低有效
#define CSB PTE_PTE4//片选信号 低有效
#define RS PTE_PTE0//数据 指令选择信号 1-数据操作 0-写指令或读状态
#define RW PTE_PTE1//读写选择信号 1-读选通 0-写选通
#define E PTE_PTE2//读写使能信号
#define RST PTE_PTE5//复位信号 无须考虑
#define LC_RSS_OP 0x3F//显示开指令
#define LC_RSS_CLS 0x3E//显示关指令
#define RSS_ROW_SET 0xC0//显示起始行设置指令
#define X_ADDR_SET 0xB8//页设置指令 X
#define Y_ADDR_SET 0x40//列地址设置指令 Y
#define LCD_DATA PTG
#define D0 PTG_PTG0
#define D1 PTG_PTG1
#define D2 PTG_PTG2
#define D3 PTG_PTG3
#define D4 PTG_PTG4
#define D5 PTG_PTG5
#define D6 PTG_PTG6
#define D7 PTG_PTG7
#define LCD_DDR DDRG
#define DDR0 DDRG_DDRG0
#define DDR1 DDRG_DDRG1
#define DDR2 DDRG_DDRG2
#define DDR3 DDRG_DDRG3
#define DDR4 DDRG_DDRG4
#define DDR5 DDRG_DDRG5
#define DDR6 DDRG_DDRG6
#define DDR7 DDRG_DDRG7
//sys_data_type status0,status1,status2,status3,status4,status5,status6,status7,status8;
unsigned int lcd_sec;
unsigned char lcd_min,min,lcd_hour,hour;
//unsigned char lcd_sec,lcd_min=0,lcd_hour=0; //分、小时
unsigned char minh=0,minl=0,hourh=0,hourl=0;//分钟、小时得高位、低位
//分钟、小时得高位、低位 用于判断时间是否变化
//unsigned char sech0=0,secl0=0,minh0=0,minl0=0,hourh0=0,hourl0=0; //后来自己添加
//unsigned char flash=1; //后来添加
unsigned int clock_count0=0/*,clock_count1=0*/; //系统时钟定时器
unsigned int clock_change=0;
sys_data_type light_fault_flags;
#define light_fault1 light_fault_flags.Bit.BIT0
#define light_fault2 light_fault_flags.Bit.BIT1
#define light_fault3 light_fault_flags.Bit.BIT2
#define light_fault4 light_fault_flags.Bit.BIT3
#define flash light_fault_flags.Bit.BIT7
#define lcd_dl_timer 8
//#define lcd_dl_timer0 80
/*--------------------------------------------------------------------------------------
| R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
| 1 0 BUSY 0 ON/OFF REST 0 0 0 0
| 该指令用于查询液晶显示模块内部控制器的状态
| BUSY 1-内部在工作 0-正常状态 ON/OFF 1-显示关闭 0-显示打开
| REST 1-复位状态 0-正常状态 在BUSY和REST状态时 除读状态指令外其它指令均不对
| 液晶显示模块产生作用
| 在对液晶显示模块操作之前要查询BUSY状态 以确定是否可以对液晶显示模块进行操作
|----------------------------------------------------------------------------------------
| R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
| 0 1 写 数 据
| 写数据指令
|----------------------------------------------------------------------------------------
| R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
| 1 1 读 显 示 数 据
| 读数据指令
读写数据指令每执行完一次读写操作列地址就自动增一 必须注意的是进行
读操作之前 必须有一次空读操作 紧接着再读 才会读出所要读的单元中的数据
--------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------*/
/*--基本函数源程序------------------------------------------------------------------------------------*/
//延时
void Lcd12864delay()
{
unsigned int i=500;
while(i--) {;}
}
/*----------------------------------------------------------------------------------------------------*/
//状态检查
void CheckState()
{
unsigned char dat;
RS=0; RW=1;//读状态
do
{
LCD_DDR=0x00;//数据方向为读
LCD_DATA=0xff;
E=1; dat=LCD_DATA; E=0;
dat=0x90 & dat; //仅当第4,7位为0时才可操作
}while(!(dat==0x00));
}
/*----------------------------------------------------------------------------------------------------*/
//写显示数据
//dat:显示数据
void WriteByte(unsigned char dat)
{
CheckState();
RS=1; RW=0;//写数据
LCD_DATA=dat;
E=1; E=0;//数据锁存
}
/*-----------------------------------------------------------------------------------------------------*/
//向LCD发送命令
//command :命令
void SendCommandToLCD(unsigned char command)
{
CheckState();
//RS=1;
RW=0;
LCD_DATA=command;
E=1; E=0;
}
/*----------------------------------------------------------------------------------------------------*/
//设定行地址(页)--X 0-7
void SetLine(unsigned char line)
{
line=line&0x07; // 0<=line<=7
line=line|0xb8; //1011 1xxx
SendCommandToLCD(line);
}
//设定列地址--Y 0-63
void SetColumn(unsigned char column)
{
column=column&0x3f; // 0=<column<=63
column=column|0x40; //01xx xxxx
SendCommandToLCD(column);
}
//设定显示开始行--XX
void SetStartLine(unsigned char startline) //0--63
{
startline=startline&0x07;
startline=startline|0xc0; //1100 0000
SendCommandToLCD(startline);
}
//开关显示
void SetOnOff(unsigned char onoff)
{
onoff=0x3e|onoff; //0011 111x
SendCommandToLCD(onoff);
}
/*---------------------------------------------------------------------------------------------------*/
//选择屏幕
//screE: 0-全屏,1-左屏,2-右屏
void SelectScreE(unsigned char screE)
{ //北京显示器:负有效 CSA: 0--右; CSB: 0--左
switch(screE)
{
case 0: CSA=1;//全屏
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
CSB=1;
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
break;
case 1: CSA=1;//左屏
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
CSB=0;
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
break;
case 2: CSA=0;//右屏
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
CSB=1;
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
break;
}
}
/*---------------------------------------------------------------------------------------------------*/
//清屏
//screE: 0-全屏,1-左屏,2-右
void ClearScreE(unsigned char screE)
{
unsigned char i,j;
SelectScreE(screE);
for(i=0;i<8;i++)
{
SetLine(i);
for(j=0;j<64;j++)
{
WriteByte(0x00);
}
}
}
/*--------------------------------------------------------------------------------------------------*/
//显示8*8点阵
//旋转90度:字模被竖着切分
//lin:行(0-7), column: 列(0-15)
//address : 字模区首地址
void Show88(unsigned char lin,unsigned char column,unsigned int address)
{
unsigned char i;
if(column>16) return;
if(column<8) SelectScreE(1); //如果列数<8(0,1,2,3,4,5,6,7)则写在第一屏上
else
{
SelectScreE(2); //否则 (8,9,10,11,12,13,14,15)写在第二屏上
column=column & 0x07; //防止越界
}
SetLine(lin);
SetColumn(column<<3);
for(i=0;i<8;i++) WriteByte(CBYTE[address+i]);
}
/*------------------------------------------------------------------------------------------------*/
//显示8*16字符
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//character:字符代码(标准ASCII码)
void ShowChar(unsigned char lin,unsigned char column,unsigned char character)
{
lin=lin<<1;
Show88(lin ,column,ASCII816[character-0x20] );
Show88(lin+1,column,ASCII816[character-0x20]+8 );
}
/*-----------------------------------------------------------------------------------------------*/
/*
//显示8*16字符串
//!!!只能显示在一行上即: 串长+column <=15
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-15)
//address : 字模区首地址
void ShowString(unsigned char lin,unsigned char column, unsigned char *string)
{
unsigned char ch;
unsigned char i=0;
while(*string!='\0')
{
ch=*string;
if(i+column >15) break; //(只能显示在一行上即: 串长+column <=15)
ShowChar(lin,i+column,ch);
string++; i++;
}
}
*/
/*----------------------------------------------------------------------------------------------*/
//显示一个汉字
//旋转90度:字模被竖着切分
//lin:行(0-3), column: 列(0-7)
//hzcode: 汉字代码(自定义的)
//uchar code HZtable
void ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode)
{
lin=lin<<1; //lin*2
Show88(lin,column,HZTable[hzcode]);
Show88(lin,column+1,HZTable[hzcode]+8);
Show88(lin+1,column,HZTable[hzcode]+16);
Show88(lin+1,column+1,HZTable[hzcode]+24);
}
/*----------------------------------------------------------------------------------------------*/
//显示图片
//旋转90度 :字模被竖着切分
//startline :开始行
//startcolumn:开始列
//linechar :图片行点除8(图片以8*8点阵为单位)
//columnchar :图片列点除8(图片以8*8点阵为单位)
//address : 字模区首地址
void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnchar,unsigned int address)
{
unsigned char i,j;
for(i=0;i<columnchar;i++)
for(j=0;j<linechar;j++)
Show88(startline+i , startcolumn+j , address+(i*linechar+j)*8 );
}
/*----------------------------------------------------------------------------------------------*/
//显示一行字符串(汉字,字母混排,一行16字节)
//lin:行
//lineheadaddr: 此行汉字代码区首地址
void ShowLine(unsigned char lin,unsigned char linehead[])
{
unsigned char i;
unsigned char byte;
unsigned int hzcode;
for( i=0; i<16; )
{
byte=linehead[i];
if(byte < 0x80) //字母
{
if(i>15) return; //!!编译器有问题,须强制退出
ShowChar(lin, i , byte);
i=i+1;
}
else // byte >= 0x80(汉字)
{
if(i>15) return; //!!编译器有问题,须强制退出
byte=byte & 0x7f; //最高位置0,即:减去0x8000
hzcode=(unsigned int)byte<<8; //?? //高8位
hzcode=hzcode+linehead[i+1]; //加低8位,组合成整型数地址
ShowHZ( lin,i,hzcode);
i=i+2;
}
}
}
/*----------------------------------------------------------------------------------------------------*/
//显示一屏汉字
//pageheadaddr:此屏汉字代码地址区首地址
void ShowPage(unsigned char pagehead[][16])
{
unsigned char i;
for(i=0;i<4;i++) ShowLine(i,pagehead[i]); //1行8个汉字,16字节
}
/*----------------------------------------------------------------------------------------------------*/
//读显示数据
unsigned char ReadByte()
{
unsigned char dat;
CheckState();
RS=1; RW=1;
LCD_DATA=0xff;
E=1; dat=LCD_DATA; E=0;
return(dat);
}
/*----------------------------------------------------------------------------------------------------*/
//反显一个8*8字块
//lin:行(0-3), column: 列(0-7)
void ReverseShow88(unsigned char lin,unsigned char column)
{
unsigned char i;
unsigned char tab[8];
if(column<8) SelectScreE(1); //如果列数<4(0,1,2,3),则写在第一屏上
else SelectScreE(2); //否则 (4,5,6,7), 写在第二屏上
//读上部8列
column=column<<3; //每个方块8*8大小
SetLine(lin);
SetColumn(column);
tab[0]=ReadByte(); //空读!!!!! //?
for(i=0;i<8;i++) tab[i]=~ReadByte();
//写回
SetLine(lin);
SetColumn(column);
for(i=0;i<8;i++) WriteByte(tab[i]);
}
/*----------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------*/
//反显一个字符
//lin:行(0-4), column: 列(0-15)
void ReverseShowChar(unsigned char lin,unsigned char column)
{
lin=lin<<1;
ReverseShow88(lin ,column);
ReverseShow88(lin+1,column);
}
/*----------------------------------------------------------------------------------------------------*/
//反显一个汉字
//lin:行(0-3), column: 列(0-7)
ReverseShowHZ(unsigned char lin,unsigned char column)
{
lin=lin<<1;
column=column<<1;
ReverseShow88(lin ,column );
ReverseShow88(lin ,column+1);
ReverseShow88(lin+1,column );
ReverseShow88(lin+1,column+1);
}
/*----------------------------------------------------------------------------------------------------*/
//反显一行汉字
//lin:行
ReverseShow(unsigned char lin)
{
unsigned char i;
for(i=0;i<8;i++) ReverseShowHZ(lin,i);
}
/*----------------------------------------------------------------------------------------------------*/
void InitLCD() //初始化LCD
{
unsigned char i=250; //延时
while(i--);
//reset=0;//复位
//reset=1;
SelectScreE(0);
SetOnOff(0); //关显示
ClearScreE(1);//清屏
ClearScreE(2);
SelectScreE(0);
SetOnOff(1); //开显示
SelectScreE(0);
SetStartLine(0); //开始行:0
}
/*----------------------------------------------------------------------------------------------------*/
void Reset() //液晶复位
{
//reset 低复位 _|-
reset=0;
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
reset=1;
//全屏
CSA=0;
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
CSB=0;
asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop);
SendCommandToLCD(0x3F);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -