利用单片机分时电价系统设计(编辑修改稿)内容摘要:

隐藏了一个列实现的细节, LCD 由两块显示芯片控制,每一块控制 61 列,即 0~ 60列为第一块芯片控制,要用 Display_Left 函数显示 ,第二块控制 61~121 列,要用Display_Right 函数显示,而此函数可以接受的列为 0~ 0x7F。 在函数中会对输入的列参数进行判断,小于 0x40 的列,函数会调用 Display_Left 函数显示 ,大于或者等于 0x40 的列,函数会调用 Display_Right 函数显示。 这样就完成了列的平滑显示。 DisplayAtRow 函数是对 DisplaySelected 函数的进一步封装,此函数的意图是掩盖页的跨越,使之能够以一个函数在 LCD 上显示一个完整的、共 32 字节数据表示的字符。 由于 DisplaySelected 函数已经掩盖了列的跨越,所以 DisplayAtRow的列参数就直接传递给了 DisplaySelected 函数。 DisplayAtRow 函数将整个 LCD分成了两个显示行,每个显示行包含 2 个页 , 16 个像素行,可以显示一个完整的字符。 其实现原理是对于位于第 0 显示行的字符,调用 2 次 DisplaySelected函数,将字符的上半数据送到第 0 页显示,将字符的下半数据送到第 1 页显示,这样就完成了整个字符的显示。 对于位于第 1 显示行的字符,将字符的上半数据调用 DisplaySelected 函数送到第 2 页显示,将 字符的下半 数据调用DisplaySelected 函数送到第 3 页显示。 这样就完成了页跨越的掩盖。 位于 LCD 显示驱动最高层,即 “显示服务提供层 ”的函数只有一个,即DisplayALine,此函数是基于 DisplayAtRow 函数的封装。 由于 DisplayAtRow 函数可以在指定位置显示一个字符,基于这种能力派生的 DisplayALine 函数的功能就是将一行字符显示在某一个显示行上。 由于 LCD 最多可以显示 8 个 1616的字符。 所以 DisplayALine 函数显示字符串的最大字符限制也为 8 个字符。 DisplayALine 函数用来向其他需要显示的函数提供服务。 一个需要进行显示的函数将它要进行显示的数据通过查表或者其他途径转换为 LCD 显示的显示码,然后将显示码保存在一个 832 的数组中传递给 DisplayALine 函数,然后DisplayALine 函数将数组中的数据全部送入某行进行显示。 两个提示函数 ShowDefault 和 ShowError 用于显示必要的提示信息。 ShowDefault函数设计成一个死循环,用于显示系统的待机画面。 此待机画面用于向用户提示键盘上各个按键的功能。 ShowError 函数在用户操作出错时向用户显示一个出错提示,以便防止用户误操作。 六、总结 这个系统是我所设计过的最为复杂的一个系统,虽然硬件部分比较简单,但是这个系统的软件完全是在我已经纯熟的 C 语言编程技巧的基础上开发的,除了为了了 解某些硬件的命令字查看过示例程序外,其他的程序完全是自己开发的,没有参考、抄袭其他任何论文、报告。 通过这个系统的设计,我对 Keil C51 的语法,开发方法有了较深的认识,可以肯定的说,如果有第二次机会开发这样的系统,那么,在系统控制程序上所犯的错误,将会大大减少。 在设计本系统之前,为单片机编写的程序都是较小的程序,一直用汇编语言写。 本系统的复杂性使汇编语言程序不利于编写和阅读,所以采用 C 语言编写。 由于我以前都是为 Intel 80586 以上,安装 windows 操作系统的 PC 写 C 语言的应用程序。 所以虽然程序完 全符合标准 C 语言的要求,但是由于硬件平台的不同,还是出现了很多问题。 现将各种问题一一描述: 中断函数寄存器组使用不当:程序中有 3 个中断函数,在最初每个中断函数使用的寄存器组都不相同,本意是为了提高寄存器的利用效率。 定义侦探狗中断 T0 使用寄存器组 1,键盘中断使用寄存器组 2,电量中断使用寄存器组 3。 但是在调试中发生了一个错误。 main 函数和 KeyBoard 函数中都调用了DisplayALine 函数显示一个字符串。 main 中的调用可以正常工作,将字符串显示在 LCD 上,但是 KeyBoard 函数中则只能显示 字符串的上半行,下半行的字总是显示在 LCD 的最左边,从而造成这样一些乱码。 这个问题对我们造成了相当的困扰,因为 main 和 KeyBoard 调用的是同一个函数。 开始时以为是在传递参数时指针出错,后来使用断点调试时才发现, DisplayALine 在显示下半行调用DisplaySelected 函数时,列 Column 的实际值都为 0,所以所有的字符的下半行都送到第一个字符下面去显示。 其后分析认为,产生的错误中,最大的不同是调用 DisplayALine 函数的位置不同,即一个在 mian 中,另一个在 KeyBoard 中,它们两 个函数使用了不同的寄存器组。 main 使用的寄存器组为第 0 组, KeyBoard使用第 2 组。 由于 DisplayALine 函数的参数是通过寄存器组来传递的,所以推断使用其他的寄存器组会导致显示错误。 将 KeyBoard 函数使用的寄存器组改为0 组,错误消失。 数据段溢出错误:在最初的程序中,除了字库外,全局变量、静态变量都按照标准 C 语言方式默认定义,没有考虑到存储位置的问题。 但是链接时发生错误,提示 data 段溢出。 最初不明所以,其后查看 C51 的帮助文档时看到,如果不显式说明变量的存储位置,则变量会根据系统模 式的设置存放到默认的数据区。 本系统中使用的是 89C58 最小系统方式,默认情况下变量会存放到系统的data 段,由于 data 段只有 128 个字节,而且还有寄存器组和位寻址区,难以容纳所有的变量。 了解到这些以后,将所有的全局变量和静态变量都显式声明到 idata段, idata 段为 256 字节,足以容纳这些变量,问题得意解决。 编译器汇编语言与 C 语言交叉编译不完善:在本系统程序设计中,在某些位置需要用到汇编中的一条 nop 指令,由于 C 语言中并无与此功能相近的语句,所以我们求助于 C51 中的 C 语言与汇编语言的交叉 编译。 即在相应位置加入pragma asm nop pragma endasm 汇编指令,执行空指令。 在编译器中设置好相关选项并进行编译。 在我的电脑上安装有 Keil C51 试用版,利用此版本进行编译、链接通过,但是使用版有代码大小限制,无法生成执行文件。 实验室安装的为 Keil C51 版,在链接时无法通过,提示大堆的符号未定义。 由于编译器版本老旧的问题,为了生成执行文件,只能将相应位置的汇编指令去除或者用与之近似的 C 语句代替。 编译器对预编译指令未正确解释:本系统程序设计时,由于 字库比较大,所以最初是将字库定义在一个头文件 中,与主程序隔离。 这样的话,修改和阅读都比较方便。 但是链接时产生错误,连接器抱怨说字库公开变量被多次定义。 推断应该是头文件被多个模块包含产生了错误。 然后修改了代码,将 文 件 中 所 有 的 变 量 定 义 都 包 含 在 预 处 理 指 令 ifndef CHARACTERLIB_H define CHARACTERLIB_H …endif 中,但是在 Keil C51 版本中仍然会产生错误。 如果换用 Keil C51 版本,则在头文 件中不加预编译指令也不会报错。 因为实际上只有 包含了。 最后,只能将字库定义全部从 中移到 中,问题解决。 我可以容忍设计中出任何问题,但是不能容忍实验室的仪器出一点点问题。 这是第一次课程设计时留下的痛苦回忆,设计的完全正确,但是结果完全错误。 最后发现仪器装作可以正常工作的样子欺骗我们,那时真想扑上去咬它。 这次使用的是湖北众友的单片机开发实验箱,总算是正常工作(并不是每个人的都正常工作,汗)。 但是问题并不是没有。 由于设计的系统中要用到一 个 LCD 显示模块,而这个模块是国产的模块,除了厂家外,并没有标准使用说明书。 只能参考实验箱的使用手册。 在这个手册上提供了 3 个关于 LCD 的信息,一个是 Protel 画的实验箱的 LCD 部分电路图,一个是手册上的 LCD 连线示例图,还有一个是 LCD 模块引脚说明表。 但是,这 3 个资料中,任意两个对 LCD 引脚连线方法的说明都不同。 真是很无语,幸好这个问题只影响 PCB 电路图的绘制,对于编程没有影响,暂时将其忽略了。 众友开发箱附带的使用手册也令人很无语,居然只有薄薄的 58 页,还没有我的设计报告长,国产产品的通病。 幸好上面 的电路图和随机附带的程序源码都还实用,不然的话。 关于这个开发板的硬件呢, CPU 是 SST 的 89C58, 256B 可用内存(喜欢), 32KB的 FlashROM(喜欢),时钟为 33MHz。 此单片机带的 32KB 的 FlashROM 帮了大忙,我的设计中程序共 20xx 多行, 1000 行为字库,一半存放于外部 RAM,一半存放于 ROM 中。 1000 行为程序代码。 这样加起来,代码大小为 15KB,要不是他的 ROM 足够大,还真的放不下。 LCD 为 FM12232A 液晶显示模块,共12232 个像素。 以 1616 的像素显示一个字的话 ,这个模块可以勉强显示 2 行,每行 8 个字。 但是比较郁闷的是,如果要完全以 1616 像素显示 8 个字,那么至少 12816 个像素,这个模块一行只有 122 个像素,哭。 既然要显示汉字,为什么不用 12832 的啊,用 122 显 8 个汉字就会少 6 个像素,无语。 只能将第四个字和第 8 个字各少 3 个像素。 虽然肉眼不仔细看的话是看不出来的,总觉得不爽之至。 还用到一个键盘,由 Intel 8279 和 16 键的键盘组成。 这个 8279, Intel 官方出的使用手册共 16 页,赞,看人家的资料就是详细。 自认为英文阅读还不错的我,(平时编程都是直接查 MSDN 的英文文档练出来的,全英文的芯片手册也看过不少)。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。