?? lcd_drv.c
字號:
//=============================================
// 320X240@單色LCD基本函數
//控制電路SED1335,總線方式
//==============================================
#include "lcd_defs.h"
#include "ha_defs.h" //LCD寄存器地址
#include "type.h"
#include "font.h"
//--------1335初始化-------------------
void Init1335(void)
{
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
LcdCommand(0x40); //系統設置指令,8個參數
LcdDataWrite(0x30);
LcdDataWrite(0x87);
LcdDataWrite(0x07);
LcdDataWrite(39); //顯示域長度為320dot
LcdDataWrite(66); //確定液晶工作頻率66
LcdDataWrite(240); //顯示屏高度為240dot
LcdDataWrite(40); //顯示屏一行所占顯示緩沖區字節數(L)
LcdDataWrite(0); //顯示屏一行所占顯示緩沖區字節數(H)
LcdCommand(0x44); //顯示區設置,最多10個參數
LcdDataWrite(0x00); //顯示1區對應的顯示RAM起始地址(L)
LcdDataWrite(0x00); //顯示1區對應的顯示RAM起始地址(H)
LcdDataWrite(240); //顯示1區控制240行
LcdDataWrite(9600%256);//顯示2區對應的顯示RAM起始地址(L) (0+40×240=9600)
LcdDataWrite(9600/256);//顯示2區對應的顯示RAM起始地址(H)
LcdDataWrite(240); //顯示2區控制240行
LcdDataWrite(SAD3%256);//顯示3區對應的顯示RAM起始地址(L) (19200)
LcdDataWrite(SAD3/256);//顯示3區對應的顯示RAM起始地址(H)
LcdDataWrite(SAD4%256);//顯示4區對應的顯示RAM起始地址(L) (28800)
LcdDataWrite(SAD4/256);//顯示4區對應的顯示RAM起始地址(H)
LcdCommand(0x5a); //水平卷動,初始化時必須清零
LcdDataWrite(0x00);
LcdCommand(0x5b); //各個顯示區的合成方式,1個參數
LcdDataWrite(0x0c); //簡單疊加,圖形模式
LcdCommand(0x59); //打開顯示,1個參數
LcdDataWrite(0x14); //開顯示區1和2,不閃爍,光標關閉
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//----清一、二屏-----------------
void LcdClear(void)
{
INT8U i,j;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
LcdCommand(0x4c); //光標向后移動
LcdLocate(0,0,SAD1); //第1區
LcdCommand(0x42);
for(j=0;j<240;j++)
{
for(i=0;i<40;i++)
LcdDataWrite(0x00);
}
LcdLocate(0,0,SAD2); //第2區
LcdCommand(0x42);
for(j=0;j<240;j++)
{
for(i=0;i<40;i++)
LcdDataWrite(0x00);
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//--------清指定區域--------------------------------------------
//入口:(x1,y1)=左上角
// (x2,y2)=右上角
void DisClrRec(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
INT16U j,i;
INT8U temp;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
LcdCommand(0x4c); //光標向后移動
for(j=y1;j<y2;j++)
{
temp = LcdRead(x1,j,offset);
temp &= (0xff<<(8-x1%8));
LcdWrite(x1,j,temp,offset);
}
for(j=y1;j<y2;j++)
{
LcdLocate(x1+8,j,offset);
LcdCommand(0x42);
for(i=x1+8;i<x2;i=i+8)
{
LcdDataWrite(0x00);
}
}
for(j=y1;j<y2;j++)
{
temp = LcdRead(x2,j,offset);
temp &= (0xff>>(x2%8));
LcdWrite(x2,j,temp,offset);
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//--------填充指定區域--------------------------------------------
//入口:(x1,y1)=左上角
// (x2,y2)=右上角
void DisFullRec(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
INT8U temp;
INT16U i,j;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
LcdCommand(0x4c); //光標向后移動
for(j=y1;j<y2;j++)
{
temp = LcdRead(x1,j,offset);
temp |= (0xff>>(x1%8));
LcdWrite(x1,j,temp,offset);
}
for(j=y1;j<y2;j++)
{
LcdLocate(x1+8,j,offset);
LcdCommand(0x42);
for(i=x1+8;i<x2;i=i+8)
{
LcdDataWrite(0xff);
}
}
for(j=y1;j<y2;j++)
{
temp = LcdRead(x2,j,offset);
temp |= (0xff<<(8-x2%8));
LcdWrite(x2,j,temp,offset);
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//----畫點-------------------------
//入口:(x,y)=位置
void DisDot(INT16U x,INT16U y,INT16U offset)
{
INT8U temp;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
temp = LcdRead(x,y,offset);
temp |= (0x80>>(x%8));
LcdWrite(x,y,temp,offset);
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//----擦除1點-------------------------
//入口:(x,y)=位置
void DisClrDot(INT16U x,INT16U y,INT16U offset)
{
INT8U temp,temp1;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
temp = LcdRead(x,y,offset);
temp1 = (0x80>>(x%8));
temp1 = ~temp1;
temp &= temp1;
LcdWrite(x,y,temp,offset);
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//-----虛線 只提供X或Y方向的,不支持斜線(11110000)-------------
//4點實4點虛間隔
//入口:(x1,y1)=起點
// (x2,y2)=終點
//注意:終點坐標必須>=起點坐標
void Dashed(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
INT16U i;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
//畫豎線
if(x1==x2)
{
for(i=y1;i<=y2-3;i=i+8)
{
DisDot(x1,i,offset);
DisDot(x1,i+1,offset);
DisDot(x1,i+2,offset);
DisDot(x1,i+3,offset);
}
}
//畫橫線
else if(y1==y2)
{
for(i=x1;i<x2-3;i=i+8)
{
DisDot(i,y1,offset);
DisDot(i+1,y1,offset);
DisDot(i+2,y1,offset);
DisDot(i+3,y1,offset);
}
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//----畫實線-支持斜線-------------
//入口:neg=0,畫,=1擦
// (x1,y1)=起點,(x2,y2)=終點
//注意:畫直線時終點坐標必須>=起點坐標
void Line(INT8U neg,INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
INT16U i;
INT16U xerr=0,yerr=0;
INT16U delta_x,delta_y,distance;
INT16U incx,incy;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
//畫豎線
if(x1==x2)
{
for(i=y1;i<y2;i++)
{
if(neg) DisClrDot(x1,i,offset);
else DisDot(x1,i,offset);
}
}
//畫橫線
else if(y1==y2)
{
for(i=x1;i<x2;i++)
{
if(neg) DisClrDot(i,y1,offset);
else DisDot(i,y1,offset);
}
}
//畫斜線
else
{
if(x2>x1)
{
delta_x = x2-x1; // 計算兩個方向的距離
incx = 1;
}
else
{
delta_x = x1-x2;
incx = 2;
}
if(y2>y1)
{
delta_y = y2-y1; // 計算兩個方向的距離
incy = 1;
}
else
{
delta_y = y1-y2;
incy = 2;
}
if(delta_x>delta_y) //判斷哪個方向增量大
distance = delta_x;
else
distance = delta_y;
for(i=0;i<distance;i++) //畫線
{
if(neg) DisClrDot(x1,y1,offset);
else DisDot(x1,y1,offset);
xerr += delta_x ;
yerr += delta_y ;
if(xerr>=distance ) //計算哪些地方為45度斜線,哪些地方為橫線或豎線
{ //當x方向大于45度時,x+1,否則x不變
xerr -= distance;
if(incx==2) x1 -= 1;
else x1 += incx;
}
if(yerr>=distance )
{ //當y方向大于45度時,y+1,否則y不變
yerr -= distance;
if(incy==2) y1 -= 1;
else y1 += incy;
}
}
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//--------矩形框-----------------------------------------------------
//入口:(x1,y1)=左上角
// (x2,y2)=右上角
void DisRec(INT16U x1,INT16U y1,INT16U x2,INT16U y2,INT16U offset)
{
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
Line(0,x1,y1,x1,y2,offset);
Line(0,x2,y1,x2,y2,offset);
Line(0,x1,y1,x2,y1,offset);
Line(0,x1,y2,x2+1,y2,offset);
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//-----在液晶屏指定位置顯示一個8*12字符---------
//入口:neg=1 反白
// (x,y)=起始坐標
// ps=點陣指針
//注意:.x必須被8整除
void Dis8X12Chr(INT8U neg,INT16U x,INT16U y,INT8U chr,INT16U offset)
{
INT8U i,temp;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
LcdCommand(0x4f); //光標向下移動
LcdLocate(x,y,offset);
LcdCommand(0x42); //設置寫命令
for(i=0;i<12;i++)
{
temp = S8X12Tab[(chr-0x20)*12+i];
if(neg) temp = ~temp;
LcdDataWrite(temp); //寫數據
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//-----在液晶屏指定位置顯示一個8*12字符串---------
//入口:neg=1 反白
// (x,y)=起始坐標
// ps=字符串指針
//注意:1.x必須被8整除,不處理換行
// 2.字符串為Ascii碼
void Dis8X12Str(INT8U neg,INT16U x,INT16U y,INT8U *ps,INT16U offset)
{
INT8U i;
INT16U xbak;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
xbak = x;
for(i=0;i<strlen((char *)(ps));i++)
{
Dis8X12Chr(neg,xbak,y,*(ps+i),offset);
xbak += 8;
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//-----在液晶屏指定位置顯示一個8*12字符串(無效0不顯示)---------
//入口:neg=1 反白
// (x,y)=起始坐標
// ps=字符串指針
//注意:1.x必須被8整除,不處理換行
// 2.字符串為Ascii碼
void Dis8X12DStr(INT8U neg,INT16U x,INT16U y,INT8U *ps,INT16U offset)
{
INT8U i,flag=0;
INT8U *pt;
for(i=0;i<strlen((char *)(ps));i++)
Dis8X12Chr(0,x+i*8,y,' ',offset);
for(i=0;i<strlen((char *)(ps));i++)
{
if(*ps == '-')
{
ps++;
flag = 1;
continue;
}
if((*ps == '0')&&(*(ps+1) != '.'))
ps++;
else
break;
}
pt = ps;
if(flag)
{
Dis8X12Chr(neg,x,y,'-',offset);
x += 8;
}
Dis8X12Str(neg,x,y,pt,offset);
}
//-----在液晶屏指定位置顯示一個16*16漢字---------
//入口:neg=1 反白
// (x,y)=起始坐標
// p=點陣指針
//注意:x必須被8整除
void Dis16X16Chr(INT8U neg,INT16U x,INT16U y,INT8U *p,INT16U offset)
{
INT8U i,j,temp;
INT16U xbak;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
xbak = x;
LcdCommand(0x4c);
for(i=0;i<16;i++)//16
{
LcdLocate(xbak,y+i,offset);
LcdCommand(0x42); //設置寫命令
for(j=0;j<2;j++)
{
temp = *(p+i*2+j);
if(neg) temp = ~temp;
LcdDataWrite(temp); //寫數據
}
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
/*
//-----在液晶屏指定位置顯示一個16*16字符串---------
//字庫按順序排列,2分法查表
//x必須被8整除,不處理換行
//入口:neg=1 反白
// (x,y)=起始坐標
// p=字符串指針
//注意:1.x必須被8整除,不處理換行
// 2.字符串為漢字國標內碼
void Dis16X16Str(INT8U neg,INT16U x,INT16U y,INT8U *p,INT16U offset)
{
INT16U xbak,temp,i;
INT8U *zikupoint;
xbak = x;
while(*p != 0x00) //0x00是字符串的結束標志
{
temp = *p;
temp = (temp<<8)|*(p+1);
i = Font2Tab(temp); //2分法查
zikupoint = S16X16Tab+i*32;
Dis16X16Chr(neg,xbak,y,zikupoint,offset);
xbak += 16;
p += 2;
}
}
*/
//-----在液晶屏指定位置顯示一個16*16字符串---------
//字庫隨機排列,從頭順序查表
//x必須被8整除,不處理換行
//入口:neg=1 反白
// (x,y)=起始坐標
// p=字符串指針
//注意:1.x必須被8整除,不處理換行
// 2.字符串為漢字國標內碼
void Dis16X16Str(INT8U neg,INT16U x,INT16U y,INT8U *p,INT16U offset)
{
INT16U xbak,temp,i;
INT8U *zikupoint;
INT8U j;
xbak = x;
while(*p != 0x00) //0x00是字符串的結束標志
{
for(i=0;;i++)
{
if(((GB_16[i].Index[0]== *p)&&(GB_16[i].Index[1]== *(p+1)))||(GB_16[i].Index[0]==0xff))
break;
}
zikupoint = &GB_16[i].Msk[0];
Dis16X16Chr(neg,xbak,y,zikupoint,offset);
xbak += 16;
p += 2;
}
}
//-------在液晶屏指定位置顯示一個32X32圖標------------
void Dis32X32Chr(INT8U neg,INT16U x,INT16U y,INT16U chr,INT16U offset)
{
INT8U i,j,temp;
INT16U xbak;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
xbak = x;
LcdCommand(0x4c); //光標向右移動
for(i=0;i<32;i++)
{
LcdLocate(xbak,y+i,offset);
LcdCommand(0x42); //設置寫命令
for(j=0;j<4;j++)
{
temp = S32X32Tab[chr*128+i*4+j];
if(neg) temp = ~temp;
LcdDataWrite(temp); //寫數據
}
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
/*
//------字庫2分法查表---------------------
INT16U Font2Tab(INT16U ch)
{
INT16U max,min,t;
INT16U temp;
min = 0; max = strlen((INT8U *)(GB16X16Tab));
do{
t = ((max-min)/4)*2 + min;
temp = GB16X16Tab[t];
temp = (temp<<8)|GB16X16Tab[t+1];
if(temp<ch) min = t;
else if(temp>ch) max = t;
else
{
min = t; break;
}
}while((max-min)>2);
return(min/2);
}*/
//-------在液晶屏指定位置顯示一個圖片PICTab[220*32]------------
void DisPic(INT16U x,INT16U y,INT16U offset)
{
INT8U i,j,temp;
INT16U xbak;
#ifndef LCD_DATABUS
LCDCS = 0;
#endif
xbak = x;
LcdCommand(0x4c); //光標向右移動
for(i=0;i<220;i++)
{
LcdLocate(xbak,y+i,offset);
LcdCommand(0x42); //設置寫命令
for(j=0;j<32;j++)
{
temp = PICTab[i*32+j];
LcdDataWrite(temp); //寫數據
}
}
#ifndef LCD_DATABUS
LCDCS = 1;
#endif
}
//--------光標定位在指定位置------------------
void LcdLocate(INT16U x,INT16U y,INT16U offset)
{
INT16U add;
LcdCommand(0x46); //設置光標地址,2個參數
add = x/8+y*40+offset;
LcdDataWrite((unsigned char)add); //低位地址
LcdDataWrite((unsigned char)(add>>8)); //高位地址
}
//-------讀液晶顯存 ----------------
unsigned char LcdRead(INT16U x,INT16U y,INT16U offset)
{
INT8U temp=1;
LcdLocate(x,y,offset);
LcdCommand(0x43); //設置讀命令
temp = LcdDataRead();
return(temp);
}
//-------寫液晶顯存 ----------------
void LcdWrite(INT16U x,INT16U y,INT8U dat,INT16U offset)
{
LcdLocate(x,y,offset);
LcdCommand(0x42); //設置寫命令
LcdDataWrite(dat); //寫數據
}
//-----寫命令---------------------
void LcdCommand(INT8U c)
{
#ifndef LCD_DATABUS
LCDRS = 1;
LCDRD = 1;
LCDWR = 0;
_nop_();_nop_();
LcmDataPort = c;
_nop_();_nop_();
LCDWR = 1;
#else
LcdWriteCmd = c;
#endif
}
//-----寫數據---------------------
void LcdDataWrite(INT8U d)
{
#ifndef LCD_DATABUS
LCDRD = 1;
LCDRS = 0;
LCDWR = 0;
_nop_();_nop_();
LcmDataPort = d;
_nop_();_nop_();
LCDWR = 1;
#else
LcdWriteData = d;
#endif
}
//-----讀數據---------------------
INT8U LcdDataRead(void)
{
unsigned char temp;
#ifndef LCD_DATABUS
LCDRS = 1;
LCDWR = 1;
LcmDataPort = 0xff;
LCDRD = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
temp = LcmDataPort;
LCDRD = 1;
#else
temp = LcdReadData;
#endif
return(temp);
}
//==============end==========================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -