打开主菜单

谷雨文档中心 β

谷雨显示接口原理说明

Ghostyu讨论 | 贡献2018年12月18日 (二) 05:48的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

目录

1 简介

为方便对各显示设备进行操作,现将各显示设备驱动进行整合。在开发者层面,将保持接口统一,而在具本硬件相关的方面,将设备抽象为统一个接口,由上层使用。这样在添加新的显示设备时,只要将显示设备按统一接口规定实现抽象接口即可。在与显示设备通信接口方面,系统中也将其抽象为接口,开发者只要实现这些硬件接口即可实现与具本的显示设备进行通信。

在组织结构上,整个驱动分成四个部分。用户调用接口,字体,图片功能块,屏幕操作接口,硬件接口。在逻辑结构上,四个模块存在上下调用关系,如图下图结构框图所示。

2 用户调用接口

此小节将介绍用户调用接口相关内容,包括相关函数与结构体。它主要包含gui.c,gui_dispstr.c,gui_dispval.c,gui_drawBitmap.c文件。

2.1 显示上下文结构体GUI_CONTEXT

GUI_Context结构,记录着显示系统当前重要信息,包括位置,中英字体,颜色等。

 1 typedef struct
 2 {
 3   COLOR_INFO              colorInfo;        //背景色,前景色
 4   const  GUI_FONT*        pENFont;          //英文字体
 5   const  GUI_FONT*        pZHFont;          //中文字体(部分)
 6   int                     paddingLeft;      //距左边距离(单位相素)
 7   int                     lineSize;         //换行时,Y轴尺寸
 8   U16                     dispX;            //当前X 轴位置
 9   U16                     dispY;            //当前y 轴位置
10   U16                     xMax;             //x轴最大位置
11   U16                     yMax;             //y轴最大位置
12 }GUI_CONTEXT;

其中COLOR_INFO也是一个结构,只是将背景色与前景色放到一起而已。

1 //******************************************************************************
2 // Name : COLOR_INFO
3 //
4 // Brief : 
5 typedef struct
6 {
7   GUI_COLOR               ftColor;           //前景色
8   GUI_COLOR               bkColor;           //背景色
9 }COLOR_INFO;

中英文件字体结构将在字本与图片部分进行说明。

2.2 用户接口函数原型

函数原型列表
序号 原型 说明
1 void GUI_Init(void) 初始化整个显示系统,包括各变量与硬件
2 void GUI_SetColor(GUI_COLOR color) 设置显示前景色

color : 传入的前景色

3 void GUI_SetBkColor(GUI_COLOR color) 设置显示背景色

color : 传入的背景色

4 void GUI_Clear(void) 清屏(用背景色覆盖整个屏幕)
5 void GUI_GotoXY(U16 x, U16 y) 设置当前显示位置

x : x 轴位置

y : y轴位置

6 GUI_GotoX(U16 x) 设置当前x轴显示位置

x : x 轴位置

7 void GUI_GotoY(U16 y) 设置当前y轴显示位置

y : y轴位置

8 void GUI_DispChar(U16 c) 在当前位置显示指字的字符

c : 字符的ASCII码

9 void GUI_DispCharAt(U16 c, U16 x, U16 y) 在指定位置显示字符

c : 字符的ASCII码

x : x 位置

y : y 位置

10 void GUI_DispChars(U16 c, U16 cnt) 在当前位置显示cnt个字符

c : 字符的ASCII码

cnt : 个数

11 void GUI_DispString(const char *s) 在当前位置显示字符串

s : 指向字符串指针

12 void GUI_DispStringAt(const char*s ,U16 x, U16 y) 在指定位置显示字符串

s : 指向字符串指针

x : x 位置

y : y 位置

13 void GUI_DispNextLine(void) 回车换行
14 void GUI_DispDec(I32 v) 在当前位置显示10进制数据

v : 数值

15 void GUI_DispDecAt(I32 v, U16 x, U16 y) 在指定位置显示10进制数据

v : 数值

x : x位置

y : y位置

16 void GUI_DispHex (U32 v, U8 len) 在当前位置显示16进制数据

v : 数值

len : 显示数字长度,如果实际长度大于len,将以实际长度为准。

如果实际长度小于len,将补0,达到len长度。

17 void GUI_DispHexAt(U32 v, U16 x, U16 y, U8 len) 在指定位置显示16进制数据

v : 数值

x : x位置

y : y位置

len : 显示数字长度,如果实际长度大于len,将以实际长度为准。

如果实际长度小于len,将补0,达到len长度。

18 void GUI_DrawBitmap (const GUI_BITMAP * pBM, int x, int y) 在指定位置显示一张BMP格式图片

pBM : 指向BITMAP指针

x : x轴位置

y : y轴位置

3 字体图片

在显示驱动中,支持中文字体与英文字体。英文字库中只包含ASCII码32到127,中文字库中只包含使用的汉字。对字体信息使用,采用三个结构体,FONT_INFO,ZHFONT_INFO,GUI_FONT。(驱动中默认提供了Font4x6,Font8x8,Font8x16,Font12x24,FontZH16x16_simsum,FontZH24x24_simsum字体)

其FONT_INFO主要用于英文字体,描述字库的范围,及字体X轴大小等信息。其结构具本内容如下。

 1 //******************************************************************************
 2 // Name : FONT_MONO
 3 //
 4 // Brief : FONT 
 5 typedef struct {
 6   const U8  * pData;       //字库数据
 7   U16 FirstChar;           //起始字符
 8   U16 LastChar;            //最后字符
 9   
10   U8 XSize;                //字体X轴大小
11   U8 BytesPerLine;         //一行几个字节
12 } FONT_INFO;

ZHFONT_INFO用于汉字字体,描述字体X轴大小,及支持的汉字编码与字库数据对应表。其结构内容如下。

 1 //******************************************************************************
 2 // Name : ZHFont_Info
 3 //
 4 // Brief : 中文相关的结构。中文采用查表方法进行显示。{只要画出要使用的汉字即可}
 5 typedef struct
 6 {
 7   U16 code;        //GB2312 encode
 8   //U16 index;     //Index in table(编码位置代替此字段)
 9 }ZHFont_MAP;
10 
11 typedef struct
12 {
13   const U8  * pData;          //字库数据
14   const ZHFont_MAP* pMap;     //映射表
15   U8 XSize;                   //x轴大小
16   U8 BytesPerLine;            //每行字节数
17 }ZHFONT_INFO;

GUI_FONT结构整合FONT_INFO或ZHFONT_INFO,字体的Y轴尺寸,及相关函数指针(具体实现在FontMethod.c 或FontZHMethod.c)。

 1 typedef void FONT_DISPCHARDISTX(U16 c);
 2 typedef int  FONT_GETCHARDISTX(const GUI_FONT* pFont);
 3 typedef int FONT_ISINFONT(const GUI_FONT* pFont, U16 c);
 4 
 5 //******************************************************************************
 6 // Name : GUI_FONT
 7 //
 8 // Brief : FONT INFO STRUCT
 9 struct GUI_FONT{
10   FONT_DISPCHARDISTX* pfDispChar;               //显示字符函数指针
11   FONT_GETCHARDISTX*  pfGetCharDistX;           //返回字体X尺寸函数指针
12   FONT_ISINFONT*      pfIsInFont;               //检查字符是否在字库中
13   U8 YSize;                                     //y 轴尺寸
14   union 
15   {
16     const FONT_INFO   *pEn;                     
17     const ZHFONT_INFO *pZHGB2312;
18   } p;
19 };

在显示系统中也加入了图片数据显示。每个图片都通过GUI_BITMAP结构来构建。GUI_BITMAP结构如下。

 1 //******************************************************************************
 2 // Name : GUI_BITMAP
 3 //
 4 // Brief : BMP格式图片信息结构,
 5 typedef struct {
 6   U16 XSize;                      //图片X大小,单位相素
 7   U16 YSize;                      //图片Y大小,单位相素
 8   U16 BytesPerLine;               //每行字节数。XSize * (BitsPerPixel / 8 )
 9   U16 BitsPerPixel;               //每个相素点几位bits
10   const U8 * pData;               //指向图片数据
11   const GUI_PALETTE * pPal;       //暂不支持
12 } GUI_BITMAP;

例如,一个图片大小为240x73,每个相素点采有16位颜色深度显示。则GUI_BITMAP构建如下。

