10874|3

77

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

基于TI图形驱动库的嵌入式图形界面设计 [复制链接]

基于TI图形驱动库的嵌入式图形界面设计

摘要:为加快嵌入式图形界面开发,TIStellaris平台(基于arm cortex m3内核)上推出了图形驱动库(Graphics Library)。本文在介绍TI图形驱动库特点的基础上给出了基于SSD1963 LCD控制器和TSC2046 触摸屏控制器在LM3S6911上的移植实例。通过分析图形驱动库的运行机制,给出了一种在Stellaris平台上使用TI图形驱动库进行嵌入式图形界面设计的通用方法。

关键字:嵌入式图形界面,图形驱动库,Stellarisarm,cortex m3

embedded Graphical Interface Design based on TI's Graphics Library

abstract:To speed up the development of embedded Graphical InterfaceI,TI introduces it's graphics library to stellaris platform(a series of mcu based on cortex m3,a type of arm core).This paper provides a example that transplants the the graphics library to the LM3S6911 microcontroller based on the SSD1963 LCD controller and the TSC2046 touchscreen controller. Finally a generic method will be provided to design embedded Graphical Interface with TI''s graphics library By analyzing how the graphics library runs.

Keyword: embedded Graphical Interface, graphics library, Stellarisarm,cortex m3

1. 引言

  当前,嵌入式系统正向智能化,人性化方向发展,一个界面友好,简单易用的图形用户界面已经成为很多嵌入式系统必不可少的重要组成部分。但是图形界面的设计往往要花费设计者大量的时间和精力,对产品尽快的推向市场造成一定的阻力。所以现在很多半导体厂商在推出一款处理器时,也会推出和处理器配套的软件支持。StellarisTI收购Luminary Micro后推出的基于arm cortex m3内核的一系列MCU产品。为简化设计者使用Stellaris设计产品的时间。TI推出了一系列的驱动库。其中就包括图形驱动库(Graphics Library)。使用TI提供的图形驱动,设计者可以快速的设计出一个界面友好,简单易用的图形用户界面。TI提供的图形驱动库除了必须用汇编编写的地方外,所有代码完全用C编写,容易理解,方便移植到任何Stellaris处理器上。并可以支持任何大小的图形显示器。它给使用图形LCD的应用程序提供了独立于硬件的图形用户接口。开发人员只需要补充底层硬件驱动程序,就可以让图形化的应用程序在Stellaris上运行起来。

2 图形驱动库架构

从软件的角度来看,TI提供的图形驱动库采用了分层的设计方法,分别为:显示驱动层,图形基元层,控件层,越上层的调用均是建立在下层功能的基础之上以实现更为复杂、强大的功能。每一层在应用中可以单独调用。

图形驱动库三层架构

2.1 显示驱动层

显示驱动层(Display Driver layer)直接和硬件相关,设计者必须跟具自己硬件的实际情况编写层驱动函数,可实现在显示器上画点,画线,画填充矩形等操作。为结构化底层驱动程序,TI提供了tDisplayer这个结构体。设计者只需要补充这个结构体就可以完成显示驱动层的补充工作。

2.2图形基元层

   图形基元层(Graphics Primitives layer)提供了一系列低级的绘制操作,其中包括了画线,画圆,画文本,和画位图图像。同时在这一层也提供了一种在屏外缓冲区(off-screen buffer)绘制的方法,允许先把图像数据绘制到屏外缓冲区,最后一次性的更新到LCD显示器上。

2.3控件层

控件(Widget)是一种集成许多图形基元的一个实体。它用来响应使用者的输入。一个典型的控件就是屏上一个按钮。当它被按下的时候可以执行一个设计者定义的动作。控件层(Widget Framework layer)提供了一种可以处理控件消息的方法。每一个控件都有其消息的处理者来响应消息。如WIDGET_MSG_PAINT这个消息可请求控件把自身绘制到显示屏上。

  控件层被组织成了一个树型的结构,控件可以从这个树中被动态的添加和移出。控件可以在程序运行时使用各种功能函数创建,也可以在编译时使用全局结构体来定义。

3图形驱动库驱动程序开发

3.1显示驱动的编写

TI的图形驱动库为设计者提供了tDisplay这样一个结构体。其定义如下:typedef struct

{

 //这个结构体的大小 

    long lSize;

//指向驱动层显示数据指针

 void *pvDisplayData;

//显示屏宽度(以像素点为单位)

unsigned short usWidth;

//显示屏高度(以像素点为单位)

 unsigned short usHeight;

//指向在屏上画点的函数指针

    void (*pfnPixelDraw)(void *pvDisplayData, long lX, long lY,

                         unsigned long ulValue);

//指向在屏上画序列点的函数指针

    void (*pfnPixelDrawMultiple)(void *pvDisplayData, long lX, long lY,

                                 long lX0, long lCount, long lBPP,

                                 const unsigned char *pucData,

                                 const unsigned char *pucPalette);

//指向在屏上画水平线的函数指针

     void (*pfnLineDrawH)(void *pvDisplayData, long lX1, long lX2, long lY,  unsigned long ulValue);

//指向在屏上画竖直线的函数指针

    void (*pfnLineDrawV)(void *pvDisplayData, long lX, long lY1, long lY2, unsigned long ulValue);

//指向在屏上画填充矩形的函数指针

     void (*pfnRectFill)(void *pvDisplayData, const tRectangle *pRect,

                        unsigned long ulValue);

//指向从RGB888向显示屏指定的颜色格式转换的函数指针

     unsigned long (*pfnColorTranslate)(void *pvDisplayData,

                                       unsigned long ulValue);

//指向更新缓冲区数据到显示屏的函数指针。

     void (*pfnFlush)(void *pvDisplayData);

}

tDisplay;

可见,设计者需要根据自己的硬件完在上述函数。然后传递函数指针到这个结构体里。

3.1.1  LCD控制器和MCU硬件连接

笔者使用的就是SSD1963来驱动一块3.5英寸的LCD显示器。SSD1963是一个自带1215KB帧缓冲的LCD控制器,支持864X48024bpp的图形显示内容。可以以不同的总宽度来和MCU通信。在这里我们选择8位总线宽度。MCU选用LM3S6911.一款运行频率可达50M,带以太网控制器的Stellaris处理器。MCULCD控制器的连接如下:

3.1.2 LCD驱动函数的编写

为加强代码的可读性,和在工程中的可移植性。笔者建立了320x240_lcd_ssd1963.h320x240_lcd_ssd1963.c这个两个文件。

320x240_lcd_ssd1963.这个文件中主要完成画点,画线,画填充矩形等函数。并以这些函数补充了tDisplay这个结构体。驱动库所有的绘制工作最终都以tDisplay类型的结构体中的函数来实现。由于这些函数又都可以通调用画点的函数来实现。所以笔者在此重点讲述画点函数的实现。其代码如下:

void LCDPixelDraw(void *pvDisplayData,long lX,long lY, unsigned long ulValue)

{

 //设置x坐标 

 LCD_WRITE_CMD(0x2A);

LCD_WRITE_DATA((lX>>8)&0xff);     

LCD_WRITE_DATA(lX);

LCD_WRITE_DATA(((lX)>>8)&0xff);     

LCD_WRITE_DATA(lX);

//设置y坐标 

 LCD_WRITE_CMD(0x2b);

LCD_WRITE_DATA((lY>>8)&0xff);     

LCD_WRITE_DATA(lY);

LCD_WRITE_DATA((lY>>8)&0xff);     

LCD_WRITE_DATA(lY);              

 LCD_WRITE_CMD(0x2c); //准备写数据   

 LCD_WRITE_COLOR(ulValue);//写入颜色数据

}

pvDisplayData是一个指向显示buffer的指针,于由我们是直接对LCD屏进行操作,故没有使用,参数lXlY分别为要绘制的像素点在屏上的x坐标和y坐标。ulValue为要写入的颜色数据。这个函数便实现了在以(lX,lY)为坐标的LCD屏上显示一个颜色为ulValue的像素点。

其中LCD_WRITE_CMDLCD_WRITE_DATALCD_WRITE_COLOR分别为写命令,写数据,和写颜色数据函数。为加快LCD耍屏速度,这三个函数都被优化成宏,内联到代码之中。例如LCD_WRITE_CMD的定义如下:

//写命令

#define LCD_WRITE_CMD(c)             \

{                                    \

  HWREG(RS_ADDR)=0x00;              \                     

  HWREG(DATA_ADDR)=c;               \

HWREG(WR_ADDR)=0x00;             \                                 

  HWREG(WR_ADDR)=0xff;              \

}

完成驱动函数的编写后,我们需要定义一个tDisplay类型的结构体并跟具硬件的实际情况和做好了的绘制函数来补充这个结构体。如下:

const tDisplay MyDisplay=

{

 .lSize=sizeof(tDisplay),//结构体大小

 .pvDisplayData=0,//驱动层显示数据指针

 .usWidth=320, // LCD 显示像素宽度

 .usHeight=240,// LCD 显示像素高度

 .pfnPixelDraw=LCDPixelDraw,//画点

 .pfnPixelDrawMultiple=LCDPixelDrawMultiple, //画序列点

 .pfnLineDrawH=LCDlineDrawH,//画水平线

 .pfnLineDrawV=LCDlineDrawV,//画竖直线

 .pfnRectFill=LCDRectFill,//画填充矩形

 .pfnColorTranslate=LCDColorTranslate,//传输颜色

 .pfnFlush=LCDFlush,//更新缓冲区数据到显示器

};

3.2触摸屏驱动代码的编写

