宋宝华谈 C 语言嵌入式系统编程修炼之四:屏幕操作
汉字处理
现在要解决的问题是,嵌入式系统中经常要使用的并非是完整的汉字库,往往只是需要提供数量有限的汉字供必要的显示功能。例如,一个微波炉的 LCD 上没有必要提供显示"电子邮件"的功能;一个提供汉字显示功能的空调的 LCD 上不需要显示一条"短消息",诸如此类。但是一部手机、小灵通则通常需要包括较完整的汉字库。
如果包括的汉字库较完整,那么,由内码计算出汉字字模在库中的偏移是十分简单的:汉字库是按照区位的顺序排列的,前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录 94 个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:94 * (区号 -1) + 位号 -1。减 1 是因为数组是以 0 为开始而区号位号是以 1 为开始的。只需乘上一个汉字字模占用的字节数即可,即:(94*(区号-1)+位号-1)*一个汉字字模占用字节数,以 16*16 点阵字库为例,计算公式则为:(94 * (区号 -1) + (位号 -1)) * 32。汉字库中从该位置起的32字节信息记录了该字的字模信息。
对于包含较完整汉字库的系统而言,我们可以以上述规则计算字模的位置。但是如果仅仅是提供少量汉字呢?譬如几十至几百个?最好的做法是:
定义宏:
定义结构体:
字模的存储用数组:
要显示特定汉字的时候,只需要从数组中查找内码与要求汉字内码相同的即可获得字模。如果前面的汉字在数组中以内码大小顺序排列,那么可以以二分查找法更高效的查找到汉字的字模。
这是一种很有效的组织小汉字库的方法,它可以保证程序有很好的结构。
系统时间显示
从 NVRAM 中可以读取系统的时间,系统一般借助 NVRAM 产生的秒中断每秒读取一次当前时间并在 LCD 上显示。关于时间的显示,有一个效率问题。因为时间有其特殊性,那就是 60 秒才有一次分钟的变化,60 分钟才有一次小时变化,如果我们每次都将读取的时间在屏幕上完全重新刷新一次,则浪费了大量的系统时间。
一个较好的办法是我们在时间显示函数中以静态变量分别存储小时、分钟、秒,只有在其内容发生变化的时候才更新其显示。
这个例子也可以顺便作为 C 语言中 static 关键字强大威力的证明。当然,在 C++ 语言里,static 具有了更加强大的威力,它使得某些数据和函数脱离"对象"而成为"类"的一部分,正是它的这一特点,成就了软件的无数优秀设计。
动画显示
动画是无所谓有,无所谓无的,静止的画面走的路多了,也就成了动画。随着时间的变更,在屏幕上显示不同的静止画面,即是动画之本质。所以,在一个嵌入式系统的 LCD 上欲显示动画,必须借助定时器。没有硬件或软件定时器的世界是无法想像的:
(1) 没有定时器,一个操作系统将无法进行时间片的轮转,于是无法进行多任务的调度,于是便不再成其为一个多任务操作系统;
(2) 没有定时器,一个多媒体播放软件将无法运作,因为它不知道何时应该切换到下一帧画面;
(3) 没有定时器,一个网络协议将无法运转,因为其无法获知何时包传输超时并重传之,无法在特定的时间完成特定的任务。
因此,没有定时器将意味着没有操作系统、没有网络、没有多媒体,这将是怎样的黑暗?所以,合理并灵活地使用各种定时器,是对一个软件人的最基本需求!
在 80186 为主芯片的嵌入式系统中,我们需要借助硬件定时器的中断来作为软件定时器,在中断发生后变更画面的显示内容。在时间显示"xx:xx"中让冒号交替有无,每次秒中断发生后,需调用 ShowDot:
菜单操作
无数人为之绞尽脑汁的问题终于出现了,在这一节里,我们将看到,在C语言中哪怕用到一丁点的面向对象思想,软件结构将会有何等的改观!
笔者曾经是个笨蛋,被菜单搞晕了,给出这样的一个系统:
要求以键盘上的"← →"键切换菜单焦点,当用户在焦点处于某菜单时,若敲击键盘上的 OK、CANCEL 键则调用该焦点菜单对应之处理函数。我曾经傻傻地这样做着:
终于有一天,我这样做了:
当我定义菜单时,只需要这样:
OK 键和 CANCEL 键的处理变成:
程序被大大简化了,也开始具有很好的可扩展性!我们仅仅利用了面向对象中的封装思想,就让程序结构清晰,其结果是几乎可以在无需修改程序的情况下在系统中添加更多的菜单,而系统的按键处理函数保持不变。
面向对象,真神了!
模拟 MessageBox 函数
MessageBox 函数,这个 Windows 编程中的超级猛料,不知道是多少入门者第一次用到的函数。还记得我们第一次在 Windows 中利用 MessageBox 输出 "Hello,World!"对话框时新奇的感觉吗?无法统计,这个世界上究竟有多少程序员学习 Windows 编程是从 MessageBox("Hello,World!",…)开始的。在我本科的学校,广泛流传着一个词汇,叫做"’Hello,World’级程序员",意指入门级程序员,但似乎"’Hello,World’级"这个说法更搞笑而形象。
上图给出了两种永恒经典的Hello,World对话框,一种只具有"确定",一种则包含"确定"、"取消"。是的,MessageBox 的确有,而且也应该有两类!这完全是由特定的应用需求决定的。
嵌入式系统中没有给我们提供 MessageBox,但是鉴于其功能强大,我们需要模拟之,一个模拟的 MessageBox 函数为:
上述函数与我们平素在 VC++ 等中使用的 MessageBox 是何等的神似啊?实现这个函数,你会看到它在嵌入式系统中的妙用是无穷的。
总结
本篇是本系列文章中技巧性最深的一篇,它提供了嵌入式系统屏幕显示方面一些很巧妙的处理方法,灵活使用它们,我们将不再被 LCD 上凌乱不堪的显示内容所困扰。
屏幕乃嵌入式系统生存之重要辅助,面目可憎之显示将令用户逃之夭夭。屏幕编程若处理不好,将是软件中最不系统、最混乱的部分,笔者曾深受其害。
原文链接:http://dev.yesky.com/9/2018509.shtml。
分享到:
相关推荐
C 语言嵌入式系统编程修炼之四:屏幕操作 C 语言嵌入式系统编程修炼之五:键盘操作 C 语言嵌入式系统编程修炼之六:性能优化 C/C++语言 void 及 void 指针深层探索 C/C++语言可变参数表深层探索 C/C++数组名与指针区别...
C语言嵌入式系统编程修炼之软件架构篇 C 语言嵌入式系统编程修炼之屏幕操作 C 语言嵌入式系统编程修炼之内存操作 C 语言嵌入式系统编程修炼之键盘操作
C 语言嵌入式系统编程修炼之道——宋宝华.pdf
c语言嵌入式系统编程修炼之道 详细介绍了C语言嵌入式开发的技术细节
C 语言嵌入式系统编程修炼之四:屏幕操作 ..........................................................36 C 语言嵌入式系统编程修炼之五:键盘操作 ..........................................................43 C ...
C语言嵌入式系统编程修炼之背景篇 作者:宋宝华出处:天极网责任编辑: 方舟
linux驱动视屏教程-宋宝华13集,下载下来的是一个txt,里面是百度网盘的地址
宋宝华驱动讲解,百度云资源,分享,主要是讲解linux,最新内核,驱动,设备树。
嵌入式C/C++语言精华文章集锦 嵌入式C/C++语言精华文章集锦 嵌入式C/C++语言精华文章集锦
宋宝华设备驱动>随书源代码,可以配套练习,会达到更好的效果
宋宝华写的《VC++动态链接库(dll)编程深入浅出》,对调用dll有详细的描述
ARM嵌入式编程与实战应用--STM32F1系列 金沙滩工作室的宋雪松编写的。我整理成一个文件,带有书签方便阅读,还添加了页码,方便打印。
Linux_I2C核心、总线与设备驱动(宋宝华 嵌入式开发
嵌入式C+C++语言精华文章锦集.rar嵌入式C+C++语言精华文章锦集.rar
1. 程序和编程语言 2. 自然语言和形式语言 3. 程序的调试 4. 第一个程序 2. 常量、变量和表达式 1. 继续Hello World 2. 常量 3. 变量 4. 赋值 5. 表达式 6. 字符类型与字符编码 3. 简单函数 1. 数学函数 2. 自定义...
宋宝华LINUX驱动书籍前言部分,为宋宝华linux驱动书籍的介绍,摘取的前言目录部分。
宋宝华视频讲解linux驱动开发,下载文件为百度网盘地址,输入密码获取视频
linux设备驱动详解视频(宋宝华)视频下载地址,地址百度网盘,提取码都在文件里面。