1 const GUI_BITMAP bmTest = {
2   240,                       // xSize
3   73,                        // ySize
4   480,                       // BytesPerLine
5   16,                        // BitsPerPixel
6   (unsigned char *)bmpLogo,  // Pointer to picture data
7   NULL                       // Pointer to palette
8 };

4 显示设备抽象接口

为支持不同显示设备,驱动中将具体的显示设备抽象为一些接口。开发者在添加额外的显示设备时,只要实现这些函数接口,并注册到系统中即可。(在驱动中默认支持谷雨的TFT_144(128x128)屏,TFT_130(240x240),对应的文件lcddrv_tft_144.c,lcddrv_tft_130.c)。

系统中将这些抽象的接口,实施成一个结构体LCDDRV_DEV_API,其内容如下。

  1 //******************************************************************************
  2 // fn : LCD_Init
  3 //
  4 // brief : Init the lcd mode
  5 //
  6 // param : none
  7 //
  8 // return  : none
  9 typedef void (*pfLCD_Init)(void);
 10 
 11 //******************************************************************************
 12 // fn : LCD_SetPixel
 13 //
 14 // brief : Set the index of given pixel
 15 //
 16 // param : x ->  x axis position
 17 //         y->   y axis positin
 18 //         colorIndex -> rgb
 19 //
 20 // return  : none
 21 // 注意:
 22 // 此函数没有作参数检查。调用函数必须确定坐标在LCD范围内。
 23 typedef void (*pfLCD_SetPixel)(int x, int y, int colorIndex);
 24 
 25 //******************************************************************************
 26 // fn : LCD_FillRect
 27 //
 28 // brief : fill the Rect with Color
 29 //
 30 // param : x0 -> the start positin in x axis
 31 //         y0 -> the start positin in y axis
 32 //         x1 -> the end positin in x axis
 33 //         y1 -> the end positin in y axis
 34 //        
 35 //          ___________________
 36 //         |                  |
 37 //         |  +(x0,y0)        |
 38 //         |                  |
 39 //         |                  |
 40 //         |         +(x1,y1) |
 41 //         |__________________|
 42 //
 43 // return  : none
 44 // 注意:
 45 // 此函数没有作参数检查。调用函数必须确定坐标在LCD范围内。  
 46 typedef void (*pfLCD_FillRect)(int x0, int y0 ,int x1, int y1,int colorIndex);
 47 
 48 //******************************************************************************
 49 // fn : LCD_DrawHLine
 50 //
 51 // breif : Draw a horizontal line
 52 //
 53 // param : x0 -> the start position of horizontal
 54 //         y  -> the vertical position
 55 //         x1 -> the end position  of horizotal
 56 //
 57 // return : none
 58 // 注意:
 59 // 此函数没有作参数检查。调用函数必须确定坐标在LCD范围内。
 60 typedef void (*pfLCD_DrawHLine)(int x0, int y, int x1,int colorIndex);
 61 
 62 //******************************************************************************
 63 // fn : LCD_DrawVLine
 64 //
 65 // breif : Draw a vertical line
 66 //
 67 // param : x  -> the horizontal position
 68 //         y0 -> the start position of vertical
 69 //         y1 -> the end position of vertical
 70 //
 71 // return : none
 72 // 注意:
 73 // 此函数没有作参数检查。调用函数必须确定坐标在LCD范围内。
 74 typedef void (*pfLCD_DrawVLine)(int x, int y0, int y1,int colorIndex);
 75 
 76 //******************************************************************************
 77 // fn : LCD_DrawBitmap
 78 //
 79 // breif : Draw a bitmap
 80 //
 81 // param : x0 -> the start position of x Axis
 82 //         y0 -> the start position of y Axis
 83 //         xSize -> the size of row
 84 //         ySize -> the size of column
 85 //         BitsPerPixel -> the NUM bits of perPixel
 86 //         BytesPerLine -> the NUM Bytes of a line
 87 //         pData ->
 88 //
 89 // return : none
 90 // 注意:
 91 // 此函数没有作参数检查。调用函数必须确定坐标在LCD范围内。  
 92 typedef void (*pfLCD_DrawBitmap)(int x0, int y0,
 93                                  int xSize, int ySize,
 94                                  int BitsPerPixel,
 95                                  int BytesPerLine,
 96                                  const U8 *pData,
 97                                  int diff,
 98                                  U32* pTrans);
 99 
100 
101 #define LCD_XSIZE_ID             0x01
102 #define LCD_YSIZE_ID             0x02
103 #define LCD_COLOR_MODE_ID        0x03
104 
105 typedef int (*pfLCD_Info)(int id);
106 
107 //******************************************************************************
108 // 定义LCD屏通用驱动接口函数
109 //
110 typedef struct 
111 {
112   pfLCD_Init          pfLcdInit;               //init func
113   pfLCD_SetPixel      pfLcdSetPixel;           //Draw dot
114   pfLCD_FillRect      pfLcdFillRect;           //fill a rectangle
115   pfLCD_DrawHLine     pfLcdDrawHLine;          //draw a horizontal line
116   pfLCD_DrawVLine     pfLcdDrawVLine;          //draw a vertical line
117   pfLCD_DrawBitmap    pfLcdDrawBitMap;         //draw a bitmap
118   pfLCD_Info          pfLcdInfo;               //get the param.Ex xsize 
119 }LCDDRV_DEV_API;

LCDDRV_DEV_API结构中成员变量都是函数指针,具体注释见上述函数指针声明。开发者在添加显示设备时,只要将实现的LCDDRV_DEV_API结构注册到lcd.c中,并通过LCDDRV_API宏定义进行引用即可。

lcd.c 在驱动中,主要起到在用户接口与显示设备驱动之间桥梁,即用户接口函数通过lcd.c与显示设备驱动进行交互。同时lcd.c中还负责参数检查。

5 硬件通信抽象接口

考虑到显示设备通信方式的不同,在驱动中,将与显示设备通信方式抽象为一个接口,即HalLcdHwTable。

 1 /* 打开关闭LCD 背光 */
 2 typedef void (*hal_lcd_bl)(U8);
 3 
 4 /* 设置通信模式:即低电平是LCD命令(选择寄存器),高电平LCD数据(设置寄存器中的值)*/
 5 typedef void (*hal_lcd_mode)(U8);
 6 
 7 /* spi通信片选,低电平有效 */
 8 typedef void (*hal_lcd_cs)(U8);
 9 
10 /* spi发送一个数据 */
11 typedef U8 (*hal_spi_write)(U8);
12 
13 /* spi 发送指定个数据 */
14 typedef U8 (*hal_spi_writeMore)(U8*,U16);
15 
16 typedef struct
17 {
18   hal_lcd_bl         pfLcdBl;
19   hal_lcd_mode       pfLcdMode;
20   hal_lcd_cs         pfLcdCs;                      //如果cs由spi控制,此处为NULL
21   hal_spi_write      pfLcdSent;
22   hal_spi_writeMore  pfLcdSentMore;
23 }HalLcdHwTable;

开发者根据平台的要求,实现HalLcdHwTable结构。hal_lcd_bl函数指数控制显示屏的背光;hal_lcd_mode函数指针控制通信数据属性,即是命令还是数据;hal_lcd_cs函数指针控制着显示屏片选;hal_spi_write函数指数用于数据的发送。

6 任意字体生成

为满足不同尺寸显示屏的显示需求,开发者可以根据自己实际需求,生成自己想要的尺寸字体。在这里用到了两个小工具,一个是PCtoLCD2002完美版-(字符模式),用于生成字符或汉字取模。一个是FontMap,将字模生成X的宏。

