原标题:做嵌入式开发时,你是怎么实现LCD显示的?

1.本文目的

做嵌入式图形开发,我们往往都会利用到各种GUI进行交互设计,但是对于GUI的字符串处理与中文字库显示,也许并不会特别关注,因为GUI已经帮助我们封装了一些通用的API,在调用相对应的API就可以显示想要的图像和字符串了。那么这些底层原理到底是什么呢?

正好和朋友讨论,我们做嵌入式开发都是将输出信息定位到串口,那能不能定位到I2C、SPI、网络等各种协议上去呢?这个确实是有意思的事情,那正好手上有个树莓派,可以通过DSI或者HDMI来显示,那就把rt-thread的console重定位到LCD上去吧,让树莓派的屏幕代替我们的串口调试助手控制台,这样就不用接上串口看输出信息了。

有了这个想法,于是立即付诸行动。需求很明确,开发平台也已经确定,树莓派4+HDMI屏(分辨率1280x800)。或者接DSI的MIPI屏,我发现树莓派的HDMI驱动原来和DSI的MIPI屏的驱动一样,所以两者没有区别。为了简化验证的操作流程,可以选择rtos,这里我就用比较熟悉的rt-thread。因为rt-thread有着和Linux类似的控制终端,这样更加方便对接。

2.资源评估

有了想法,若要想进行下去,必须评估一下手上的资源是否齐全。下面列出必要的资源

1.树莓派4

选择树莓派4作为验证平台,是我因为现在手上环境搭建已经很方便了。嵌入式开发的痛点和难点就是在环境搭建上,一个好的的开发环境可以达到事半功倍的效果。环境搭建值得好好整理,对于验证各种功能,实现各种特性的验证都十分的好用。

2.hdmi屏

由于已经完成树莓派4的hdmi屏驱动的研究工作,并且hdmi驱动和最后抽象出来的就是 FrameBuffer 。操作起来不用管底层的实现,只需要向这个 Framebuffer 的地址处写数据,会自动将这个数据显示到LCD的屏上,十分的方便。并不用关心x,y坐标,像素等等。

3.字库

这里先通过英文字库进行演示,后面再谈中文字库。目前抽取的是开源的GUI中的 font_dejavu_40 字库进行研究。后面的40表示每个字符高度为40个像素,因为屏的分辨率为 1280x800 。如果每个字符的高度太小则看起来文字非常的小,在大屏上看起来十分不友好,所以这里选择40个高度的字体,而宽度不定是因为字符的宽度是不是确定的,每个字符有着自己的宽度比如 L 和 l 两个数字的宽度就不一样。

有了上述资源,就可以进行后面的探究了,下面来梳理一下显示原理。

3.显示原理

计算机图形本质上就是像素点的集合,更加具体的就是红黄蓝三原色的组合。

三原色的排布组成了一个像素点。实际LCD放大后像素点看起来如下图所示。

而这些像素的亮度决定了最后显示在屏幕上的效果。像素深度(bits per pixel,简称 bpp ) 描述了每个像素的位数,比如32位则是RGBA8888,24位常见的RGB565和16位常见的565等等。这些都是一个像素所能够表示的信息。

而多个像素可以表示一个图像信息。像素是图像操作的最小单位,所以下面暂时不要考虑颜色信息。

来看一个字库中一个字符的信息

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x1f, 0x80, //..+%@@@@@.....

0xff, 0x80, //@@@@@@@@@.....

0xff, 0x80, //@@@@@@@@@.....

0xe3, 0x80, //@%%+..@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x03, 0x80, //......@@@.....

0x7f, 0xfc, //.@@@@@@@@@@@@@

0x7f, 0xfc, //.@@@@@@@@@@@@@

0x7f, 0xfc, //.@@@@@@@@@@@@@

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

0x00, 0x00, //..............

上述就是字符 1 在字符中的存放信息,每个字节按位展开, . 表示0, @ 表示1。则右边的注释展示了该串字符的信息。如果我们将上述信息告诉给cpu,然后CPU处理这些信息放到LCD上显示则可以显示字符串1。

如果把上面的数组用程序解析交给LCD该如何设计。

1.拷贝上述数组到程序里,作为只有一个字符的字库数组array

2.申请一块和framebuff一样大的内存palette,作为图像输入的 画板

3.读取array第一和第二个元素,将第一个元素按高位解析,如果是0向palette填充黑色像素点,1向palette填充白色像素点。

字库中的每一位对应LCD的一个像素,如果对于RGB565来说,则表示2个字节。那我们可以做这样的理解。字库中 1 的宽度是32个像素,高度是40个像素。

于是可以做标准字库的解析了。一个标准字库是包含多个这样的字符串结构的,所以字符串需要一张表记录这些信息,根据asiic码表排序,字库的存放顺序也可如此,然后一个索引表记录着每个字符串的宽度,数组所在的起始地址信息,有了这些信息,就可以依次做解析然后转换成像素进行显示了。

4.嵌入式上汉字处理

嵌入式上受到资源限制,汉字字库一直都不好解决,不能为了显示汉字把2500~7000个汉字都收录进去,这样需要的内存资源和flash资源十分庞大。为了解决这个问题,一般都是自定义字库,就是首先列出该项目中实际会用到的所有汉字,然后利用特定的软件生成对应的像素字符数组,生成的同时,也会对应这一张map表,方便查找具体汉字的位置。

在处理英文的时候,由于所需的字符很少,可以通过ASCII码进行索引,汉字则可以自定义索引规则,这些都是需要自己设计处理的。但是原理是一样的。

5.结果验证与展示

经过上述的操作,已经完成了lcd console的任务,可以给自己交差了。

其实现的代码也已经放到百度网盘上可以供参考。

链接:https://pan.baidu.com/s/17A37ISKT0tW3WWq2oXJASw

