📄 lcdlib.c
字号:
********************************************************************************************************/
void GUI_Rectangle(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
{
GUI_HLine(x0, y0, x1, color);
GUI_HLine(x0, y1, x1, color);
GUI_RLine(x0, y0, y1, color);
GUI_RLine(x1, y0, y1, color);
}
/*********************************************************************************************************
** Function name: GUI_RectangleFill
** Descriptions: 填充矩形。画一个填充的矩形,填充色与边框色一样。
** 操作失败原因是指定地址超出缓冲区范围。
** Input: x0 矩形左上角的x坐标值
** y0 矩形左上角的y坐标值
** x1 矩形右下角的x坐标值
** y1 矩形右下角的y坐标值
** color 填充颜色
** Output: 无
** Created by: 黄绍斌
** Created Date: 2005-12-31
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void GUI_RectangleFill(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
{
uint32 i;
// 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1)
if(x0 > x1) // 若x0>x1,则x0与x1交换
{
i = x0;
x0 = x1;
x1 = i;
}
if(y0 > y1) // 若y0>y1,则y0与y1交换
{
i = y0;
y0 = y1;
y1 = i;
}
// 判断是否只是直线
if(y0 == y1)
{
GUI_HLine(x0, y0, x1, color);
return;
}
if(x0 == x1)
{
GUI_RLine(x0, y0, y1, color);
return;
}
while(y0 <= y1)
{
GUI_HLine(x0, y0, x1, color); // 当前画水平线
y0++; // 下一行
}
}
/*********************************************************************************************************
** Function name: GUI_Line
** Descriptions: 画任意两点之间的直线。
** 操作失败原因是指定地址超出缓冲区范围。
** Input: x0 直线起点的x坐标值
** y0 直线起点的y坐标值
** x1 直线终点的x坐标值
** y1 直线终点的y坐标值
** color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
** Output: 无
** Created by: 黄绍斌
** Created Date: 2005-12-31
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void GUI_Line(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
{
int32 dx; // 直线x轴差值变量
int32 dy; // 直线y轴差值变量
int8 dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向
int8 dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向
int32 dx_x2; // dx*2值变量,用于加快运算速度
int32 dy_x2; // dy*2值变量,用于加快运算速度
int32 di; // 决策变量
dx = x1-x0; // 求取两点之间的差值
dy = y1-y0;
// 判断增长方向,或是否为水平线、垂直线、点
if(dx>0) // 判断x轴方向
{
dx_sym = 1; // dx>0,设置dx_sym=1
}
else
{
if(dx<0)
{
dx_sym = -1; // dx<0,设置dx_sym=-1
}
else
{
// dx==0,画垂直线,或一点
GUI_RLine(x0, y0, y1, color);
return;
}
} // end of if(dx>0)...else...
if(dy>0) // 判断y轴方向
{
dy_sym = 1; // dy>0,设置dy_sym=1
}
else
{
if(dy<0)
{
dy_sym = -1; // dy<0,设置dy_sym=-1
}
else
{
// dy==0,画水平线,或一点
GUI_HLine(x0, y0, x1, color);
return;
}
} // end of if(dy>0)...else...
// 将dx、dy取绝对值
dx = dx_sym * dx;
dy = dy_sym * dy;
// 计算2倍的dx及dy值
dx_x2 = dx*2;
dy_x2 = dy*2;
// 使用Bresenham法进行画直线
if(dx >= dy) // 对于dx>=dy,则使用x轴为基准
{
di = dy_x2 - dx;
while(x0 != x1)
{
GUI_Point(x0, y0, color);
x0 += dx_sym;
if(di<0)
{
di += dy_x2; // 计算出下一步的决策值
}
else
{
di += dy_x2 - dx_x2;
y0 += dy_sym;
}
} // end of while(x0 != x1)...
GUI_Point(x0, y0, color); // 显示最后一点
}
else // 对于dx<dy,则使用y轴为基准
{
di = dx_x2 - dy;
while(y0 != y1)
{
GUI_Point(x0, y0, color);
y0 += dy_sym;
if(di<0)
{
di += dx_x2;
}
else
{
di += dx_x2 - dy_x2;
x0 += dx_sym;
}
} // end of while(y0 != y1)...
GUI_Point(x0, y0, color); // 显示最后一点
} // end of if(dx >= dy)...else...
}
/*********************************************************************************************************
** Function name: GUI_DispPic
** Descriptions: 指定位置显示图片(图片大小为w、h)。
** 不能正确显示原因可能是指定的起始点不对,或高度、宽度超出液晶显示范围,或数据格式错误。
** Input: x,y 更新区域的起始点(左上角)
* w,h 区域宽度和高度
* buffer 显示数据缓冲区(uint16, 格式为 R:5, G:6, B:5)
** Output: 无
** Created by: 黄绍斌
** Created Date: 2005-12-31
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void GUI_DispPic( uint16 x, uint16 y,
uint16 w, uint16 h,
uint16 *buffer)
{
int i, j;
volatile uint16 *p_buffer;
// 需填充区域参数过滤
if( (x >= GUI_LCM_XMAX) ||
(y >= GUI_LCM_YMAX)
)
{ return;
}
if((x+w) > GUI_LCM_XMAX)
{ return;
}
if((y+h) > GUI_LCM_YMAX)
{ return;
}
// 更新显示数据
for(i=0; i<h; i++) // 输出h行数据
{
// 输出一行(w)数据
p_buffer = (uint16 *)FrameBuffer;
p_buffer = p_buffer + y*GUI_LCM_XMAX + x;
for(j=0; j<w; j++)
{
*p_buffer++ = *buffer++; // 输出数据
}
// 指向下一行
y++;
} // end of for(i=0; i<h; i++)...
}
void Lcd_Init_44()
{
LCD_PortInit(); // 初始化LCD控制口线
LCD_ControlInit(); // 初始化LCD控制器
Lcd_DispON(); // 打开LCD显示
TFT_FillSCR(WHITE); // 全屏填充清屏颜色(即清屏)
}
void Lcd_MoveViewPort(int vx,int vy,int depth)
{
/*
U32 addr;
switch(depth)
{
case 1:
// LCDBASEU,LCDBASEL register has to be changed before 12 words before the end of VLINE.
// In mono mode, x=320 is 10 words, So, We can't change LCDBASEU,LCDBASEL
// during LINECNT=1~0 at mono mode.
//The processor mode should be superviser mode.
DisableInterrupt();
#if (LCD_XSIZE<512)
while((rLCDCON1>>22)<=1); // if x<512
#else
while((rLCDCON1>>22)==0); // if x>512 ((12+4)*32)
#endif
addr=(U32)frameBuffer1+(vx/8)+vy*(SCR_XSIZE/8);
rLCDSADDR1= (0x0<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
// monochrome, LCDBANK, LCDBASEU
rLCDSADDR2= M5D( ((addr+(SCR_XSIZE*LCD_YSIZE/8))>>1) ) | (MVAL<<21);
EnableInterrupt();
break;
case 4:
//The processor mode should be superviser mode.
DisableInterrupt();
#if (LCD_XSIZE<256)
while((rLCDCON1>>22)<=1); // if x<256
#else
while((rLCDCON1>>22)==0); // if x>256
#endif
addr=(U32)frameBuffer4+(vx/4)+vy*(SCR_XSIZE/4);
rLCDSADDR1= (0x1<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
// 4-gray, LCDBANK, LCDBASEU
rLCDSADDR2= M5D(((addr+(SCR_XSIZE*LCD_YSIZE/4))>>1)) | (MVAL<<21);
EnableInterrupt();
break;
case 16:
//The processor mode should be superviser mode.
DisableInterrupt();
#if (LCD_XSIZE<128)
while((rLCDCON1>>22)<=1); // if x<128
#else
while((rLCDCON1>>22)==0); // if x>128
#endif
addr=(U32)frameBuffer16+(vx/2)+vy*(SCR_XSIZE/2);
rLCDSADDR1= (0x2<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
// 16-gray, LCDBANK, LCDBASEU
rLCDSADDR2= M5D(((addr+(SCR_XSIZE*LCD_YSIZE/2))>>1)) | (MVAL<<21);
EnableInterrupt();
break;
case 256:
//The processor mode should be superviser mode.
DisableInterrupt();
#if (LCD_XSIZE<64)
while((rLCDCON1>>22)<=1); // if x<64
#else
while((rLCDCON1>>22)==0); // if x>64
#endif
addr=(U32)frameBuffer256+(vx/1)+vy*(SCR_XSIZE/1);
rLCDSADDR1= (0x3<<27) | ( (addr>>22)<<21 ) | M5D(addr>>1);
// 256-color, LCDBANK, LCDBASEU
rLCDSADDR2= M5D(((addr+(SCR_XSIZE*LCD_YSIZE))>>1)) | (MVAL<<21);
EnableInterrupt();
break;
}
*/
}
void Lcd_PowerReset(void)
{
U8 i;
// rPDATC = ( rPDATC | 3<<4 ); //crtl=1,adj=1
for(i=0;i<1;i++);
// rPDATC = ( rPDATC & (~(1<<5)) ); //ctrl=0
for(i=0;i<2;i++);
// rPDATC = ( rPDATC | 1<<5 ); //ctrl=1
for(i=0;i<1;i++);
// rPDATC = ( rPDATC & (~(1<<4)) ); //adj=0
}
void Lcd_PowerUp(void)
{
U8 i;
// rPDATC = ( rPDATC | 2<<4 ); //ctrl=1,adj=0
for(i=0;i<2;i++);
// rPDATC = ( rPDATC | 1<<4 ); //adj=1
for(i=0;i<1;i++);
// rPDATC = ( rPDATC & (~(1<<4)) ); //adj=0
for(i=0;i<2;i++);
}
//*****************************************************************************
void MoveViewPort(int depth)
{
int vx=0,vy=0,vd;
vd=(depth==1)*16+(depth==4)*8+(depth==16)*4+(depth==256)*2;
while(1)
{
switch(Uart_Getch())
{
case 'i':
if(vy>=vd)vy-=vd;
break;
case 'j':
if(vx>=vd)vx-=vd;
break;
case 'k':
if(vx<=SCR_XSIZE-LCD_XSIZE-vd)vx+=vd;
break;
case 'm':
if(vy<=(SCR_YSIZE-LCD_YSIZE-vd))vy+=vd;
break;
case '\r':
return;
default:
break;
}
Uart_Printf("vx=%3d,vy=%3d\n",vx,vy);
Lcd_MoveViewPort(vx,vy,depth);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -