LCD驱动

  这里以 (分辨率为:192*64)的 数据8线并口液晶屏 举例

一、基础知识

1.1 分辨率

  分辨率指的是屏幕点阵可显示 行和列 点阵的数量;例如我这款192*64分辨率屏幕,它的行显示点数是 192 、列显示点数是 64;分辨率的大小 跟 屏幕的大小 是没有任何关系的;有些屏幕很大但是它显示(点阵)的最小像素是真的大(像我手头这个),因此分辨率并不大,显示的东西也不多。ASCII码的最小字体是0508(点阵),汉字的最小字体则是1616(点阵)
举例:分辨率192*64
  单行可显示最多汉字为:192/16 = 12 个
  汉字最多显示行数: 64/16 = 4 行
因此,该屏最多只能显示 4行(每行)12个的汉字

1.2 驱动代码思路

  以该屏为例;一个好的(不带EWWIN)嵌入式LCD驱动应该分为三大块:
1)底层,LCD硬件驱动(一般由该屏的原本数据手册和源码例程提供)
2)中间层,提供字库和字体写入驱动、框体、阴影、图片等
3)应用层,提供封装界面轮询方式等,用于主程序调用

举例:

  1. Lcd_drv.c
  2. Lcd_dev.c
  3. lcd_user.c
  4. font.h (该字库文件只会被Lcd_dev.c所调用)

二、高级应用

  在显示的过程中,无非就是 1)残影 2)显示方式

  1. 残影是在Lcd显示中经常出现的问题;例如之前显示 “28”,后面再显示 “6”,但是实际效果会显示“26”,这个“2”就是残影
  2. 当你要显示一串数字,带有小数点、单位,甚至(正)负号;而实际上,在Lcd显示的均为字符串,它并不是一组数字,你无法让一个float类型变量(数值)直接显示在Lcd上;如果数字和符号分开显示,又容易形成头疼的残影

2.1 消影

  消影的要点,无非就是要根据屏的分辨率,以及规划好 数据显示区,并且把数据显示区分成每一个最小显示具体字符单位;对要显示的数据位数进行判断,然后从右到左,逐渐挪最高位显示位置;然后将剩下的空白单位格子,用空白显示填充

2.2 数字和字符串转换

  这个最重要的就是sprintf函数了;sprintf函数主要功能是把格式化的数据写入某个字符串中,但需要为正整数(不然符号位会被当成数值)。

数值转换字符串主要为两种:
1)单个数字转换成字符串,用于界面需要具体调整单个数字(不常用到)
2)一个带正负号、小数点、单位等的数值,转换成字符串

以下代码实现 数值进行转换成字符串:(不带符号和单位,可根据下面思路添加)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static const char *cSprintf[]=
{
"%d",
"%d.%01d",
"%d.%02d",
"%d.%03d",
"%d.%04d",
"%d.%05d",
};
static uint32_t uiPowVal[] = {1,10,100,1000,10000,100000};

uint32_t _valSprintf(uint32_t uiVal,uint8_t ucShift,char *pucFrame)
{
uint32_t uiLen = 0;

switch(ucShift)
{
case 1:
case 2:
case 3:
case 4:
case 5:
uiLen = sprintf(pucFrame,cSprintf[ucShift],(uiVal/uiPowVal[ucShift]),(uiVal%uiPowVal[ucShift]));
break;
default:
uiLen = sprintf(pucFrame,cSprintf[0],uiVal);
break;
}
return uiLen;
}

2.3 界面显示划分

  1. 采用回调函数,将每个界面都分割成两块实现:(界面初始化)InitGUI 和 (界面刷新)UpdateGUI;方便查看各个界面功能代码
  2. 采用 switch轮询方式显示页面,页码作为switch参数;再用enum枚举页码,可以使得页面扩展时 增加和删减页面变得更简单,而且可随意更改序号;
  3. 构造一个结构体能够用来记录 当前页码 和 缓存页码 ;缓存页码会在进入某个页面就一直保存对应的值,当前页码则是会根据操作可能发生变化;两个页码对比,就可以知道页面是否要重新进入初始化;
-------------本文结束感谢您的阅读-------------