提取码:dgr6

上述代码仅供参考,优化部分还需完善。

6.总结

需要注意的是,对于不同的LCD,需要自己找到合适的大小的字体,这样才能看起来清楚。另外在实现的细节上需要注意的是最好不要在framebuffer上直接绘图,可以放到一个与framebuffer大小一样的数组中,叫做palette,也就是画板。当绘制一帧画面完成后,再刷新到framebuffer中,这是因为framebuffer是非cache的,操作起来会影响刷屏的帧率,看起来帧率会很低。

对于英文字库的显示、中文汉字的处理,有很多东西需要去拓展。其中汉字的抗锯齿问题就很值得研究学习,汉字模糊,汉字的锐化等等,万变不离其宗,其核心都是对像素的处理。LCD绘图,理解像素处理流程,所有的上层应用实现都非常好理解。

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。返回搜狐,查看更多

责任编辑:

嵌入式linux调试dsi,做嵌入式开发时,你是怎么实现LCD显示的?相关推荐

  1. 嵌入式linux ASoC架构声卡驱动开发

    嵌入式linux ASoC架构声卡驱动开发 文章目录 嵌入式linux ASoC架构声卡驱动开发 需求分析 ASoC架构下声卡驱动代码结构 codec驱动 snd_soc_register_codec ...

  2. 嵌入式Linux设备驱动程序:在运行时读取驱动程序状态

    嵌入式Linux设备驱动程序:在运行时读取驱动程序状态 Embedded Linux device drivers: Reading driver state at runtime 在运行时了解驱动程 ...

  3. 使用java做paypal开发时购买东西支付不成功的原因

    使用java做paypal开发时购买东西支付不成功的原因 没有设置网站习惯设定,登陆自己的paypal账户,在网站习惯设定上填写回调的url路径,这样就可以 支付成功了并且异步修改订单的状态. 支付成 ...

  4. 嵌入式linux的发展历程,嵌入式Linux论文(历史发展分类及应用)

    嵌入式Linux 一.嵌入式Linux简介 1.1 嵌入式Linux历史 随着社会的发展,信息化技术的成熟和数字化产品的普及,让以计算机技术.芯片技术和软件技术为核心的嵌入式系统再度成为当前研究和应用 ...

  5. 嵌入式系统开发与应用——嵌入式 Linux 调试环境搭建

    附录:UBoot常用命令手册 一. 实验目的 1.掌握VMware中设置共享文件夹的方法,为后续实验做准备: 2.熟悉 Linux TFTP 配置,为后续 Linux 底层开发做准备(后面会用 tft ...

  6. 嵌入式linux sd卡读写,嵌入式Linux之我行——S3C2440上MMC/SD卡驱动实例开发讲解(二)...

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 一.开发环境 主  机:VMWa ...

  7. 嵌入式linux clion,跨平台IDE集成开发环境Clion教程:嵌入式开发

    CLion是一款专为开发C及C++所设计的跨平台IDE.它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员的生产力.这种强大的IDE帮助开发人员在Linux.OS X和Windows ...

  8. 嵌入式linux 添加中断,《嵌入式linux应用程序开发完全手册》中断控制器操作(外部中断)学习笔记...

    <嵌入式linux应用程序开发完全手册>中断控制器操作(外部中断)学习笔记 一.ARM中断体系 当一个"异常"发生时,或者说当收到一个中断触发信号时,ARM9将会自动完 ...

  9. 嵌入式linux应用层中断函数,嵌入式LINUX驱动开发(中断处理函数)

    嵌入式LINUX驱动开发(中断处理函数) 2020年08月11日 | 萬仟网网络运营 | 我要评论 嵌入式LINUX驱动学习之7中断相关(一)中断处理函数一.函数.头文件及说明二.编译举例:一.函数. ...

最新文章

  1. 用无序列表做的网站公告牌(Billboard)
  2. Vue组件中使用Sass或者Less全局变量
  3. 【每周NLP论文推荐】 NLP中命名实体识别从机器学习到深度学习的代表性研究
  4. [转载]Java-集合框架完全解析
  5. 用户路径分析:揭秘你的用户行为偏好习惯
  6. 前端UI框架《Angulr》入门
  7. Python 包管理工具 pip 安装 和 使用
  8. 图像处理——图像增强
  9. java response设置403,java.io.IOException:服务器返回URL的HTTP响应代码:403
  10. matlab动态图最新存储文件,MATLAB 动图绘制、保存
  11. php文档头,头部文档(header.php)
  12. MySQL进阶之SQL优化
  13. 自适应滤波——线性预测(LPC)
  14. linux uuid挂载磁盘_Linux磁盘设备磁盘设备的UUID标识代码(sda,sdb,sdc…)变化的解决办法...
  15. 成为一名Java高级工程师需要掌握哪些技能
  16. php date 函数用法,PHP日期时间函数date()使用方法
  17. 智能车辆纵向速度跟踪与控制方法研究
  18. ThreeJs 学习之旅(十六)—Physics(物理)
  19. 博达网站服务器地址怎么查,路由器博达路由器配置经典教程
  20. 凤姐和她的传销币们-千氪

热门文章

  1. 32位系统和x86的关系?
  2. POJ 3616 Milking Time (字符串DP)
  3. 在 VB.NET 编程中使用数组
  4. CCF201709-1 打酱油(100分)【水题】
  5. HDU2111 Saving HDU【贪心】
  6. CCF NOI1079 合法C标识符
  7. HDU1870 愚人节的礼物【堆栈+输入输出+水题】
  8. B00003 C++标准库 std::bitset
  9. Spark utils —— 设置日志级别
  10. JVM 内存管理、自带性能监测调优工具 (jstack、jstat)及 JVM GC 调优