📄 lcddrive.c
字号:
/****************************************************************************************
* 文件名:LCDDRIVE.C
* 功能:TFT6758液晶模块驱动。驱动芯片为HD66781 (片内224640字节GRAM,即240*(96+320)*18/8),
* 门驱动(Gate driver)芯片为HD66783。
*
* RGB对应值(16位数据,d15--d0):
* d15--d11 R色
* d10--d5 G色
* d4--d0 B色
* 写操作时地址计数器会自动增长,而读操作则不会自动增长。读操作时,读第2个数
* 据才是有效的数据
****************************************************************************************/
#include "config.h"
/*******************************************************
* 名称: TftSendCom
* 功能: 向TFT液晶模块发送命令字。
* 入口参数: com 命令字(uint16)
* 出口参数: 无
*******************************************************/
void TftSendCom(uint16 com)
{ HD66781_IR = com;
}
/*******************************************************
* 名称: TftSendDat
* 功能: 向TFT液晶模块发送数据。
* 入口参数: dat 待发送的数据(uint16)
* 出口参数: 无
*******************************************************/
void TftSendDat(uint16 dat)
{ HD66781_DR = dat;
}
/*******************************************************
* 名称: TftRcvDat
* 功能: 读取TFT液晶模块的数据。
* 入口参数: 无
* 出口参数: 返回值即是读出的数据
*******************************************************/
uint16 TftRcvDat(void)
{ uint16 ret;
ret = HD66781_DR;
return(ret);
}
#define MAX_WAIT 10000 /* 等待超时控制值 */
/*******************************************************
* 名称: TftSerialCom
* 功能: 向TFT液晶模块发送串行命令(HD66781-->HD66783)。
* 入口参数: indx 目标寄存器索引
* dat 待发送的数据(uint16)
* 出口参数: 无
*******************************************************/
void TftSerialCom(uint16 indx, uint16 dat)
{ uint32 delay;
uint16 bak;
TftSendCom(GATEIC_DAT);
TftSendDat(dat); // 发送数据
delay = 0;
TftSendCom(GATEIC_CON);
while(1)
{ bak = TftRcvDat(); // 读TE位(0110H寄存器的d8位)
if((bak&0x0100) == 0) break; // 若TE=0,表明允许发送数据
delay++;
if(delay>MAX_WAIT) return; // 超时操作
}
indx |= 0x0100; // 设置TE=1
TftSendDat(indx); // 指定目标寄存器索引
}
/*******************************************************
* 名称: TftSetAddr
* 功能: 设置数据地址指针(坐标值)。
* 入口参数: x 横坐标的值 (0-239)
* y 纵坐标的值 (0-319)
* 出口参数: 设置正确返回TRUE,参数超出范围返回FALSE
*******************************************************/
uint8 TftSetAddr(uint16 x, uint16 y)
{ TftSendCom(SET_ADDR_X); // 设置地址低8位
TftSendDat(x);
TftSendCom(SET_ADDR_Y); // 设置地址高9位
TftSendDat(y);
if((x<240) && (y<320)) return(TRUE);
else return(FALSE);
}
/*******************************************************
* 名称: TftSetWrite
* 功能: 设置数据地址指针(坐标值),并发送写数据命令。
* 接着不断的写入数据即可,GRAM地址会自动增加。
* 入口参数: x 横坐标的值 (0-239)
* y 纵坐标的值 (0-319)
* 出口参数: 设置正确返回TRUE,参数超出范围返回FALSE
*******************************************************/
uint8 TftSetWrite(uint16 x, uint16 y)
{ uint8 ret;
ret = TftSetAddr(x, y);
TftSendCom(WR_RD_DATA); // 写数据
return(ret);
}
/*******************************************************
* 名称: TftSetWindow
* 功能: 设置数据填充窗口大小。
* 入口参数: x0,y0 窗口左上角从标
* x1,y1 窗口右上角从标
* 出口参数: 设置正确返回TRUE,参数错误返回FALSE
*******************************************************/
uint8 TftSetWindow(uint16 x0, uint16 y0, uint16 x1, uint16 y1)
{ // 参数过滤
if(x1>239) x1 = 239;
if(y1>319) y1 = 319;
if((x1<=x0) || (y1<=y0)) return(FALSE);
// 设置数据填充窗口大小
TftSendCom(SET_WINDOW_SX);
TftSendDat(x0);
TftSendCom(SET_WINDOW_SY);
TftSendDat(y0);
TftSendCom(SET_WINDOW_EX);
TftSendDat(x1);
TftSendCom(SET_WINDOW_EY);
TftSendDat(y1);
return(TRUE);
}
/*******************************************************
* 名称: DelaymS
* 功能: 软件延时(1mS,与系统时钟有关)。
* 入口参数: no 延时控制(uint32),值越大延时越长
* 出口参数: 无
*******************************************************/
void DelaymS(uint32 no)
{ uint32 i;
for(; no>0; no--)
{ for(i=0; i<1500; i++);
}
}
/****************************************************************************
* 名称:TFT_FillSCR()
* 功能:全屏填充。直接使用数据填充显示缓冲区。
* 入口参数:dat 填充的数据
* 出口参数:无
****************************************************************************/
void TFT_FillSCR(uint16 dat)
{ uint16 i, j;
TftSetWindow(0,0, 239, 319);
TftSetWrite(0, 0);
for(i=0; i<GUI_LCM_YMAX; i++) // 历遍所有行
{ for(j=0; j<GUI_LCM_XMAX; j++) // 历遍所有行
{ TftSendDat(dat); // 填充数据
}
}
}
/*******************************************************
* 名称: TftReset
* 功能: 控制TFT液晶模块复位。
* 入口参数: 无
* 出口参数: 无
*******************************************************/
void TftReset(void)
{ IO0DIR = IO0DIR | HD66781_RST;
IO0CLR = HD66781_RST;
DelaymS(10);
IO0SET = HD66781_RST;
DelaymS(10);
}
// 定义TFT6758初始化数据信息
STCOM_INI TFT6758_INI[] =
{ // 设置电源
{HD66783_COM, 0x0001, 0x0474, 0}, // HD66783电压设置1
{HD66783_COM, 0x0002, 0x02DE, 0}, // HD66783电压设置2
{HD66783_COM, 0x0001, 0x0C74, 0},
{HD66781_COM, 0x0100, 0x0050, 0}, // HD66781电源控制
{HD66783_COM, 0x0000, 0x080C, 0}, // HD66783电源控制
{HD66783_COM, 0x0002, 0x012E, 0},
{HD66783_COM, 0x0001, 0x04B2, 30},
{HD66783_COM, 0x0001, 0x04F0, 0},
{HD66783_COM, 0x0003, 0x0008, 0}, // HD66783扫描模式设置
{HD66783_COM, 0x0006, 0x09C0, 70}, // HD66783输出设置
// 打开显示
{HD66783_COM, 0x0000, 0x0C0A, 0},
{HD66781_COM, 0x0100, 0x0110, 0}, // 电源控制1, STB=0, SLP=0, DSTB=0 (正常工作模式)
{HD66781_COM, 0x0007, 0x0001, 50},
{HD66781_COM, 0x0007, 0x0012, 0},
{HD66783_COM, 0x0000, 0x0C08, 0},
{HD66781_COM, 0x0007, 0x0003, 50},
{HD66781_COM, 0x0007, 0x0013, 0},
{HD66781_COM, 0x0007, 0x0113, 0}, // 显示控制1, D1:D0=11(使能显示)
// 其它设置
{HD66781_COM, 0x0001, 0x0100, 0}, // 驱动输出控制, SS=1
{HD66781_COM, 0x0002, 0x0700, 0}, // 驱动波形控制
{HD66781_COM, 0x0003, 0x1030, 0}, // 启动模式设置, HWM=0, ID1:ID0 =11, AM=0 (不使用缓冲, 地址自动更新为"左上"至"右下"方式)
// BRG=0, OSD=0, TRI=0 (点象素数据为:RRRRRGGGGGGBBBBB)
{HD66781_COM, 0x0004, 0x0000, 0}, // 缩放控制1
{HD66781_COM, 0x0005, 0x0000, 0}, // 缩放控制2
{HD66781_COM, 0x0008, 0x0303, 0}, // 显示控制2, FP3:FP0=3, BP2:BP0=3 (非显示周期数)
{HD66781_COM, 0x0009, 0x142C, 0}, // 显示控制3
{HD66781_COM, 0x000B, 0x0000, 0}, // 显示控制4, FRCON=0, COL1:0=00 (262144色)
{HD66781_COM, 0x000C, 0x0001, 0}, // 外部显示接口控制1
{HD66781_COM, 0x000D, 0x0010, 0}, // 帧周期控制
{HD66781_COM, 0x000E, 0x0210, 0}, // 外部显示接口控制2
{HD66781_COM, 0x000F, 0x0000, 0}, // 外部显示接口控制3
{HD66781_COM, 0x0010, 0x0000, 0}, // 门驱动(Gate driver)接口控制1
{HD66781_COM, 0x0011, 0x0000, 0}, // 门驱动(Gate driver)接口控制2
{HD66781_COM, 0x0012, 0x0002, 0}, // 门驱动(Gate driver)接口控制3
{HD66781_COM, 0x0013, 0x0000, 0}, // 门驱动(Gate driver)接口控制4
{HD66781_COM, 0x0015, 0x0000, 0}, // 门驱动(Gate driver)接口控制5
{HD66781_COM, 0x0016, 0x0000, 0}, // 门驱动(Gate driver)接口控制6
{HD66781_COM, 0x0017, 0x0000, 0}, // 门驱动(Gate driver)接口控制7
{HD66781_COM, 0x0018, 0x0005, 0}, // 门驱动(Gate driver)接口控制8
{HD66781_COM, 0x0019, 0x0000, 0}, // 门驱动(Gate driver)接口控制9
{HD66781_COM, 0x001B, 0x0000, 0}, // 门驱动(Gate driver)接口控制10
{HD66781_COM, 0x0200, 0x0000, 0}, // GRAM地址设置(R201H,R200H), 0x0000
{HD66781_COM, 0x0201, 0x0000, 0},
{HD66781_COM, 0x0203, 0x0000, 0}, // GRAM写屏蔽控制(R204H,R203H), 0x0000
{HD66781_COM, 0x0204, 0x0000, 0},
{HD66781_COM, 0x0210, 0x0000, 0}, // window地址设置(R210H,R211H):水平方向为0--239 (x = 239+1)
{HD66781_COM, 0x0211, 0x00EF, 0},
{HD66781_COM, 0x0212, 0x0000, 0}, // window地址设置(R212H,R213H):垂直方向为0--319 (y = 319+1)
{HD66781_COM, 0x0213, 0x013F, 0},
{HD66781_COM, 0x0400, 0x0027, 0}, // 液晶光栅行设置,NL0[5:0]=39, 即(39+1)*8=320
{HD66781_COM, 0x0401, 0x0001, 0}, // 基本显示控制, REV=1(正方向显示), VLE=0(不滚屏)
{HD66781_COM, 0x0402, 0x0000, 0}, // 显示起始行地址(y), 0
{HD66781_COM, 0x0403, 0x013F, 0}, // 显示终止行地址(y), 319
{HD66781_COM, 0x0404, 0x0000, 0}, // 滚屏行数, 0
{HD66781_COM, 0x0405, 0x0000, 0}, // 缩放显示起始行地址(y), 0
{HD66781_COM, 0x0406, 0x0000, 0}, // 缩放显示终止行地址(y), 0
{DATA_END, 0, 0, 0}
};
/*******************************************************
* 名称: TftInit
* 功能: 初始化TFT液晶模块。
* 入口参数: 无
* 出口参数: 无
*******************************************************/
void TftInit(void)
{ STCOM_INI init_dat;
int i;
TftReset();
for(i=0; i<100; i++) // 设定最多100条初始化命令
{ init_dat = TFT6758_INI[i];
if(init_dat.type==DATA_END) break;
if(init_dat.type==HD66783_COM)
{ TftSerialCom(init_dat.com, init_dat.dat);
}
else
{ TftSendCom(init_dat.com);
TftSendDat(init_dat.dat);
}
DelaymS(init_dat.dly);
}
}
/****************************************************************************
* 名称:GUI_Initialize()
* 功能:初始化GUI,包括初始化显示缓冲区,初始化LCM并清屏。
* 入口参数:无
* 出口参数:无
* 说明:用户根据LCM的实际情况编写此函数。
****************************************************************************/
void GUI_Initialize(void)
{ TftInit();
TFT_FillSCR(GUI_CCOLOR);
}
/****************************************************************************
* 名称:GUI_FillSCR()
* 功能:全屏填充。直接使用数据填充显示缓冲区。
* 入口参数:dat 填充的数据
* 出口参数:无
* 说明:用户根据LCM的实际情况编写此函数。
****************************************************************************/
void GUI_FillSCR(TCOLOR dat)
{ TFT_FillSCR(dat);
}
/****************************************************************************
* 名称:GUI_ClearSCR()
* 功能:清屏。
* 入口参数:无
* 出口参数:无
* 说明:用户根据LCM的实际情况编写此函数。
****************************************************************************/
void GUI_ClearSCR(void)
{ TFT_FillSCR(GUI_CCOLOR);
}
/****************************************************************************
* 名称:GUI_Point()
* 功能:在指定位置上画点。
* 入口参数:x 指定点所在列的位置
* y 指定点所在行的位置
* color 显示颜色
* 出口参数:返回值为1时表示操作成功,为0时表示操作失败。
****************************************************************************/
uint8 GUI_Point(uint16 x, uint16 y, TCOLOR color)
{ /* 参数过滤 */
if(x>=GUI_LCM_XMAX) return(0);
if(y>=GUI_LCM_YMAX) return(0);
/* 刷新显示 */
TftSetWrite(x, y);
TftSendDat(color);
return(1);
}
/****************************************************************************
* 名称:GUI_ReadPoint()
* 功能:读取指定位置点的颜色数据。
* 入口参数:x 指定点所在列的位置
* y 指定点所在行的位置
* 出口参数:返回值即是读出值(RRRRRGGGGGGBBBBB)。
****************************************************************************/
uint8 GUI_ReadPoint(uint16 x, uint16 y, TCOLOR *ret)
{ uint16 dat;
uint16 bak;
/* 参数过滤 */
if(x>=GUI_LCM_XMAX) return(0);
if(y>=GUI_LCM_YMAX) return(0);
/* 读取数据 */
TftSetAddr(x, y); // 设置地址
TftSendCom(WR_RD_DATA);
bak = TftRcvDat();
bak = TftRcvDat();
dat = (bak>>11); // B色
dat |= (bak<<11); // R色
dat |= (bak&0x07E0); // G色
*ret = dat;
return(1);
}
/****************************************************************************
* 名称:GUI_HLine()
* 功能:画水平线。
* 入口参数:x0 水平线起点所在列的位置
* y0 水平线起点所在行的位置
* x1 水平线终点所在列的位置
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出缓冲区范围。
****************************************************************************/
void GUI_HLine(uint16 x0, uint16 y0, uint16 x1, TCOLOR color)
{ uint16 bak;
if(x0>x1) // 对x0、x1大小进行排列,以便画图
{ bak = x1;
x1 = x0;
x0 = bak;
}
GUI_Point(x0, y0, color); // 显示第一点
x0++;
while(x1>=x0)
{ TftSendDat(color); // 不断填充并显示
x0++;
}
}
/****************************************************************************
* 名称:GUI_RLine()
* 功能:画垂直线。
* 入口参数: x0 垂直线起点所在列的位置
* y0 垂直线起点所在行的位置
* y1 垂直线终点所在行的位置
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出缓冲区范围。
****************************************************************************/
void GUI_RLine(uint16 x0, uint16 y0, uint16 y1, TCOLOR color)
{ uint16 bak;
if(y0>y1) // 对y0、y1大小进行排列,以便画图
{ bak = y1;
y1 = y0;
y0 = bak;
}
while(y1>=y0)
{ GUI_Point(x0, y0, color); // 逐点显示,描出垂直线
y0++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -