原子哥,我遇到一个困惑,情况如下:
就是在TFTLCD开窗口显示数据时,我按照你的方式写的程序,要完成的功能是:
1.在指定区域内填充指定颜 {MOD}
2.写字符
因为你说过开窗写数据可以提高写入速度,可是这样问题就来了。
问题一:在指定区域内填充指定颜 {MOD}时竖屏时一切正常,但是,横屏时就出问题了。(因为填充要么方向不对,要么坐标不对。。)
分析:我想了好久,也找了好久,还是没想出来,最后在论坛的
http://www.openedv.com/posts/list/7477.htm#38275找到了答案,原来我的问题出在坐标设置上,分析如下
就改了我的程序如下:
/***********************************************************
* 函数名称:LCD_SetCursor
* 函数功能:LCD设置坐标函数
* 入口参数: x( 水平坐标 )、y( 垂直坐标 )
* 出口参数:无
***********************************************************/
__inline void LCD_SetCursor( u16 x, u16 y )
{
#if USE_HORIZONTAL==1 // 使用横屏
LCD_WriteREG(R32, y); // 设置GRAM的x坐标
LCD_WriteREG(R33, 319-x); // 设置GRAM的y坐标
#else
LCD_WriteREG( R32, x ); // 设置GRAM的x坐标
LCD_WriteREG( R33, y ); // 设置GRAM的y坐标
#endif
}
/**********************************************************
* 函数名称:LCD_SetWindowSize
* 函数功能:设置窗口大小(edx-stx)*(edy-sty)
* 入口参数: stx: 开始x坐标
* edx: 结束x坐标
* sty: 开始y坐标
* edy: 结束y坐标
* 出口参数:无
***********************************************************/
void LCD_SetWindowSize( u16 stx, u16 edx, u16 sty, u16 edy )
{
#if USE_HORIZONTAL==1 // 横屏
LCD_WriteREG( R80, sty ); // LCD写寄存器函数
LCD_WriteREG( R81, edy ); // LCD写寄存器函数
LCD_WriteREG( R82, 319-edx ); // LCD写寄存器函数
LCD_WriteREG( R83, 319-stx ); // LCD写寄存器函数
#else
LCD_WriteREG( R80, stx ); // LCD写寄存器函数
LCD_WriteREG( R81, edx ); // LCD写寄存器函数
LCD_WriteREG( R82, sty ); // LCD写寄存器函数
LCD_WriteREG( R83, edy ); // LCD写寄存器函数
#endif
}
/***********************************************************
* 函数名称:LCD_Fill
* 函数功能:在指定区域内填充指定颜 {MOD}
* 入口参数: 区域大小
xend-xsta)*(yend-ysta)、c(颜 {MOD})
* 出口参数:无
***********************************************************/
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{
u16 i,j;
LCD_SetWindowSize( xsta, xend, ysta, yend );// 设置窗口大小
LCD_SetCursor(xsta,ysta); //设置光标位置
LCD_WriteCom(R34); //开始写入GRAM
#if USE_HORIZONTAL==1 // 使用横屏
for(i=0;i<(xend-xsta)+1;i++)
{
for(j=0;j<(yend-ysta)+1;j++)LCD_WriteData(color);//填充颜 {MOD}
}
#else
for(i=0;i<(yend-ysta)+1;i++)
{
for(j=0;j<(xend-xsta)+1;j++)LCD_WriteData(color);////填充颜 {MOD}
}
#endif
LCD_SetWindowSize( 0x0000, LCD_W, 0x0000, LCD_H );//恢复窗体大小
}
把在指定区域内填充指定颜 {MOD}的问题解决。可是还有问题。
问题二: 开窗口 写字符时竖屏一切OK,问题还是出在横屏显示,横屏显示时叠加方式显示字符正常,可是不叠加方式就出问题了,
还是老办法去想、去找,最后还是没解决(不叠加方式显示要么是乱码、要么是显示字符方向不对),急啊!后来没办法只能重取模来解决。
就重取模:
// ------------------ 常用ASCII表字模的数据表 ------------------ //
// 码表从0x20~0x7e
// 取模软件:PCtoLCD2002 //
// 取模方式:阴码,逐列式,逆向,文字垂直翻转
// 大小:16*8
// -------------------------------------------------------------- //
。。。。。。。数据
改写程序如下:
/**********************************************************
* 函数名称:LCD_ShowChar
* 函数功能:在指定位置显示一个字符
* 入口参数: x : 0~234
* y : 0~308
* Char: 要显示的字符:" "--->"~"
* mode: 叠加方式(1)还是非叠加方式(0)
* c : 字体颜 {MOD}
* 出口参数:无
***********************************************************/
void LCD_ShowChar(u16 x,u16 y,u8 Char,u8 mode, u16 c )
{
u8 temp;
u8 pos,t;
if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return;
LCD_SetWindowSize( x, (x+LCD_FONT_W-1), y, (y+LCD_FONT_H-1) );// 开辟窗口写数据
LCD_SetCursor(x,y); // 设置光标位置
LCD_WriteCom( R34 );// RAMdata 寄存器
Char=Char-' ';//得到偏移后的值
#if USE_HORIZONTAL==1 // 横屏
if(!mode)//非叠加方式
{
for(pos=0;pos<(LCD_FONT_H);pos++)
{
temp=asc1_1608[Char][15-pos]; //调用1608字体
for(t=0;t<(LCD_FONT_W);t++)
{
if
(temp&0x80)
{
LCD_WriteData( c );
}else LCD_WriteData( BACK_COLOR );
temp<<=1;
}
}
}
#else
if(!mode)//非叠加方式
{
for(pos=0;pos<(LCD_FONT_H);pos++)
{
temp=asc2_1608[Char][pos]; //调用1608字体
for(t=0;t<(LCD_FONT_W);t++)
{
if(temp&0x01)
{
LCD_WriteData( c );
}else LCD_WriteData( BACK_COLOR );
temp>>=1;
}
}
}
#endif
else//叠加方式 叠加方式显示多用于在显示的图片上再显示字符
{
for(pos=0;pos<LCD_FONT_H;pos++)
{
temp=asc2_1608[Char][pos]; //调用1608字体
for(t=0;t<LCD_FONT_W;t++)
{
if(temp&0x01)LCD_DrawPoint(x+t,y+pos,c);//画一个点
temp>>=1;
}
}
}
LCD_SetWindowSize( 0x0000, LCD_W, 0x0000, LCD_H );//恢复窗体大小
}
上面在处理不叠加方式显示时横竖屏问题上用不同的取模数据和不同的扫描方式,但是叠加方式我还是没解决,只能共用一个取模数据和同种画点方法;
这样虽然解决了开窗显示字符问题,但是总感觉这样好浪费资源,不好,所以原子哥或者各位高手能给小弟指引一条明路,运用其他方法,在下不胜感激
#define LCD_WIDTH 320
#define LCD_HEIGHT 240
void LCD_CreatWindows(u16 sx,u16 sy,u16 width,u16 height)
{
u16 ex = sx + width-1;
u16 ey = sy + height-1;
#ifdef vertical
#ifdef __h1__
LCD_WriteReg(R80,sx);
LCD_WriteReg(R81,ex);
LCD_WriteReg(R82,sy);
LCD_WriteReg(R83,ey);
LCD_WriteReg(R32,sx);
LCD_WriteReg(R33,sy);
#else
LCD_WriteReg(R80,LCD_HEIGHT-1-ex);
LCD_WriteReg(R81,LCD_HEIGHT-1-sx);
LCD_WriteReg(R82,LCD_WIDTH-1-ey);
LCD_WriteReg(R83,LCD_WIDTH-1-sy);
LCD_WriteReg(R32,LCD_HEIGHT-1-sx);
LCD_WriteReg(R33,LCD_WIDTH-1-sy);
#endif
#else
#ifdef __h1__
LCD_WriteReg(R80,LCD_HEIGHT-1 - ey); //横屏也有2种方式,方式1
LCD_WriteReg(R81,LCD_HEIGHT-1 - sy);
LCD_WriteReg(R82,sx);
LCD_WriteReg(R83,ex);
LCD_WriteReg(R32,LCD_HEIGHT-1 - sy);
LCD_WriteReg(R33,sx);
#else
LCD_WriteReg(R80,sy); //横屏也有2种方式,方式2,在方式1的基础上旋转180度
LCD_WriteReg(R81,ey);
LCD_WriteReg(R82,LCD_WIDTH-1-ex);
LCD_WriteReg(R83,LCD_WIDTH-1-sx);
LCD_WriteReg(R32,sy);
LCD_WriteReg(R33,LCD_WIDTH-1-sx);
#endif
#endif
LCD_WR_REG(R34);//开始写入GRAM
}
在LCD初始化时,把寄存器3修改为这个,
#ifdef vertical
#ifdef __h1__
LCD_WriteReg(0x003,0x1030);
#else
LCD_WriteReg(0x003,0x1000);
#endif
#else
#ifdef __h1__
LCD_WriteReg(0x003,0x10a8); //控制扫描方向
#else
LCD_WriteReg(0x003,0x1098); //控制扫描方向
#endif
#endif
其他的就按照你之前写的来做就行了,希望能帮到你
一周热门 更多>