初级会员

- 积分
- 167
- 金钱
- 167
- 注册时间
- 2019-10-19
- 在线时间
- 25 小时
|
从咸鱼上买了一块二手的阿波罗767核心板,根据自己的需求制作了一块底板,看了原子的767综合历程,非常喜欢它的滑屏。但原子的例程是竖屏的而本人需要横屏显示,在原子论坛上搜索相关修改成横屏的帖子,大家都在说因为要改很多东西,而放弃。其实有人想改成横屏只是想要它的横向滑
屏效果,至于里面的功能大部分是根据自己的需要来做删减。
我在修改成横屏的过程中摸索了1个多星期,今天终于想通了它的显示原理并修改成功!现在把修改过程做个简单的介绍。由于本人是业余爱好者,
所学专业并非电子或软件而是景观设计专业,接触STM也就大半年时间,在讲述过程中所用的术语可能不标准,请大家不要喷!
本例程修改是以RGB屏800X400为例,其他分辨大家自己参考修改。
第一次修改成横屏的时候是下面显示的样子,估计很多人改成横屏基本都这样!
而且左右滑屏时,滑屏区域是上下移动,与原效果差距太大,且显示界面是乱码。对此我仔细读究原子的代码,主要看SPB.C(这个代码主要设置
显示图标的各个参数)及SPBLCD.C (这个代码用来滑屏显示)。
第一步首先要修改的是void LCD_Init(void)初始化函数中的显示方向,大概在1836行,把LCD_Display_Dir(0)改为LCD_Display_Dir(1);这是最基本的,大家都会改这个。
当然改完后直接编译下载就成了上图的效果。对此我把原子SPBLCD.C中的画点函数一个个标识在它的竖向显示背景图片中后发现它有如下规律。
/在指定位置画点.
//x,y:坐标
//color:颜色.
void slcd_draw_point(u16 x,u16 y,u16 color)
{
if(lcdltdc.pwidth)x=spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2-x-1;
sramlcdbuf[y+x*spbdev.spbheight]=color;
}
图片中的color指针数组的0点是在右上角,从右上角往下递增,从右往左递增。如果把这张图片逆时针旋转90°刚好是RGB屏的扫描方向,因为RGB屏的扫描方式以
设备界面固定不变的,例如800X480的屏,它以800作为X轴,480作为Y轴,扫描是从左往右,从上到下,那么我们要显示的像素指针数组也要与它相适应,也要
从左往右曾大,从上到下增大,如果不一一对应,读出来的像素点就错误了。
那么如果把图片改为横向显示且是我们所用的尺寸大小其color指针数组如下图所示
color指针数组与RGB屏扫面方向是一致的,但在调用LTDC_Color_Fill()函数时会出现一个问题,那就是LTDC_Color_Fill()使用DMA传输,而
在传输过程中color指针会一直递增当它超过我们屏幕显示区域后它不能自动换行,举例说明一下,正常情况下我们要的显示效果是,如果滑屏后
传递过来的X坐标值,那么我要显示应该是从color[x]处开始读取它的像素数据,读到color[屏幕宽度]后,color指针数组要跳到下行的X处,但DMA传进去的
只是color[x]的首地址,之后它的地址会一直递增而不会跳到下行X处的位置,因此我把SPBLCD.C中void slcd_frame_show(u32 x)函数做了 如下修改,
//显示一帧,即启动一次spi到lcd的显示.
//x:坐标偏移量
void slcd_frame_show(u32 x)
{
if(lcdltdc.pwidth)
{
// x=spbdev.spbwidth*(SPB_PAGE_NUM-1)+spbdev.spbahwidth*2-x;
// LTDC_Color_Fill(0,spbdev.stabarheight,spbdev.spbwidth-1,spbdev.stabarheight+spbdev.spbheight-1,sramlcdbuf+x*spbdev.spbheight);
u16 i;
for(i=0;i<spbdev.spbheight;i++)
{
LTDC_Color_Fill(0,spbdev.stabarheight+i,spbdev.spbwidth-1,spbdev.stabarheight+i,sramlcdbuf+x+i*(spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2));
}
每次传递一行参数,一共用传递spbdev.spbheight次,spbdev.spbheight是滑屏显示的高度,这样就解决了指针不会跳行的问题(这是我自己的理解,如果大家有更好办法可以跟一下贴)
因为原子用竖屏传递参数不存在这问题,所以它只要给了color的首地址,首地址一直递增后自动回到下一行的首地址(这跟它的图片像素*color数组排列有关)。
下面我把修改过的地方一一贴出来,大家可以根据自己的屏幕大小自行参考修改
在SPB.C中需要修改的地方
第一处
}else if(lcddev.width==800) //对于800*1280的LCD屏幕//对于800*48的RGB屏幕
{
// icowidth=110;
// micoyoff=18;
// lcdtype=5;
// icoindex=2;
// spbdev.stabarheight=30;
// spbdev.spbheight=1090;
// spbdev.spbwidth =800;
// spbdev.spbfontsize=16;
icowidth=110;
micoyoff=10;
lcdtype=5;
icoindex=2;
spbdev.stabarheight=30;
spbdev.spbheight=300; //我自己定义的滑屏的高度
spbdev.spbwidth =800;
spbdev.spbfontsize=16;
}
第二处----(只改了红色字体处,上下图标的间距,根据自己需要修改)
for(i=0;i<SPB_ICOS_NUM;i++)
{
spbdev.icos.width=icowidth; //必须 等于图片的宽度尺寸
spbdev.icos.height=icowidth+spbdev.spbfontsize+spbdev.spbfontsize/4;
spbdev.icos.x=icoxpit/2+(i%4)*(icowidth+icoxpit)+(i/8)*spbdev.spbwidth;
spbdev.icos.y=spbdev.stabarheight+10+((i%8)/4)*(spbdev.icos.height+15);
spbdev.icos.path=(u8*)spb_icos_path_tbl[icoindex];
spbdev.icos.name=(u8*)icos_name_tbl[gui_phy.language];
}
在SPBLCD.C中需要修改的地方
//在指定位置画点.
//x,y:坐标
//color:颜色.
void slcd_draw_point(u16 x,u16 y,u16 color)
{
if(lcdltdc.pwidth&&lcdltdc.dir==0)
{
x=spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2-x-1;
sramlcdbuf[y+x*spbdev.spbheight]=color;
}else if(lcdltdc.pwidth&&lcdltdc.dir==1)
{
sramlcdbuf[x+y*(spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2)]=color;
}
}
//读取指定位置点的颜色值
//x,y:坐标
//返回值:颜色
u16 slcd_read_point(u16 x,u16 y)
{
if(lcdltdc.pwidth&&lcdltdc.dir==0)
{
x=spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2-x-1;
return sramlcdbuf[y+x*spbdev.spbheight];
}
else if(lcdltdc.pwidth&&lcdltdc.dir==1)
{
return sramlcdbuf[x+y*(spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2)];
}
}
其实这两个函数改不改都没关系,因为滑屏中并没有使用到他们。
最后一个修改在
//显示一帧,即启动一次spi到lcd的显示.
//x:坐标偏移量
void slcd_frame_show(u32 x)
{
if(lcdltdc.pwidth)
{
// x=spbdev.spbwidth*(SPB_PAGE_NUM-1)+spbdev.spbahwidth*2-x;
// LTDC_Color_Fill(0,spbdev.stabarheight,spbdev.spbwidth-1,spbdev.stabarheight+spbdev.spbheight-1,sramlcdbuf+x*spbdev.spbheight);
u16 i;
for(i=0;i<spbdev.spbheight;i++)
{
LTDC_Color_Fill(0,spbdev.stabarheight+i,spbdev.spbwidth-1,spbdev.stabarheight+i,sramlcdbuf+x+i*(spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2));
}
}else
改完后,做一张横向显示的图片,我用的是RGB800X400根据spbdev.spbwidth*SPB_PAGE_NUM+spbdev.spbahwidth*2算得X轴长度为2800
Y轴我定义了300,所以图片像素为2800X300,然后保存到你代码要求的相应文件夹内。
最后就是这样的显示效果!
|
|