1、 天津电子信息职业技术学院课 程 设 计课题名称 基于 uCOS的 LCD 驱动编写 姓 名 王浩 学 号 35 班 级 电信 S10-1 专 业 电子信息工程 成 绩 完成日期 2012-06-01 基 于 uCOSII 的 LCD 驱 动 编 写摘要LCD 是嵌入式操作系统的重要组成部分,是系统和用户之间进行交互和信息交换的媒介,它实现信息的内部形式与人类可以接受形式之间的转换。用户可以只通过 LCD 监测系统内部运行状态,然后作出相应的处理。因而具有良好的人机界面的嵌入式操作系统能过很好的完成系统开发、生产生活的需要。S3C44B0X 中具有内置的LCD 控制器,它能将显示缓存(在SDR
2、AM存储器中)中的LCD图像数据传输到外部的LCD驱动电路上的逻辑功能。它支持单色、4级、16级灰度LCD显示,以及256彩色LCD显示。在显示灰度时,它采用时间抖动算法(time-based dithering algorithm)和帧率控制 (Frame Rate Control)方法,在显示彩色时,它采用RGB的格式,即RED、GREEN、BLUE,三色混合调色。通过软件编程,可以实现233或332的RGB调色的格式。对于不同尺寸的LCD显示器,它们会有不同的垂直和水平象素点、不同的数据宽度、不同的接口时间及刷新率,通过对LCD 控制器中的相应寄存器写入不同的值,来配置不同的LCD 显示
3、板。LCD 能够正常工作得益于软硬件的协同工作,S3C44B0X 集成了 LCD 的控制器,即不带驱动电路的 LCD 显示模块,驱动程序需要根据用户需要来自行添加。u C / O S 是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统,在具体应用中稳定可靠,并且支持 uIP TCP/IP 协议栈、ucGUI 等,可扩展性强,功能强大。因此,在 uC/OS II 下写的 LCD 驱动具有较好的实时性和稳定性,功能强大。关键词:嵌入式系统;LCD 显示;驱动电路;目录一、系统设计 51.课题目标及总体方案 .52.LCD 驱动程序组成 53.UCOSII 操作系统下添加 LCD 驱动
4、程序 .64.应用程序 7二、实验结果测试 8三、总结 .9四、心得体会 9五、参考文献 10六、附 录 11一、系统设计1.课题目标及总体方案首先学习了解 LCD 的驱动程序,然后在移植好的 UCOSII 项目中添加 LCD 的驱动程序, 最后能够在 uCOSII 下,编写 LCD 应用任务的简单编程实例,来检验 LCD 驱动程序的完好度。本实验实例为在 LCD 屏上显示跑马灯,同时模拟 CPU 板上 D7、D8 灯的交替闪烁,闪烁周期为跑马灯周期。2.LCD 驱动程序组成LCD 驱动程序的文件夹 Gui(如图 1 所示),其中,包括四个文件夹:图 1Font 中存放的是字体文件,存放四个文
5、件,Font_Cn12.c 为调用汉字库 12X12 汉字的引用文件;Font_Cn16.c 为调用汉字库 16X16 汉字的引用文件; Font8X16 为调用 ASCII码的源文件,它的大小为 8X16;Gchar.c 为显示字符的源程序库。Glib 中存放绘图的中层和上层的函数,上层函数是直接供用户调用的 API, 。Glib 文件夹内存放两个文件,Glib.c 是图形显示库的源代码,它主要实现 LCD 的中层和上层供用户调用的 API 函数,Glib.h 则是供其他文件或自身调用的头文件。Init 中存放 GUI 初始化的函数, Init 文件夹内存放两个文件,data.h 是数据类型
6、重定义的文件,GUI_Init.c 是 GUI 系统的初始化文件。Lcddriver 中存放的是 LCD 的底层驱动函数,以及对 LCD 控制器的初始化函数。Lcddriver 文件内存放两个文件,Lcddriver.c 包括 LCD 的底层读写内存用来绘图的函数,以及初始化 LCD 控制寄存器的初始化硬件的函数。 Lcddrive 是供其他文件或自身调用的头文件。 3.UCOSII 操作系统下添加 LCD 驱动程序在 UCOSII 操作系统下添加 LCD 驱动程序,也就是把整个 GUI 文件夹加入该项目里。同时,还要在 ApplicationINC 目录下的 config.h 文件中,加入
7、GUI 程序的头文件,#include “GuiGlibGlib.h“,这是为了在应用中方便调用画图的 API 函数。如果,要在 LCD 上显示英文或汉字,还要在 ApplicationSRCMain.c 中声明引用的是 extern GUI_FONT CHINESE_FONT12;等外部定义过的字体。这样,编译就能通过,就把LCD 的驱动程序以及小型的 GUI 图形库,加载到了 UCOSII 操作系统上了。在 UCOSII 操作系统下,要单独开辟一个 GUI 任务,进行画图,一般这个任务的优先级很低,一般它仅比空闲任务的优先级高,这样做是为了可以使更多的任务等级显示在屏上。在 Applica
8、tion/SRC 下的 MAIN.C 文件,有 GUI 的应用任务,绘图的 API 函数即放在这里,或者作一个应用函数的文件,在此任务里调用。所有的对 LCD 显示操作内容要在MAIN.C 文件中编写。4.应用程序本实验实例为在 LCD 屏上显示跑马灯,同时模拟 CPU 板上 D7、D8 灯的交替闪烁,闪烁周期为跑马灯周期。来检验 LCD 驱动程序是否能正常工作。实验流程图如下:程序开始先进行各项初始化,包括开发板、GUI 初始化、系统初始化,然后配置LCD 屏幕设置 ,运行时先调用跑马灯延时程序 Timedelay() ,跑马灯运行一周后,置开发板上 D7、D8 灯亮灭,通过信号传递置 LC
9、D 屏幕上模拟 D7D8 灯亮灭, 接着调用Timedelay()函数,循环任务。二、实验结果测试测试方法: 在移植好的 UCOSII 项目中添加 LCD 的驱动程序。 (方法参见第一章 第二节) 在 main.c 文件中编写程序(源程序见附录) ,先使用画图函数绘出包含跑马灯,模拟 D7、D8 两灯在内的 LCD 界,用函数 timedelay()控制跑马灯运行,timedelay()亦是延时函数。D7、D8 两灯每交替闪说一次,调用一次 timedelay()延时函数。 连接电脑和试验箱,编译程序,无错误,把程序下载到 S3C44B0X,观察结果。 观察现象,有问题检查修改 MAIN.C
10、文件。LCD 界面显示如下:图 2三、总结实验结果显示出预期的 LCD 界面,LCD 屏幕显示预定图案(如图 2) 。屏幕上D7、D8 随 CPU 板上的 D7,D8 两灯同步闪烁,而且跑马灯每转一周,两个等交替闪烁一次。说明 LCD 驱动即添加到内核中没有问题,系统工作正常。四、心得体会课程设计完成了,在这个过程中我学到了很多东西。我对嵌入式系统有了更加深入的了解,对书本上的知识也有了更加深刻的理解,对以前有些含糊不理解的地方也有了新的认识。学会使用嵌入式系统实现问题解决的一般过程,在 UCOSII 下,LCD 驱动程序的结构,以及 LCD 驱动程序怎样添加道内核中去,也能够使用嵌入式系统设
11、计制作一些简单实例。这次课程设计给我们理论联系实际的机会,书本上的东西很抽象,通过这次课程设计,能够把自己的想法和设计实现是一件很开心的事情,而依靠自己独立思考发现并解决一个问题也更是一件开心的事情。课程设计中也遇到了许多问题,比如:老师给的参考程序并不能是 LCD 屏幕和 CPU实验板上的灯同步闪烁,最后多次检查并和同学讨论才发现问题所在,问题程序代码如下:for(i=0;i100000;i+);rPCONB = 0x7cf;rPDATB = 0x7ef;for(i=0;i100000;i+); /*问题所在* 处理函数当设置 CPU 板 D7、D8 灯亮灭后,又通过 for(i=0;i10
12、0000;i+);延时一段时间,才去修改 LCD 屏幕上的 LCD 两个灯 ,当去掉第二行延时代码时,LCD 屏幕模拟的灯泡和 CPU 实验板上的 D7、D8 等同步闪烁。课程设计让我认识到个人的力量是渺小的,依靠一个人的努力也是不够的,许多事情只有靠大家精诚合作,一起思考讨论,分工协作,才能完成。大家之间要默契配合,相互理解,阐述各自对问题不同看法、不同理解的相互交流是发现问题学的新知的良好契机。课程设计很快就结束了,我觉得最大的收获就是能够理论联系实际,把书本上的知识活学活用道实际中来解决一些实际问题,这样才能发挥用途。独立思考解决问题,并能够接受他人意见来修正完善自己的想法,最终付诸于实
13、现。五、参考文献1 王永,何立民嵌入式系统原理与设计M浙江:浙江大学出版社2 Jean J. Labrosse 著 ; 邵贝贝等译嵌入式实时操作系统 C/OS- 第 2 版M 北京:北京航空航天大学出版社六、附 录1.主函数void Main(void) Target_Init(); / ARMII 实验系统的初始化,包括 CPU 板GUI_Init();OSInit(); / 操作系统的初始化Send_D7light_Sem = OSSemCreate(0); /创建信号量Send_LCD_Sem = OSSemCreate(0);OSTaskCreate(Task_1, (void *)0
14、, (OS_STK *) OSTaskCreate(Task_2, (void *)0, (OS_STK *)OSSemPost(Send_LCD_Sem);OSStart();2.跑马灯闪烁程序(即延时程序)void timedelay() INT32U i,k ;for(i=0;i8;i+)k=i%8;switch(k)case 0 : Set_Color(GUI_RED); Fill_Circle (220, 80, 20); /跑马灯 1 亮Set_Color(GUI_GREEN);Fill_Circle (262, 98, 20); /跑马灯 2 灭Fill_Circle (280,
15、 140, 20); /跑马灯 3 灭Fill_Circle (262, 182, 20); /跑马灯 4 灭Fill_Circle (220, 200, 20); /跑马灯 5 灭Fill_Circle (178, 182, 20); /跑马灯 6 灭Fill_Circle (160, 140, 20); /跑马灯 7 灭Fill_Circle (178, 98, 20); /跑马灯 8 灭break;case 1 : 处理函数 1; /省略,类似 case 0 处理函数case 2 : 处理函数 2; /省略,类似 case 0 处理函数case 3 : 处理函数 3; /省略,类似 ca
16、se 0 处理函数case 4 : 处理函数 4; /省略,类似 case 0 处理函数case 5 : 处理函数 5; /省略,类似 case 0 处理函数case 6 : 处理函数 6; /省略,类似 case 0 处理函数case 7 : 处理函数 7; /省略,类似 case 0 处理函数3.控制 CPU 板上 D7、D8 和 LCD 模拟灯同步闪烁 部分程序for(;) OSSemPend(Send_D7light_Sem, 0, if(flag=0)Set_Color(GUI_RED);Fill_Circle(60, 160, 20); /LCD 模拟 D7 亮 Set_Color
17、(GUI_BLACK);Fill_Circle(60, 100, 20); flag = 1;else Set_Color(GUI_BLACK);Fill_Circle(60, 160, 20); /LCD 模拟 D8 亮Set_Color(GUI_RED);Fill_Circle(60, 100, 20); flag = 0;OSSemPost(Send_LCD_Sem);void Task_1(void *pdata)INT8U err;INT32U flag=0;Rtc_Tick_Init(); /打开时钟节拍,让操作系统跑起来for(;)OSSemPend(Send_LCD_Sem, 0, if(flag=0)timedelay(); /调用延时rPCONB = 0x7cf;rPDATB = 0x7ef; /CPU 板上 D7 亮flag = 1;elsetimedelay(); /调用延时rPCONB = 0x7cf;rPDATB = 0x7df; /CPU 板上 D8 亮flag = 0;OSSemPost(Send_D7light_Sem);