LCD显示屏UI界面

LCD显示屏UI界面

硬件:德飞莱STM32开发板M3S(STM32F103ZE)
    LCD控制器 ILI9325 LCD屏幕大小320×240
软件:keil uVision4
固件库:STM32F10x_StdPeriph_Lib_V3.5.0
uCOSIII版本:Release V3.02.00 (2011/08/01)

该篇文章承接上一篇完成的ucosiii移植工作,原计划是使用ucgui编写个类似MP4功能的显示界面,但是未能找到足够的学习资料,并在尝试emwin未果后,索性自己编写一个简单的UI界面程序,目前实现的功能比较原始,代码还有不小改进空间。

1.实现的功能

目前编写完成的代码,在LCD基本驱动的基础上,完成图标显示,背景显示,图标滚动,图标点击功能,类似于MP4主页,效果如下图。
这里写图片描述
其他页面未填充具体内容,点击任意图标后如下图
这里写图片描述
图中方框用于返回主页面

2. UI程序结构

程序的层次,结构比较简单,没有全面考虑,可能架构方面比较乱,用框图进行示意
这里写图片描述
如图所示,每个页面在代码中被描述为单独的页,页的属性如下

typedef struct page
{
    bui_block_t *blocklist;     //块属性结构体链表
    uint8_t     dflag;          //回收页面标志
    uint16_t    xnum;           //滚动数值
    uint16_t    ynum;
    int16_t     MAXXPOS;        //页面最大x坐标
    int16_t     MAXYPOS;        //页面最大y坐标
    uint8_t     sdir;           //滚动方向
    uint8_t     ISSET;          //页面最大坐标是否设置
}bui_page;

blocklist用于指向该页面中所有块组成的链表,dflag用于标志该页面在页面切换时是否销毁。
目前该结构体只有这些属性,若果有功能的增加,该部分可能有所删减。
页用来描述页面,页面由不同的块组成,状态栏,图标等都作为页面的块。背景不作为块,只是单纯的显示作用,页面中的各个部件皆有块属性,如下

//项目属性结构体
typedef struct item
{
    uint16_t    lft2item;   //块左边界到项目距离
    uint16_t    top2item;   //块上边界到项目距离
    uint16_t    rit2item;   //块右边界到项目距离
    uint16_t    bot2item;   //块下边界到项目距离
    void (*onclick_fun)(void *); //点击响应函数指针
    void (*scroll_fun)(void *); //滚动处理函数指针
}bui_item_t;

//块属性结构体
typedef struct block
{
    int16_t     x_tl;       //块左上角x坐标       
    int16_t     y_tl;       //块左上角y坐标
    int16_t     x_br;       //块右下角x坐标
    int16_t     y_br;       //块右下角y坐标
    uint8_t     num;        //块序号
    bui_item_t  item;       //项目属性
    struct block *next;
}bui_block_t;

给个块的属性在页面创建时人为赋值初始化,块包含项目属性结构体,项目中有该块(或项目)的点击及滚动处理函数。
状态栏也是一个块,用于显示信号、电量、时间等(缺乏硬件支持,目前是个摆设,但是有函数接口)。
UI的其他部件应当包含块结构体指针,用于显示定位及实现触屏功能。

3.图标

用于描述图标的属性结构体如下

typedef struct icon_attr
{
    int16_t x_ori;      //原始x坐标
    int16_t y_ori;      //原始y坐标
    int16_t xc_tl;      //当前左上角x坐标
    int16_t yc_tl;      //当前左上角y坐标
    int16_t xp_tl;      //上一次左上角x坐标
    int16_t yp_tl;      //上一次左上角y坐标
    int16_t xc_br;      //当前右下角x坐标
    int16_t yc_br;      //当前右下角y坐标
    int16_t xp_br;      //上一次右下角x坐标
    int16_t yp_br;      //上一次右下角y坐标
    uint8_t FLAG;       //滚动方向标志
    uint16_t width;     //图标宽度
    uint16_t height;    //图标高度
    bui_block_t *block;
    const unsigned char *icon;      //图标数据数组指针
    struct icon_attr *next_icon;   
}icon_t;

该结构体中参数多数用来定位,block为图标的块属性,icon指向图标的颜色数据数组(该数组用工具软件通过图片生成)。本UI中只支持一个图标链表,用于主页图标的显示。
图标的滚动原理并不复杂,在发生滚动之后,调用图标块属性指针指向的项目结构体中的滚动处理函数,重新定位图标的坐标,之后先将上次图标位置的图像替换为背景,之后重新绘制图标即可。但是这种方式在屏幕刷新率较低的情况下容易造成图标的闪烁。因此在替换图标为背景时仅替换其中一部分。

4.背景

背景采用的是图片平铺的方式显示,因为UI编写过程中暂未实现文件系统的支持,所以背景图片采用和图标一样的数组方式固定到程序中,采用一张完整图片将耗费大量存储资源,所以采用较小图片平铺显示方式完成背景的显示。只写了两个函数

void BUI_SetBkGround(const unsigned char *bk,uint16_t width,uint16_t height);
/*该函数用于设置背景图参数*/
void BUI_DrawBkGroundAtPos(int16_t x_tl,int16_t y_tl,int16_t x_br,int16_t y_br);
/*该函数用于在固定范围内绘制背景图*/

5.其他

该UI中驱动仅实现了画点,线,矩形,颜色填充等简单功能,LCD的初始化另由其他驱动文件实现,UI中驱动接口用了类似emwin的接口实现方式。触摸屏的功能由触屏驱动实现,未在UI中包含触屏操作。
触屏操作的函数接口由page提供,发生触屏操作后,调用page中的函数接口,page遍历当前page中所有的块,调用块中项目的触屏操作函数进行处理。

void BUI_Click(uint16_t xpos,uint16_t ypos)
{
    bui_block_t *tmp;
    onclick_args args;

    if(*pcurrentpage == NULL)
        return ;

    tmp = (*pcurrentpage)->blocklist;
    args.xpos = xpos;
    args.ypos = ypos;

    //遍历块属性结构体链表,找到点击点所在块
    //调用块中项目结构体的点击处理函数(测试用)
    while(tmp->next!=NULL){
        if((tmp->next->x_tl<xpos && tmp->next->x_br>xpos) && \
            (tmp->next->y_tl<ypos && tmp->next->y_br>ypos)){
            tmp->next->item.onclick_fun(&args);
            return ;    
        }   
        tmp = tmp->next;    
    }       
}

如以上代码所示,在点击处理函数中,根据点击点的坐标判断在哪个块的范围内,之后调用该块中项目的点击处理函数进行处理。
滚动处理与其类似。

注:当前程序在块创建过多时会卡死,一是怀疑堆内存空间不足,二是函数栈的问题。由于没有jtag等工具,无法确认,从程序上未看出问题。

从效果上来看,该UI离可用还有相当大的差距,后续如果仍对其有兴趣的话可能会陆续添加字体支持,更多部件,找出程序的BUG。该UI的代码及整个项目文件可从下面链接获得http://download.csdn.net/detail/u010376646/9920136

今后重点会在linux平台驱动方面。

  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值