这里以英文12x24大小字体的大写字母A为例。

  1. 双击打开PCtoLCD2002
  2. 输入字符A
  3. 将字体宽度与高度改成24
  4. 点击设置按钮,将格式设成C51,每行显示数改成24x2 = 48。如下图所示。
  5. 点击生成字模,此时下方将会显示A字符字模数据。
  6. 双击运行FontMap,将5步骤生成字模数据复制到输入框中,同时在cfg框中,将BytesPerLine改成2。参数根据实际字体大小进行调整,多于8的陪数就要加1。如本例12,此参数就填写2(12/8 + 12%8 ? 1 : 0).
  7. 点击StartMAP按钮,就会生成X与_的组成A的样子,如上图所示。
  8. 完成所有字库创建之后,在字库文体的中创建FONT_INFO结构,GUI_FONT结构来表述字体。
  9. 最后一步最为重要。创建GUI_FONT* GUI_pEnFont指针变量,且指向上述创建的GUI_FONT变量,由驱动使用。例如下面示例代码。
     1 const FONT_INFO FontInfo12x24 = {
     2  GUI_FontData[0],
     3  32,                    /* FirstChar */
     4  127,                   /* LastChar */
     5  12,                     /* XSize */
     6  2                      /* BytesPerLine */
     7 };
     8   
     9 const GUI_FONT GUI_Font12x24 = { FONT_FUNC, 24, {&FontInfo12x24}};
    10 
    11 
    12 //外部使用
    13 const GUI_FONT* GUI_pEnFont = &GUI_Font12x24;
    

7 增加显示屏

显示屏操作,已经抽象LCDDRV_DEV_API接口。开发者只要实现这些函数接口,并在lcd.c文件中进行声明即可。同时通信部分实现HalLcdHwTable硬件接口即可。

在LCDDRV_DEV_API接口中,对显示屏进行初始化设置,画点,画线,填充矩形,显示一个图片等操作。最后将这些函数放到LCDDRV_DEV_API变量中。以谷雨显示屏GYU_TFT_130(240x240)型为例,实现LCDDRV_DEV_API。

  1 //******************************************************************************
  2 // fn : LCDDRV_TFT130_Init
  3 //
  4 // brief : Init the lcd mode
  5 //
  6 // param : none
  7 //
  8 // return  : none
  9 extern void LCDDRV_TFT130_Init(void)
 10 {
 11   //open the backlight
 12   HalLcdHwFunc.pfLcdBl(LCD_BL_ON);
 13   
 14   _SetReg(0x36);     //memery access control
 15   _SetData(0x00);
 16   
 17   _SetReg(0x3A);     //interface pixel formate
 18   _SetDataMore((U8*)PIXEL_FORMATE_INTERFACE , 1);
 19 
 20   _SetReg(0xB2);     //porch setting
 21   _SetDataMore((U8*)PORCTRL_SETTING , 3);
 22   
 23   _SetReg(0xB7);     //gate control
 24   _SetDataMore((U8*)GATE_CTL , 1);
 25   
 26   _SetReg(0xBB);     //VCOM setting
 27   _SetDataMore((U8*)VCOM_SETTING , 1);
 28   
 29   _SetReg(0xC0);     //LCM control
 30   _SetDataMore((U8*)LCM_CTL , 1);
 31   
 32   _SetReg(0xC2);     //VDV VRH enable control setting
 33   _SetDataMore((U8*)VDV_VRH_EN_SETTING , 1);
 34   
 35   _SetReg(0xC3);     //VRH setting
 36   _SetDataMore((U8*)VRH_SET, 1);
 37   
 38   _SetReg(0xC4);     //VDV setting
 39   _SetDataMore((U8*)VDV_SET, 1);
 40   
 41   _SetReg(0xC6);     //frame rate control
 42   _SetDataMore((U8*)FRAME_RATE_CTL, 1);
 43   
 44   _SetReg(0xD0);     //pwr control
 45   _SetDataMore((U8*)PWR_CTL, 2);
 46   
 47   _SetReg(0xE0);     //gamma 1
 48   _SetDataMore((U8*)GAMMA_CONTROL1, 14);
 49   
 50   _SetReg(0xE1);     //gamma 2
 51   _SetDataMore((U8*)GAMMA_CONTROL2, 14);
 52   
 53   _SetReg(0x21);     //display inversion on
 54 
 55   _SetReg(0x11);     //exit on sleep
 56   
 57   _SetReg(0x29);     //Display on
 58   
 59 }
 60 //******************************************************************************
 61 // fn : LCDDRV_TFT130_SetPixel
 62 //
 63 // brief : Set the index of given pixel
 64 //
 65 // param : x ->  x axis position
 66 //         y->   y axis positin
 67 //         colorIndex -> rgb
 68 //
 69 // return  : none
 70 // 注意
 71 // 此函数没有作参数检查,调用者必须确定坐标在范围内
 72 extern void LCDDRV_TFT130_SetPixel(int x, int y, int colorIndex)
 73 {
 74   U16 color = _Color2Index(colorIndex);
 75   
 76   LCDDRV_TFT_SetXY(x,y);
 77   
 78   _SetColorIndices(color);
 79 }
 80 
 81 //******************************************************************************
 82 // fn : LCDDRV_TFT130_FillRect
 83 //
 84 // brief : fill the Rect with Color
 85 //
 86 // param : x0 -> the start positin in x axis
 87 //         y0 -> the start positin in y axis
 88 //         x1 -> the end positin in x axis
 89 //         y1 -> the end positin in y axis
 90 //        
 91 //          ___________________
 92 //         |                  |
 93 //         |  +(x0,y0)        |
 94 //         |                  |
 95 //         |                  |
 96 //         |         +(x1,y1) |
 97 //         |__________________|
 98 //
 99 // return  : none
100 // 注意
101 // 此函数没有作参数检查,调用者必须确定坐标在范围内
102 extern void LCDDRV_TFT130_FillRect(int x0, int y0 ,int x1, int y1,int colorIndex)
103 {
104   U16 devColor = _Rev16(_Color2Index(colorIndex));
105  
106   U16 xDelta = 0, yDelta = 0, bytesPerline; 
107   
108   xDelta = (x1 > x0 ? x1 - x0 : x0 - x1) + 1 ;
109   yDelta = (y1 - y0 ? y1 - y0 : y0 - y0) + 1 ;
110   
111   bytesPerline = xDelta << 1;
112   
113   for(U16 i = 0 ; i < xDelta ; i++)
114   {
115     gLcdBuf[i] = devColor;
116   }
117 
118   _SetLcdRect(x0,y0,x1,y1);
119   
120   for(U16 i = 0 ; i < yDelta ; i++)
121   {
122     _SetDataMore((U8*)&gLcdBuf,bytesPerline);
123   }
124   
125 }
126 
127 //******************************************************************************
128 // fn : LCDDRV_TFT130_DrawHLine
129 //
130 // breif : Draw a horizontal line
131 //
132 // param : x0 -> the start position of horizontal
133 //         y  -> the vertical position
134 //         x1 -> the end position  of horizotal
135 //
136 // return : none
137 // 注意
138 // 此函数没有作参数检查,调用者必须确定坐标在范围内
139 extern void LCDDRV_TFT130_DrawHLine(int x0, int y, int x1,int colorIndex)
140 {
141   U16 devColor = _Rev16(_Color2Index(colorIndex));
142   
143   U16 xDelta = 0, bytesPerline = 0; 
144   
145   xDelta = (x1 > x0 ? x1 - x0 : x0 - x1) + 1;
146   bytesPerline = xDelta << 1;
147   
148   for(U16 i = 0 ; i < xDelta ; i++)
149   {
150     gLcdBuf[i] = devColor;
151   }
152   
153   _SetLcdRect(x0,y,x1,y);
154   
155 
156   _SetDataMore((U8*)&gLcdBuf,bytesPerline);
157   
158 }
159 //******************************************************************************
160 // fn : LCDDRV_TFT130_DrawVLine
161 //
162 // breif : Draw a vertical line
163 //
164 // param : x  -> the horizontal position
165 //         y0 -> the start position of vertical
166 //         y1 -> the end position of vertical
167 //
168 // return : none
169 // 注意
170 // 此函数没有作参数检查,调用者必须确定坐标在范围内
171 extern void LCDDRV_TFT130_DrawVLine(int x, int y0, int y1 ,int colorIndex)
172 {
173   U16 devColor = _Rev16(_Color2Index(colorIndex));
174   
175   U16 yDelta = 0, bytesPerline = 0; 
176   
177   yDelta = y1 - y0 ? y1 - y0 : y0 - y0;
178   bytesPerline = 2;
179   
180   _SetLcdRect(x,y0,x,y1);
181   
182   for(U16 i = 0 ; i < yDelta ; i++)
183   {
184     _SetDataMore((U8*)&devColor,bytesPerline);
185   }
186 }
187 //******************************************************************************
188 // fn : LCDDRV_TFT130_DrawBitmap
189 //
190 // breif : Draw a bitmap
191 //
192 // param : x0 -> the start position of x Axis
193 //         y0 -> the start position of y Axis
194 //         xSize -> the size of row
195 //         ySize -> the size of column
196 //         BitsPerPixel -> the NUM bits of perPixel
197 //         BytesPerLine -> the NUM Bytes of a line
198 //         pData ->
199 //
200 // return : none
201 // 注意
202 // 此函数没有作参数检查,调用者必须确定坐标在范围内
203 extern void LCDDRV_TFT130_DrawBitmap(int x0, int y0,
204                                       int xSize, int ySize,
205                                       int BitsPerPixel,
206                                       int BytesPerLine,
207                                       const U8 *pData,
208                                       int Diff,
209                                       U32* pTrans)
210 {
211   int i = 0;
212   switch(BitsPerPixel)
213   {
214   case 1:
215     for(i = 0 ; i < ySize ; i++)
216     {
217       _DrawBitLine1BPP(x0,i + y0, pData, Diff, xSize, pTrans);
218       pData += BytesPerLine;
219     }
220     
221     break;
222   case 2:
223     break;
224   case 4:
225     break;
226   case 8:
227     break;
228   case 16:
229     for(i = 0; i < ySize ; i++)
230     {
231       _DrawBitLine16BPP( x0, i + y0, (const U16 *)pData, xSize);
232       pData += BytesPerLine;
233     }
234     break;
235     
236   }
237 }
238 
239 //******************************************************************************
240 // fn : LCDDRV_TFT130_GetInfo
241 //
242 // brief : get the lcd related parameter
243 //
244 // param : id -> the id of param
245 //
246 // return : info
247 extern int LCDDRV_TFT130_GetInfo(int id)
248 {
249   switch(id)
250   {
251   case LCD_XSIZE_ID :
252     return LCD_XSIZE;
253   case LCD_YSIZE_ID:
254     return LCD_YSIZE;
255   case LCD_COLOR_MODE_ID:
256     return LCD_COLOR_MODE;
257   }
258   return 0;
259 }
260 ... ...
261 //******************************************************************************
262 // Name : LCDDRV_TFT144_Api
263 //
264 // brief : lcd abstract
265 const LCDDRV_DEV_API LCDDRV_TFT130_Api = 
266 {
267   .pfLcdInit        = LCDDRV_TFT130_Init,
268   .pfLcdSetPixel    = LCDDRV_TFT130_SetPixel,
269   .pfLcdFillRect    = LCDDRV_TFT130_FillRect,
270   .pfLcdDrawHLine   = LCDDRV_TFT130_DrawHLine,
271   .pfLcdDrawVLine   = LCDDRV_TFT130_DrawVLine,
272   .pfLcdDrawBitMap  = LCDDRV_TFT130_DrawBitmap,
273   .pfLcdInfo        = LCDDRV_TFT130_GetInfo
274 };

