📄 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 "lpc2294.h"#include "lcddrive.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 = 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}};// 定义总线速度控制字 #define BCFG_DEF 0x10000400#define IDCY (0x01<<0)#define WST1 (0x03<<5)#define WST2 (0x03<<11)#define BCFG3_SET (BCFG_DEF | IDCY | WST1 | WST2)/******************************************************** 名称: TftInit* 功能: 初始化TFT液晶模块。* 入口参数: 无* 出口参数: 无*******************************************************/void TftInit(void) { STCOM_INI init_dat; int i; BCFG3 = BCFG3_SET; 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); } }/******************************************************** 名称: TFT_UpdateRects* 功能: 更新LCM显示区域。更新数据在Framebuffer中。* 入口参数: x,y 更新区域的起始点* w,y 区域宽度和高度* buffer Framebuffer起始地址* 出口参数: 无*******************************************************/void TFT_UpdateRects( int x, int y, // 起始点坐标 int w, int h, // 区域宽度、高度 uint16 *buffer) // Framebuffer起始地址 { int i, j; uint16 *addr;#if SWAP_XY_EN==1 int Xok, Yok; #endif // 需填充区域参数过滤 if(x<0) { w = w + x; x = 0; } if(y<0) { h = h + y; y = 0; } #if SWAP_XY_EN==1 if( x > (GUI_LCM_YMAX-1) || y > (GUI_LCM_XMAX-1) ) { return; } if((x+w) > (GUI_LCM_YMAX-1)) { w = GUI_LCM_YMAX - x; } if((y+h) > (GUI_LCM_XMAX-1)) { h = GUI_LCM_XMAX - y; } #else if( x > (GUI_LCM_XMAX-1) || y > (GUI_LCM_YMAX-1) ) { return; } if((x+w) > (GUI_LCM_XMAX-1)) { w = GUI_LCM_XMAX - x; } if((y+h) > (GUI_LCM_YMAX-1)) { h = GUI_LCM_YMAX - y; } #endif if((w<=0) || (h<=0)) return; /* 若需要交换x、y轴,则Yok = x, Xok = GUI_LCM_XMAX - y-1。则填充矩形算法为: 起点为(GUI_LCM_XMAX - y - h, x); 每一行数据个数为h个字节,共w行数据; 行数据起始点地址:addr = buffer + ((y + h - 1)*GUI_LCM_YMAX + x) + i (第i行,n为0--w)。 同一行中,下一点数据地址变化:addr = addr - GUI_LCM_YMAX; 以上所说的"行"、Xok和Yok,是针对液晶屏的。*/#if SWAP_XY_EN==1 Xok = (int)GUI_LCM_XMAX - (y + h); Yok = x; for(i=0; i<w; i++) // 输出w行数据 { // 计算出更新区域的buffer地址 addr = buffer + ((y + h - 1)*GUI_LCM_YMAX + x) + i; // 输出一行(w个)数据 TftSetWrite(Xok, Yok); for(j=0; j<h; j++) { TftSendDat(*addr); addr = addr - GUI_LCM_YMAX; } // 指向下一行 Yok++; } #else for(i=0; i<h; i++) // 输出h行数据 { // 计算出更新区域的buffer地址 addr = buffer + (y*GUI_LCM_XMAX + x); // 输出一行(w)数据 TftSetWrite(x, y); for(j=0; j<w; j++) { TftSendDat(*addr); addr++; } // 指向下一行 y++; } #endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -