TinyUI-LCD驱动对接

       TinyUI对于MCU是否集成LCD控制器都支持,但需要实现TinyUI定义的TUIFBInterface纯虚类接口,FB为frame buffer的缩写。该接口部分方法是否需要实现依赖于当前需要移植的MCU是否集成LCD控制器,如果集成了LCD控制器,则只需实现极少部分的方法,但是如果MCU未集成LCD控制器,则可能需要实现大部分的方法。

 

TinyUI定义的显示接口

TUIFBInterface.h

#ifndef __TUI_FB_INTERFACE__
#define __TUI_FB_INTERFACE__

#include <TUITypes.h>




class TUIFBInterface
{
public:
    /*********************************************************************************************************************
     @Function: readPoint
     @Description: 获取LCD某个像素的颜色值
                            1. 未集成LCD控制器的MCU重写该方法,若不支持,则返回false。
                            2. 集成LCD控制器的MCU不需要重写该方法
     @Param:
                    x: 待读取像素值的水平坐标
                    y: 待读取像素值的垂直坐标
                    color: 输出参数,返回该像素点的颜色值
     @Return:
                    true: 支持读取像素;false: 不支持读取像素
    ***********************************************************************************************************************/
    virtual bool readPoint(int32_t x, int32_t y, color_t* color) { return false; }

    /*********************************************************************************************************************
     @Function: drawPoint
     @Description: 在指定位置(x, y)绘制一个点
                            1. 未集成LCD控制器的MCU必须立即绘制。
                            2. 集成LCD控制器的MCU实现空方法即可。
     @Param:
                    x: 绘制点的水平坐标
                    y: 绘制点的垂直坐标
                    visibleX1: 水平绘制坐标左边界,当x小于该坐标部分将不绘制,未集成LCD控制器的MCU由底层实现
                    visibleY1: 垂直绘制坐标上边界,当y小于该坐标部分将不绘制,未集成LCD控制器的MCU由底层实现
                    visibleX2: 水平绘制坐标右边界,当x大于该坐标部分将不绘制,未集成LCD控制器的MCU由底层实现
                    visibleY2: 垂直绘制坐标下边界,当y大于该坐标部分将不绘制,未集成LCD控制器的MCU由底层实现
                    color: 绘制点的颜色
     @Return:
                    none
    ***********************************************************************************************************************/
    virtual void drawPoint(int32_t x, int32_t y, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color) = 0;

    /*********************************************************************************************************************
     @Function: drawLine
     @Description: 从指定位置(x1, y1)到(x2, y2)绘制一条直线
                            1. 未集成LCD控制器的MCU必须立即绘制。
                            2. 集成LCD控制器的MCU实现空方法即可。
     @Param:
                    x1: 绘制直线的水平起始坐标
                    y1: 绘制直线的垂直起始坐标
                    x2: 绘制直线的水平结束坐标
                    y2: 绘制直线的垂直结束坐标
                    visibleX1: 水平绘制坐标左边界,当x1或x2小于该坐标部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleY1: 垂直绘制坐标上边界,当y1或y2小于该坐标部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleX2: 水平绘制坐标右边界,当x1或x2大于该坐标部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleY2: 垂直绘制坐标下边界,当y1或y2大于该坐标部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    color: 绘制点的颜色
     @Return:
                    none
    ***********************************************************************************************************************/
    virtual void drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color) = 0;

    /*********************************************************************************************************************
     @Function: drawBuffer
     @Description: 从指定左上角位置(x,y)开始绘制一段内存数据
                            该内存数据按照从左到右,从上到下进行绘制,该内存数据可以为图片/字体或一个矩形区域数据
                            1. 未集成LCD控制器的MCU必须立即绘制。
                            2. 集成LCD控制器的MCU实现空方法即可。
     @Param:
                    x: 绘制点的左上角水平坐标
                    y: 绘制点的左上角垂直坐标
                    bufferWidth: 内存数据的宽度
                    bufferHeight: 内存数据的高度
                    visibleX1: 水平绘制坐标左边界,当x小于该坐标时将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleY1: 垂直绘制坐标上边界,当y小于该坐标时将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleX2: 水平绘制坐标右边界,当(x + bufferWidth - 1)大于该坐标的部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleY2: 垂直绘制坐标下边界,当(y + bufferHeight - 1)大于该坐标的部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    buffer: 内存数据(颜色数据),数据为大端模式
     @Return:
                    none
    ***********************************************************************************************************************/
    virtual void drawBuffer(int32_t x, int32_t y, uint32_t bufferWidth, uint32_t bufferHeight, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, const uint8_t* buffer) = 0;

    /*********************************************************************************************************************
     @Function: clear
     @Description: 从指定左上角位置(x,y)开始,使用指定颜色对一块矩形区域清除
                            1. 未集成LCD控制器的MCU必须立即绘制。
                            2. 集成LCD控制器的MCU实现空方法即可。
     @Param:
                    x: 绘制点的左上角水平坐标
                    y: 绘制点的左上角垂直坐标
                    width: 矩形区域的宽度
                    height: 矩形区域的高度
                    visibleX1: 水平绘制坐标左边界,当x小于该坐标时将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleY1: 垂直绘制坐标上边界,当y小于该坐标时将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleX2: 水平绘制坐标右边界,当(x + width - 1)大于该坐标的部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    visibleY2: 垂直绘制坐标下边界,当(y + height - 1)大于该坐标的部分将不会绘制,未集成LCD控制器的MCU由底层实现
                    color: 绘制点的颜色
     @Return:
                    none
    ***********************************************************************************************************************/
    virtual void clear(int32_t x, int32_t y, uint32_t width, uint32_t height, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color) = 0;

    /*********************************************************************************************************************
     @Function: getBPP
     @Description: 获取LCD像素深度,如16BPP(RGB565), 18BPP(RGB888)
     @Param:
                    none
     @Return:
                    像素深度,如16, 18, 24等
    ***********************************************************************************************************************/
    virtual uint8_t getBPP() = 0;

    /*********************************************************************************************************************
     @Function: getScreenWidth
     @Description: 获取LCD宽度(像素)
     @Param:
                    none
     @Return:
                    宽度值,如: 320, 800, 1920
    ***********************************************************************************************************************/
    virtual uint32_t getScreenWidth() = 0;

    /*********************************************************************************************************************
     @Function: getScreenHeight
     @Description: 获取LCD高度(像素)
     @Param:
                    none
     @Return:
                    宽度值,如: 240, 480, 1080
    ***********************************************************************************************************************/
    virtual uint32_t getScreenHeight() = 0;

    /*********************************************************************************************************************
     @Function: getFB
     @Description: 获取显存
                            1. 未集成LCD控制器的MCU返回nullptr
                            2. 成LCD控制器的MCU返回某一块内存首地址,内存大小 = LCD宽度 * LCD高度 * (像素深度 / 8)
     @Param:
                    none
     @Return:
                    内存地址
    ***********************************************************************************************************************/
    virtual uint8_t* getFB() = 0;

    /*********************************************************************************************************************
     @Function: submit
     @Description: GDI提交数据,代表GDI需要刷新一屏数据至LCD进行显示
                            1. 未集成LCD控制器的MCU可以执行一些收尾工作或实现空方法
                            2. 集成LCD控制器的MCU,此时必须完成窗口/层(双缓存切换),并准备好另一块缓存供GDI使用
     @Param:
                    buffer: GDI当前持有的显存
     @Return:
                    none
    ***********************************************************************************************************************/
    virtual void submit(uint8_t* buffer) = 0;
};


#endif // !__TUI_FB_INTERFACE__

 

集成LCD控制器的MCU

1. 必须实现的接口如下:

        1. drawPoint()

            当TinyUI调用该方法时,LCD驱动必须立即执行绘制点的操作。

        2. drawLine()

            当TinyUI调用该方法时,LCD驱动必须立即执行绘制线的操作。

        3. drawBuffer()

            当TinyUI调用该方法时,LCD驱动必须立即执行绘制小缓存的操作。该缓存可能是一个字符的位图,或其他小缓存,该缓存具有长和宽的特性。

        4. clear()

            当TinyUI调用该方法时,LCD驱动必须使用指定的颜色清除参数指定的矩形区域。

        5. getBPP()

            当TinyUI调用该方法时,LCD驱动返回当前LCD的像素深度,如16位、24位、32位等。

        6. getScreenWidth()

            当TinyUI调用该方法时,LCD驱动返回当前LCD的水平宽(像素)

        7. getScreenHeight()

            当TinyUI调用该方法时,LCD驱动返回当前LCD的垂直高(像素)

2. 可选实现方法

        1. readPoint()

            读取某一个像素点当前的颜色值,主要用于实现透明效果。

集成LCD控制器的MCU

1. 必须实现的接口

        1. getBPP()

            当TinyUI调用该方法时,LCD驱动返回当前LCD的像素深度,如16位、24位、32位等。

        2. getScreenWidth()

            当TinyUI调用该方法时,LCD驱动返回当前LCD的水平宽(像素)

        3. getScreenHeight()

            当TinyUI调用该方法时,LCD驱动返回当前LCD的垂直高(像素)

        4. getFB()

            一般情况下,集成了LCD控制器的MCU,外匹配的可用内存相对比较大,因为LCD控制器一般都会提供多个窗口或显示层,窗口或显示层即是我们通常所说的缓存概念,提高LCD刷新率。

           该方法主要用于获取显存,LCD驱动返回显存首地址即可。

        5. submit()

           该方法用于提交并显示当前显存内容,LCD驱动底层需执行响应显存的切换动作,并返回原有显存或另一个显存(多窗口或多显示层一般都设计双缓存)

 

移植示例

        本示例主要使用STM32F103为例进行演示,STM32F103未集成LCD控制器,而是使用FSMC接口控制ILI9341控制器对LCD进行控制,LCD分辨率为320x240。

        本示例中使用的LCD驱动使用了目前后台开发比较流行的依赖注入技术,移植过程中可以看到调用device_driver_autowired()获取某一个驱动,本示例的LCD驱动也是使用C语言编写的。

        移植步骤

        1. 创建UIDisplay.h

           1) 并包含TUIFBInterface.h

           2) 定义UIDisplay类,并继承自TUIFBInterface

ifndef __UI_DISPLAY_H__
#define __UI_DISPLAY_H__
#include "device_driver_ioc.h"
#include <TUIFBIntface.h>


class UIDisplay : public TUIFBInterface
{
public:
    UIDisplay();
    virtual ~UIDisplay();

/* 声明TUIFBInterface所有方法 */
public:
    bool readPoint(int32_t x, int32_t y, color_t* color);
    void drawPoint(int32_t x, int32_t y, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color);
    void drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color);
    void drawBuffer(int32_t x, int32_t y, uint32_t bufferWidth, uint32_t bufferHeight, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, const uint8_t* buffer);
    void clear(int32_t x, int32_t y, uint32_t width, uint32_t height, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color);
    uint8_t getBPP();
    uint32_t getScreenWidth();
    uint32_t getScreenHeight();
    uint8_t* getFB();
    void submit(uint8_t* buffer);

private:
    lcd_controller_t *ili9341 = nullptr; // ILI9341驱动对象
};

        2. 创建UIDisplay.cpp,并实现UIDisplay.h中的方法

#include <UIDisplay.h>


UIDisplay::UIDisplay()
{
    ili9341 = (lcd_controller_t *)device_driver_autowired(DDTYPE_LCD_CONTROLLER, DDID_LCD_CONTROLLER_ILI9341);
    ili9341->ops->open();
}

UIDisplay::~UIDisplay()
{
    ili9341->ops->close();
}

bool UIDisplay::readPoint(int32_t x, int32_t y, color_t* color)
{
    uint16_t c = 0;
    ili9341->ops->read_point(x, y, &c);

    *color = c;

    return true;
}

void UIDisplay::drawPoint(int32_t x, int32_t y, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color)
{
    ili9341->ops->draw_point(x, y, color);
}

void UIDisplay::drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color)
{
    ili9341->ops->draw_line(x1, y1, x2, y2, color);
}

void UIDisplay::drawBuffer(int32_t x, int32_t y, uint32_t bufferWidth, uint32_t bufferHeight, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, const uint8_t* buffer)
{
    ili9341->ops->draw_buffer(x, y, bufferWidth, bufferHeight, buffer);
}

void UIDisplay::clear(int32_t x, int32_t y, uint32_t width, uint32_t height, int32_t visibleX1, int32_t visibleY1, int32_t visibleX2, int32_t visibleY2, color_t color)
{
    ili9341->ops->clear(x, y, width, height, color);
}

uint8_t UIDisplay::getBPP()
{
    return ili9341->ops->get_bpp();
}

uint32_t UIDisplay::getScreenWidth()
{
    return ili9341->ops->get_width();
}

uint32_t UIDisplay::getScreenHeight()
{
    return ili9341->ops->get_height();
}

uint8_t* UIDisplay::getFB()
{
    return nullptr; // 无LCD控制器,返回nullptr即可
}

void UIDisplay::submit(uint8_t* buffer)
{
    // 无LCD控制器,空方法
}

 

向TinyUI注册LCD接口

        

UIDisplay *display = new UIDisplay();
LUIRegisterFBInterface(display);

 

模拟程序演示Button&ListView测试在STM32F103显示效果

 

第一行置顶,滚动到第10行,再回滚到第6行的效果

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneOnce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值