在控件层中,传递给控件的消息必须要包含一个坐标,让驱动库知道这个消息应该传递给哪一个控件。坐标确认的一种方法就是使用触摸屏。在触摸屏的驱动之中我们要完成坐标的采集和消息的传递。触摸屏驱动程序可行驱动库传递三种消息

WIDGET_MSG_PTR_DOWN 触摸屏被按下消息

WIDGET_MSG_PTR_MOVE 触摸屏上滑动消息

WIDGET_MSG_PTR_UP   触摸屏上弹起消息

消息的传递通过WidgetPointerMessage()这个函数来完成。

当控件层收到消息后,并不是马上处理消息,而是把消息把在消息队列之中,只有调用了WidgetMessageQueueProcess()这个函数才开始处理消息。把显示数据更新到显示屏上。

3.2.1触摸屏控制器和MCU硬件连接

笔者使用的是TSC2046这一款触摸屏控制器,最高可配置成12位精度进行转换。可通过配置实现单端和差分方式的数据转换。在实际应用中笔者配置为12位差分转换方式。TSC2046检测到屏幕被按下时会通过PENIRQMCU申请中断。在中断中获取坐标,向驱动库传递消息。触摸屏控制器和MCU硬件连如下

3.2.2触摸屏驱动函数的编写

TSC2046为和MCU之间通讯采用了GPIO模拟SPI的方式实现。

读取坐标的过程如下:

在实际应用中,使用 getpoint()这个函数把采集到的LCD坐标值保存到g_sTouchXg_sTouchY这两个全局变量之中。根据MCU检测到的触摸屏不同状态向控件层传递不同的消息。消息传递有如下形式:

WidgetPointerMessage(WIDGET_MSG_PTR_DOWN,g_sTouchX,g_sTouchY);在主程序中调用WidgetMessageQueueProcess()来处理消息。

4图形驱动库嵌入式图形界面设计

图形界面的设计可从TI提供的三层结构之中任意一层开始。但是从控件层开始设计可设计出可控性和结构性更强的界面。在控件层整个工作过程中,通过tContext型的结构体出维护绘制的上下文,其定义如下:typedef struct

{

//结构体大小  

long lSize;

//指向驱动层显示结构的指针

    const tDisplay *pDisplay;

//屏幕显示区域大小

    tRectangle sClipRegion;

  //绘制前景颜色

      unsigned long ulForeground;

//绘制背景颜色

        unsigned long ulBackground;

//绘制字体     

const tFont *pFont;

}

tContext;

在使用驱动库之前,都要先初始化硬件,然后调用GrContextInit()来初始化绘制上下文。添加控件到控件树的根(WIDGET_ROOT)。具体代码如下:

  LCD_Init();//lcd初始化

  TouchScreenInit();//触摸屏初始化

  GrContextInit(&MyContext,&MyDisplay);//初始化绘制上下文

  WidgetPaint(WIDGET_ROOT);//绘制控件树的根

  WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sBackground);//添加背景控件到根

  WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sNext);//添加下一步按键到根

while(1)

{

WidgetMessageQueueProcess();//处理消息

}

以上代码便实现了在LCD屏上绘制显示背景,并添加执行下一步的控件显示到LCD屏上,当MCU检测到有触摸事件时,通过触摸屏驱动向控件层传递消息。当处理消息的时间,如果发送消息的坐标在这个控键显示的坐标范围内,则控间会接收到这个消息,并调用事先设置的函数,执行操作。

所有复杂的界面均可用此方法实现。以响应外部的输入,执行预订的操作。

5结论

 TI开发的基于Stellaris平台的图形驱动库功能强大,但简单易用。可以帮助设计人员在产品开发中快速方便的设计出漂亮美观,操作性强的图形界面。简化了设计流程,降低了设计成本。具有很强的实用价值。

参考文献

1. Stellaris® Graphics Library user guide.   Texas Instruments

2. Stellaris® LM3S6911 Microcontroller DATA SHEET.  Texas Instruments

3.SSD1963 product Preview.   SOLOMON SYSTECH SEMICONDUCTOR

4.TSC2046 low voltage i/0 touch screen controller.   Texas Instruments

  

最新回复

MARK MARK  详情 回复 发表于 2011-7-6 11:00
点赞 关注

回复
举报

2751

帖子

0

TA的资源

裸片初长成(初级)

沙发
 
mark
 
 

回复

2万

帖子

74

TA的资源

管理员

板凳
 

原帖由 tangguanglun 于 2011-4-27 18:25 发表 基于TI图形驱动库的嵌入式图形界面设计摘要:为加快嵌入式图形界面开发,TI在Stellaris平台(基于arm cortex m3内核)上推出了图形驱动库(Graphics Library)。本文在介绍TI图形驱动库特点的基础上 ...

 

楼主 请以附件形式上传图片 图片未显示出来 :)

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

4
 
MARK MARK
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表