同时在lcd.c中进行声明。

 1 //******************************************************************************
 2 // Lcd drivers list
 3 //
 4 extern const LCDDRV_DEV_API LCDDRV_TFT144_Api;
 5 extern const LCDDRV_DEV_API LCDDRV_TFT130_Api;
 6 
 7 
 8 
 9 #ifdef LCD_TFT_144
10 
11 #define LCDDRV_API     (&LCDDRV_TFT144_Api)
12 
13 #elif LCD_TFT_130
14 
15 #define LCDDRV_API     (&LCDDRV_TFT130_Api)
16 
17 #else
18 
19 #error "Please,select a lcd driver!"
20 
21 #endif

在显示屏硬件通信接口方面HalLcdHwTable的实现,将是开发者根据自己实际屏幕通信接口要求进行修改。这里以谷雨GYU_TFT_130屏幕为便。它采用二线SPI通信方式,有背光控制,片选控制,数据模式控制。最终实现如下。

 1 //******************************************************************************
 2 //定义LCD硬件操作接口函数表
 3 //
 4 HalLcdHwTable  HalLcdHwFunc = 
 5 {
 6   .pfLcdBl       = HAL_LcdBl,
 7   .pfLcdMode     = HAL_LcdMode,
 8   .pfLcdCs       = HAL_LcdCs,
 9   .pfLcdSent     = Hal_LcdSpiSent,
10   .pfLcdSentMore = Hal_LcdSpiSentMore
11 };