|
/********************************************************************************************* * 文 件 名:LCM12864Drive.c * 功 能:LCM12864图形液晶模块驱动。使用LPC213X/214X的GPIO口模拟总线控制操作。 * * 液晶模块与LPC213X/214X的连接如下所示: * * LCM12864 LPC213X/214X 备 注 * * RS P0.18 0:传送命令; 1:传送数据 * RW P0.19 0:进行写操作 1:进行读操作 * E P0.20 读写脉冲 * D0 P1.16 数据线0 * D1 P1.17 数据线1 * D2 P1.18 数据线2 * D3 P1.19 数据线3 * D4 P1.20 数据线4 * D5 P1.21 数据线5 * D6 P1.22 数据线6 * D7 P1.23 数据线7 * CSA P1.24 左半屏选择,高电平选中 * CSB P1.25 右半屏选择,高电平选中 * RST P0.17 复位控制,低电平复位 * BLK P0.11 背光控制,高电平点亮 ******************************************************************************************************************/ #include "config.h"
TCOLOR gui_disp_buf[GUI_LCM_YMAX/8][GUI_LCM_XMAX];// 定义显示缓冲区 // 注意:由于LCM12864液晶模块的显示单元是按垂直方向排列的,即1字节 // 数据表示某一列的8个点,所以定义显示缓冲区时就使用了"列宽/8" // 作为第1维数组的大小。
/****************************************************************************************************************** * 函数名称:LCM12864_Delay() * 功 能:软件延时函数。用于LCM12864显示输出时序控制。 * 入口参数:无 * 出口参数:无 *******************************************************************************************************************/ void LCM12864_Delay(void) { uint8 i;
for(i=0; i<100; i++); }
/****************************************************************************************************************** * 函数名称:OutData() * 功 能:输出总线数据/命令。 * 入口参数:dat 8位数据/命令 * 出口参数:无 *******************************************************************************************************************/ void OutData (uint8 dat) { if((dat & 0x01)==1) H_LCM12864_D0(); else L_LCM12864_D0(); if((dat & 0x02)==2) H_LCM12864_D1(); else L_LCM12864_D1(); if((dat & 0x04)==4) H_LCM12864_D2(); else L_LCM12864_D2(); if((dat & 0x08)==8) H_LCM12864_D3(); else L_LCM12864_D3(); if((dat & 0x10)==16) H_LCM12864_D4(); else L_LCM12864_D4(); if((dat & 0x20)==32) H_LCM12864_D5(); else L_LCM12864_D5(); if((dat & 0x40)==64) H_LCM12864_D6(); else L_LCM12864_D6(); if((dat & 0x80)==128) H_LCM12864_D7(); else L_LCM12864_D7(); }
/****************************************************************************************************************** * 函数名称:LCM12864_WriteCMD() * 功 能:向LCM12864写命令。 * 入口参数:command 要写入LCM12864的命令字 * 出口参数:无 *******************************************************************************************************************/ void LCM12864_WriteCMD(uint8 command) { L_LCM12864_E(); // 将E置低 L_LCM12864_RS(); // RS=0,表示发送命令 OutData(command); LCM12864_Delay(); H_LCM12864_E(); LCM12864_Delay(); L_LCM12864_E(); LCM12864_Delay(); }
/****************************************************************************************************************** * 函数名称:LCM12864_WritEDAta() * 功 能:向LCM12864写数据。 * 入口参数:data 要写入LCM12864的数据 * 出口参数:无 *******************************************************************************************************************/ void LCM12864_WritEDAta(uint8 data) { L_LCM12864_E(); // 将E置低 H_LCM12864_RS(); // RS=1,表示发送数据 OutData(data); LCM12864_Delay(); H_LCM12864_E(); LCM12864_Delay(); L_LCM12864_E(); LCM12864_Delay(); }
/****************************************************************************************************************** * 函数名称:LCM12864_WriteByte() * 功 能:向LCM12864指定点写一字节数据。 * 入口参数:x x坐标值(0-127) * y y坐标值(0-63) * data 所要写的数据 * 出口参数:无 *******************************************************************************************************************/ void LCM12864_WriteByte(uint8 x, uint8 y, uint8 data) { /* 参数过滤 */ x = x&0x7f; y = y&0x3f;
L_LCM12864_CSA(); L_LCM12864_CSB(); // 不选中左半屏及右半屏 y = y>>3; // 更新显示缓冲区 gui_disp_buf[y][x] = data; /* 更新LCD12864显示 */ if(x<64) // 判断选择左、右半屏 { H_LCM12864_CSA(); // CSA置高,控制前64个点 } else { H_LCM12864_CSB(); // CSB置高,控制后64个点 x = x-64; } LCM12864_WriteCMD(LCM12864_ADDRSTRY+x); // 设置当前列地址,即x坐标 LCM12864_WriteCMD(LCM12864_ADDRSTRX+y); // 设置当前页地址,即y坐标 LCM12864_WritEDAta(data); // 向LCM12864写数据 }
/****************************************************************************************************************** * 函数名称:LCM12864_ReadByte() * 功 能:从显示缓冲区读取指定点上的数据。 * 入口参数:x x坐标值(0-127) * y y坐标值(0-63) * 出口参数:返回该点上的字节数据。 *******************************************************************************************************************/ uint8 LCM12864_ReadByte(uint8 x, uint8 y) { /* 参数过滤 */ x = x&0x7f; y = y&0x3f;
y = y>>3; return (gui_disp_buf[y][x]); // 返回显示缓冲区指定点上的数据 }
/****************************************************************************************************************** * 函数名称:LCM12864_DispFill() * 功 能:向LCM12864填充数据。 * 入口参数:filldata 要写入LCM12864的填充数据 * 出口参数:无 * 说 明:此函数会设置显示起始行为0,且会自动选中CSA有效。 *******************************************************************************************************************/ void LCM12864_DispFill(uint8 filldata) { uint8 x,y;
H_LCM12864_CSA(); H_LCM12864_CSB(); // 选中左半屏及右半屏 LCM12864_WriteCMD(LCM12864_STARTROW); // 设置显示起始行为0
for(x=0; x<8; x++) { LCM12864_WriteCMD(LCM12864_ADDRSTRX+x); // 设置页地址,即X LCM12864_WriteCMD(LCM12864_ADDRSTRY); // 设置列地址,即Y for(y=0; y<64; y++) { LCM12864_WritEDAta(filldata); } }
L_LCM12864_CSB(); }
/****************************************************************************************************************** * 函数名称:LCM12864_DispIni() * 功 能:LCM12864显示初始化。 * 入口参数:无 * 出口参数:无 *******************************************************************************************************************/ void LCM12864_DispIni(void) { uint32 i; /* 选择LPC213X/214X的相关引脚为GPIO用来模拟总线驱动LCM12864 */ PINSEL0&=~((uint32)0x03<<22); // P0.11选择为GPIO PINSEL1&=~((uint32)0x3fc<<2); // P0.17~P0.20选择为GPIO PINSEL2&=~((uint32)0x01<<3); // P1.16~P1.25选择为GPIO /* 设置用来模拟总线用的GPIO方向为输出 */ IO0DIR|=((uint32)0x01<<LCM12864_BLK) | ((uint32)0x01<<LCM12864_RST) | ((uint32)0x01<<LCM12864_RS) | ((uint32)0x01<<LCM12864_RW) | ((uint32)0x01<<LCM12864_E); IO1DIR|=((uint32)0x01<<LCM12864_D0) | ((uint32)0x01<<LCM12864_D1) | ((uint32)0x01<<LCM12864_D2) | ((uint32)0x01<<LCM12864_D3) | ((uint32)0x01<<LCM12864_D4) | ((uint32)0x01<<LCM12864_D5) | ((uint32)0x01<<LCM12864_D6) | ((uint32)0x01<<LCM12864_D7) | ((uint32)0x01<<LCM12864_CSA) | ((uint32)0x01<<LCM12864_CSB);
H_LCM12864_BLK(); // 打开背光 L_LCM12864_RW(); // 只写数据到总线
/* 复位LCM */ L_LCM12864_RST(); for(i=0; i<5000; i++); H_LCM12864_RST(); for(i=0; i<5000; i++);
H_LCM12864_CSA(); H_LCM12864_CSB(); // 选中左半屏及右半屏
LCM12864_WriteCMD(LCM12864_DISPON); // 打开显示 LCM12864_WriteCMD(LCM12864_STARTROW); // 设置显示起始行为0 LCM12864_WriteCMD(LCM12864_ADDRSTRX); // 设置页地址,即X LCM12864_WriteCMD(LCM12864_ADDRSTRY); // 设置列地址,即Y }
/****************************************************************************************************************** * 函数名称:GUI_FillSCR() * 功 能:全屏填充。填充显示缓冲区及LCM12864。 * 入口参数:data 填充的数据 * 出口参数:无 *******************************************************************************************************************/ void GUI_FillSCR(TCOLOR data) { uint8 i,j; /* 填充显示缓冲区 */ for(i=0; i<(GUI_LCM_YMAX/8); i++) { for(j=0; j<GUI_LCM_XMAX; j++) { gui_disp_buf[i][j] = data; } } LCM12864_DispFill(data); // 填充LCM12864 }
/****************************************************************************************************************** * 函数名称:GUI_Initialize() * 功 能:初始化GUI,包括初始化显示缓冲区及LCM12864并清屏。 * 入口参数:无 * 出口参数:无 *******************************************************************************************************************/ void GUI_Initialize(void) { LCM12864_DispIni(); // 初始化LCM12864模块工作模式,纯图形模式 GUI_FillSCR(0x00); // 初始化缓冲区为0x00,并输出屏幕(清屏) }
uint8 const DEC_HEX_TAB[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; /****************************************************************************************************************** * 函数名称:GUI_Point() * 功 能:在指定位置上画点。 * 入口参数:x 指定点所在列的位置 * y 指定点所在行的位置 * color 对于黑白色或蓝白色LCM12864,为0时灭,为1时显示 * 出口参数:返回值为1时表示操作成功,为0时表示操作失败。 *******************************************************************************************************************/ uint8 GUI_Point(uint8 x, uint8 y, TCOLOR color) { uint8 bak; /* 参数过滤 */ if(x>=GUI_LCM_XMAX) return(0); if(y>=GUI_LCM_YMAX) return(0); /* 设置相应的点为1或0 */ bak = LCM12864_ReadByte(x,y); if(0==color) { bak &= (~DEC_HEX_TAB[y&0x07]); } else { bak |= DEC_HEX_TAB[y&0x07]; } LCM12864_WriteByte(x, y, bak); // 刷新显示 return(1); }
/****************************************************************************************************************** * 函数名称:GUI_ReadPoint() * 功 能:读取指定点的颜色。 * 入口参数:x 指定点所在列的位置 * y 指定点所在行的位置 * ret 保存颜色值的指针 * 出口参数:返回0表示指定地址超出缓冲区范围。 * 说 明:对于单色,设置ret的d0位为1或0 *******************************************************************************************************************/ uint8 GUI_ReadPoint(uint8 x, uint8 y, TCOLOR *ret) { uint8 bak;
/* 参数过滤 */ if(x>=GUI_LCM_XMAX) return(0); if(y>=GUI_LCM_YMAX) return(0); bak = LCM12864_ReadByte(x,y); if( (bak & (DEC_HEX_TAB[y&0x07])) == 0 ) *ret = 0x00; else *ret = 0x01; return(1); }
/****************************************************************************************************************** * 函数名称:GUI_HLine() * 功 能:画水平线。 * 入口参数:x0 水平线起点所在列的位置 * y0 水平线起点所在行的位置 * x1 水平线终点所在列的位置 * color 显示颜色(对于黑白色或蓝白色LCM12864,为0时灭,为1时显示LCM12864,为0时灭,为1时显示) * 出口参数:无 *******************************************************************************************************************/ void GUI_HLine(uint8 x0, uint8 y0, uint8 x1, TCOLOR color) { uint8 bak;
/* 对x0、x1大小进行排列,以便画图 */ if(x0>x1) { bak = x1; x1 = x0; x0 = bak; } do { GUI_Point(x0, y0, color); // 逐点显示,描出垂直线 x0++; }while(x1>=x0); }
/****************************************************************************************************************** * 函数名称:GUI_RLine() * 功 能:画竖直线。根据硬件特点,实现加速。 * 入口参数:x0 垂直线起点所在列的位置 * y0 垂直线起点所在行的位置 * y1 垂直线终点所在行的位置 * color 显示颜色(对于黑白色或蓝白色LCM12864,为0时灭,为1时显示LCM12864,为0时灭,为1时显示) * 出口参数:无 *******************************************************************************************************************/ void GUI_RLine(uint8 x0, uint8 y0, uint8 y1, TCOLOR color) { uint8 bak; uint8 data; /* 对y0、y1大小进行排列,以便画图 */ if(y0>y1) { bak = y1; y1 = y0; y0 = bak; } do { bak = LCM12864_ReadByte(x0,y0); // 先读取当前点的字节数据 /* 进行'与'/'或'操作后,将正确的数据写回LCM 若y0和y1不是同一字节,则y0--当前字节结束,即(y0+8)&0x38,全写1,或者0。 若y0和y1是同一字节,则y0--y1,要全写1,或者0。 方法:dat=0xff,然后按y0清零dat低位,按y1清零高位。*/
if((y0>>3) != (y1>>3)) // 竖直线是否跨越两个字节(或以上) { data = 0xFF << (y0&0x07); // 清0低位 if(color) { data = bak | data; // 若color不为0,则显示 } else { data = ~data; // 若color为0,则清除显示 data = bak & data; } LCM12864_WriteByte(x0,y0, data); y0 = (y0+8)&0x38; } else { data = 0xFF << (y0&0x07); data = data & ( 0xFF >> (7-(y1&0x07)) ); if(color) { data = bak | data; // 若color不为0,则显示 } else { data = ~data; // 若color为0,则清除显示 data = bak & data; } LCM12864_WriteByte(x0,y0, data); return; } }while(y1>=y0); }
/****************************************************************************************************************** * 文 件 名:LCM12864Drive.h * 功 能:LCM12864图形液晶模块驱动头文件。使用LPC213X/214X的GPIO口模拟总线控制操作。 * * 液晶模块与LPC213X/214X的连接如下所示: * * LCM12864 LPC213X/214X 备 注 * * RS P0.18 0:传送命令; 1:传送数据 * RW P0.19 0:进行写操作 1:进行读操作 * E P0.20 读写脉冲 * D0 P1.16 数据线0 * D1 P1.17 数据线1 * D2 P1.18 数据线2 * D3 P1.19 数据线3 * D4 P1.20 数据线4 * D5 P1.21 数据线5 * D6 P1.22 数据线6 * D7 P1.23 数据线7 * CSA P1.24 左半屏选择,高电平选中 * CSB P1.25 右半屏选择,高电平选中 * RST P0.17 复位控制,低电平复位 * BLK P0.11 背光控制,高电平点亮 * * 作 者:POWER * 日 期:2006年5月18号 * 斯凯科技主页:www.ARMsky.net * 斯凯科技论坛:www.ARMsky.net/bbs ******************************************************************************************************************/
#ifndef LCM12864Drive_H #define LCM12864Drive_H
/* 定义颜色数据类型(可以是数据结构)*/ #define TCOLOR uint8
/* 定义LCM像素数宏 */ #define GUI_LCM_XMAX 128 // 定义液晶x轴的像素数 #define GUI_LCM_YMAX 64 // 定义液晶y轴的像素数
/* 定义RS控制 */ #define LCM12864_RS 18 #define H_LCM12864_RS() IO0SET=(uint32)0x01<<LCM12864_RS #define L_LCM12864_RS() IO0CLR=(uint32)0x01<<LCM12864_RS
/* 定义RW控制 */ #define LCM12864_RW 19 #define H_LCM12864_RW() IO0SET=(uint32)0x01<<LCM12864_RW #define L_LCM12864_RW() IO0CLR=(uint32)0x01<<LCM12864_RW
/* 定义E控制 */ #define LCM12864_E 20 #define H_LCM12864_E() IO0SET=(uint32)0x01<<LCM12864_E #define L_LCM12864_E() IO0CLR=(uint32)0x01<<LCM12864_E
/* 定义D0数据线 */ #define LCM12864_D0 16 #define H_LCM12864_D0() IO1SET=(uint32)0x01<<LCM12864_D0 #define L_LCM12864_D0() IO1CLR=(uint32)0x01<<LCM12864_D0
/* 定义D1数据线 */ #define LCM12864_D1 17 #define H_LCM12864_D1() IO1SET=(uint32)0x01<<LCM12864_D1 #define L_LCM12864_D1() IO1CLR=(uint32)0x01<<LCM12864_D1
/* 定义D2数据线 */ #define LCM12864_D2 18 #define H_LCM12864_D2() IO1SET=(uint32)0x01<<LCM12864_D2 #define L_LCM12864_D2() IO1CLR=(uint32)0x01<<LCM12864_D2
/* 定义D3数据线 */ #define LCM12864_D3 19 #define H_LCM12864_D3() IO1SET=(uint32)0x01<<LCM12864_D3 #define L_LCM12864_D3() IO1CLR=(uint32)0x01<<LCM12864_D3
/* 定义D4数据线 */ #define LCM12864_D4 20 #define H_LCM12864_D4() IO1SET=(uint32)0x01<<LCM12864_D4 #define L_LCM12864_D4() IO1CLR=(uint32)0x01<<LCM12864_D4
/* 定义D5数据线 */ #define LCM12864_D5 21 #define H_LCM12864_D5() IO1SET=(uint32)0x01<<LCM12864_D5 #define L_LCM12864_D5() IO1CLR=(uint32)0x01<<LCM12864_D5
/* 定义D6数据线 */ #define LCM12864_D6 22 #define H_LCM12864_D6() IO1SET=(uint32)0x01<<LCM12864_D6 #define L_LCM12864_D6() IO1CLR=(uint32)0x01<<LCM12864_D6
/* 定义D7数据线 */ #define LCM12864_D7 23 #define H_LCM12864_D7() IO1SET=(uint32)0x01<<LCM12864_D7 #define L_LCM12864_D7() IO1CLR=(uint32)0x01<<LCM12864_D7
/* 定义CSA控制 */ #define LCM12864_CSA 24 #define H_LCM12864_CSA() IO1SET=(uint32)0x01<<LCM12864_CSA #define L_LCM12864_CSA() IO1CLR=(uint32)0x01<<LCM12864_CSA
/* 定义CSB控制 */ #define LCM12864_CSB 25 #define H_LCM12864_CSB() IO1SET=(uint32)0x01<<LCM12864_CSB #define L_LCM12864_CSB() IO1CLR=(uint32)0x01<<LCM12864_CSB
/* 定义RST控制 */ #define LCM12864_RST 17 #define H_LCM12864_RST() IO0SET=(uint32)0x01<<LCM12864_RST #define L_LCM12864_RST() IO0CLR=(uint32)0x01<<LCM12864_RST
/* 定义BLK控制 */ #define LCM12864_BLK 11 #define H_LCM12864_BLK() IO0SET=(uint32)0x01<<LCM12864_BLK #define L_LCM12864_BLK() IO0CLR=(uint32)0x01<<LCM12864_BLK
/* 定义LCM12864操作的命令字 */ #define LCM12864_DISPON 0x3f // 打开LCM12864显示 #define LCM12864_STARTROW 0xc0 // 显示起始行0,可以用LCM12864_STARTROW+x设置起始行。(x<64) #define LCM12864_ADDRSTRX 0xb8 // 页起始地址,可以用LCM12864_ADDRSTRX+x设置当前页(即X)。(x<8) #define LCM12864_ADDRSTRY 0x40 // 列起始地址,可以用LCM12864_ADDRSTRY+x设置当前列(即Y)。(x<64)
/****************************************************************************************************************** * 函数名称:GUI_FillSCR() * 功 能:全屏填充。填充显示缓冲区及LCM12864。 * 入口参数:data 填充的数据 * 出口参数:无 *******************************************************************************************************************/ extern void GUI_FillSCR(uint8 data);
/****************************************************************************************************************** * 函数名称:GUI_ClearSCR() * 功 能:清屏。 * 入口参数:无 * 出口参数:无 *******************************************************************************************************************/ #define GUI_ClearSCR() GUI_FillSCR(0x00)
/****************************************************************************************************************** * 函数名称:GUI_Initialize() * 功 能:初始化显示缓冲区及LCM12864并清屏。 * 入口参数:无 * 出口参数:无 *******************************************************************************************************************/ extern void GUI_Initialize(void);
/****************************************************************************************************************** * 函数名称:GUI_Point() * 功 能:在指定位置上画点。 * 入口参数:x 指定点所在列的位置 * y 指定点所在行的位置 * color 对于黑白色或蓝白色LCM12864,为0时灭,为1时显示 * 出口参数:返回值为1时表示操作成功,为0时表示操作失败。 *******************************************************************************************************************/ extern uint8 GUI_Point(uint8 x, uint8 y, uint8 color);
/****************************************************************************************************************** * 函数名称:GUI_ReadPoint() * 功 能:读取指定点的颜色。 * 入口参数:x 指定点所在列的位置 * y 指定点所在行的位置 * ret 保存颜色值的指针 * 出口参数:返回0表示指定地址超出缓冲区范围。 * 说 明:对于单色,设置ret的d0位为1或0 *******************************************************************************************************************/ extern uint8 GUI_ReadPoint(uint8 x, uint8 y, uint8 *ret);
/****************************************************************************************************************** * 函数名称:GUI_HLine() * 功 能:画水平线。 * 入口参数:x0 水平线起点所在列的位置 * y0 水平线起点所在行的位置 * x1 水平线终点所在列的位置 * color 显示颜色(对于黑白色或蓝白色LCM12864,为0时灭,为1时显示LCM12864,为0时灭,为1时显示) * 出口参数:无 *******************************************************************************************************************/ extern void GUI_HLine(uint8 x0, uint8 y0, uint8 x1, uint8 color);
/****************************************************************************************************************** * 函数名称:GUI_RLine() * 功 能:画竖直线。根据硬件特点,实现加速。 * 入口参数:x0 垂直线起点所在列的位置 * y0 垂直线起点所在行的位置 * y1 垂直线终点所在行的位置 * color 显示颜色(对于黑白色或蓝白色LCM12864,为0时灭,为1时显示LCM12864,为0时灭,为1时显示) * 出口参数:无 *******************************************************************************************************************/ extern void GUI_RLine(uint8 x0, uint8 y0, uint8 y1, uint8 color);
/****************************************************************************************************************** * 函数名称:GUI_CmpColor() * 功 能:判断颜色值是否一致 * 入口参数:color1 颜色值1 * color2 颜色值2 * 出口参数:返回1表示相同;返回0表示不相同 *******************************************************************************************************************/ #define GUI_CmpColor(color1,color2) ((color1&0x01)==(color2&0x01))
/****************************************************************************************************************** * 函数名称:GUI_CopyColor() * 功 能:颜色值复制 * 入口参数:color1 目标颜色变量 * color2 源颜色变量 * 出口参数:无 *******************************************************************************************************************/ #define GUI_CopyColor(color1,color2) *color1=color2&0x01
#endif
|