资源描述
河海大学物联网工程学院
课程设计报告
题 目 基于LCD的电子时钟实验
专业、学号 电信 、
授课班号
完成时间 2013.07.05
课程设计(报告)任务书
(理 工 科 类)
Ⅰ、课程设计(报告)题目:
基于LCD的电子时钟实验
Ⅱ、课程设计(论文)工作内容
一、课程设计目标
1、培养综合运用知识和独立开展实践创新的能力;
2、培养学生的编程能力、用计算机解决实际问题的能力。
3、学习LCD与ARM的LCD的控制器的接口原理;
4、掌握内置LCD控制器驱动编写方法;
5、RTC控制方法。
二、研究方法及手段应用
1、将任务分成若干模块,查阅相关论文资料,分模块调试和完成任务;
2、查阅网上的相关素材,查阅相关论文资料,进行比较、研究;
3、在独立思考的基础上,请教老师,和同组同学讨论、学习;
4、运用Proteus仿真环境、S3C44B0x实验箱实验平台进行实验调试;
5、学习并使用使用ADS1.2编译汇编语言和C语言,连接生成Hex文件和Axf文件。
三、课程设计预期效果
1、完成实验环境搭建;
2、分模块调试和编译;
3、组合并完善程序。
4、联合仿真软件运行程序
5、显示时钟界面;
6、动态显示当前的时间,包括:年、月、日、时、分、秒,时针,分针、秒针必须为动态实时指示当前的时间;
学生姓名: 刘晓婷 专业年级: 电信、10级
河海大学本科课程设计报告
目 录
前 言 ………………………………………………………………………………………………1
第一章 系统设计 …………………………………………………………………………………2
第一节 课题目标及总体方案…………………………………………………………………..2
………………
第二节……………………………..
…………………
第二章 实验(测试)结果及讨论……….……………………………………………………….5
………………
第三章 结论………………………………………………………………………………………10
………………
心得体会…………………………………………………………………………………………42
参考文献 …………………………………………………………………………………………43
附 录 …………………………………………………………………………………………44
一、源程序………………………………………………………………………………………60
二、其他………………………………………………………………………………………61
- 21 -
前 言
计算机技术及集成电路技术的飞速发展,嵌入式技术的日渐普及,使其在通讯、网络、工控、医疗、电子等领域发挥着越来越重要的作用。
通常我们常用的LCD显示模块,有两种,一是带有驱动电路的LCD显示模块,一是不带驱动电路的LCD显示屏。大部分ARM处理器中都集成了LCD的控制器,所以,针对ARM芯片,一般不使用带驱动电路的LCD显示模块。S3C44B0X 中具有内置的LCD 控制器,它能将显示缓存(在SDRAM存储器中)中的LCD图像数据传输到外部的LCD驱动电路上的逻辑功能。
实时时钟(RTC)器件是一种能提供日历/时钟、数据存储等功能的专用集成电路,常用作各种计算机系统的时钟信号源和参数设置存储电路。RTC具有计时准确、耗电低和体积小等特点,特别适用于在各种嵌入式系统忠记录事件发生的时间和相关信息,尤其是在通信工程、电力自动化、工业控制等自动化程度较高领域的无人职守环境。随着集成电路技术的不断发展,RTC器件的新品也不断推出。这些新品不仅具有准确的RTC,还有大容量的存储器、温度传感器和A/D数据采集通道等,已成为集RTC、数据采集和存储于一体的综合功能器件,特别适用于以微控制器为核心的嵌入式系统。
通过S3C44B0X实验系统板实现LCD电子时钟的设计,可以增强我们的自学能力和思考能力,掌握科学研究的方法,提高信息检索的能力以及获取与时俱进知识的能力。同时,使我们深刻学习了ARM的相关知识,增强对实际电路的感性认识,提高了分析问题,处理问题的能力。
关键字:S3C44B0X 、嵌入式、电子时钟
第一章 系统设计
第一节 课题目标及总体方案
本实验是基于ARM处理器而设计的实时时钟,综合性较强,涉及到RTC外部中断,C语言编程等知识。需使用到中断,涉及对外部中断进行初始化,其中有规定优先级,中断触发方式,中断地址分配。采用液晶模块LCD显示实时时间,同样要对它进行初始化,包括检查总线忙与闲,传送地址,传送数据及显示函数的编程。
运用ads1.2编译汇编语言和C语言,连接生成Hex文件和Axf文件。使用PROTEUS 仿真,选用ARM7 LPC2106 芯片和LCD12864,导入Hex文件,然后进行软件仿真调试。将Axf文件下载到S3C44B0试验箱上,通过LCD实物调试程序,完成电子时钟计时功能。
第二节 相关组件说明
一、LCD显示原理
S3C44B0X 中具有内置的LCD 控制器,它能将显示缓存(在SDRAM存储器中)中的LCD图像数据传输到外部的LCD驱动电路上的逻辑功能。它支持单色、4级、16级灰度LCD显示,以及256彩色LCD显示。在显示灰度时,它采用时间抖动算法(time-based dithering algorithm)和帧率控制 (Frame Rate Control)方法,在显示彩色时,它采用RGB的格式,即RED、GREEN、BLUE,三色混合调色。通过软件编程,可以实现233或332的RGB调色的格式。对于不同尺寸的LCD显示器,它们会有不同的垂直和水平象素点、不同的数据宽度、不同的接口时间及刷新率,通过对LCD 控制器中的相应寄存器写入不同的值,来配置不同的LCD 显示板。本次课设的显示模式设置为8bit单扫描模式。
二、 proteus简介
Proteus软件是英国Labcenter electronics公司出版的EDA工具软件。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前最好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器。
在PROTEUS绘制好原理图后,调入已编译好的目标代码文件:*.HEX,可以在PROTEUS的原理图中看到模拟的实物运行状态和过程。PROTEUS不仅可将许多单片机实例功能形象化,也可将许多单片机实例运行过程形象化。前者可在相当程度上得到实物演示实验的效果,后者则是实物演示实验难以达到的效果。它的元器件、连接线路等却和传统的单片机实验硬件高度对应。这在相当程度上替代了传统的单片机实验教学的功能,例:元器件选择、电路连接、电路检测、电路修改、软件调试、运行结果等。
三、S3C44B0X实验系统简介
EL-ARM-830 型教学实验系统属于一种综合的教学实验系统,该系统采用了目前在国内普遍认同的ARM7TDMI 核,32 位微处理器,实现了多模块的应用实验。它是集学习、应用编程、开发研究于一体ARM 实验教学系统。用户可根据自己的需求选用不同类型的CPU 适配板,在不需要改变任何配置情况下,完成从ARM7 到ARM9 的升级,同时,实验系统上的Tech_V 总线能够拓展较为丰富的实验接口板。用户在了解Tech_V 标准后,更能研发出不同用途的实验接口板。除此之外,在实验板上有丰富的外围扩展资源(数字、模拟信号发生器,数字量IO 输入输出,语音编解码、人机接口等单元),可以完成ARM的基础实验、算法实验和数据通信实验、以太网验。其功能框图如下所示。
四、USOSII操作系统简介
μC/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。
μC/OS-II 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌入到开发的产品中。μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。μC/OS-II 已经移植到了几乎所有知名的CPU 上。
第三节 流程框图
第四节 主要程序分析
一、 程序中初始化包括
1.Lcd的初始化:
U16 LCD_Init(U8 Lcd_Bpp)
{
switch(Lcd_Bpp)
{
Case 8:
rLCDCON1=(0)|(2<<5)|(MVAL_USED<<7)|(0x1<<8)|(0x1<<10)|(CLKVAL_COLOR<<12);
rLCDCON2=(LINEVAL)|(HOZVAL_COLOR<<10)|(10<<21);
rLCDSADDR1= (0x3<<27) | ( ((U32)Video_StartBuffer>>22)<<21 )| M5D((U32)Video_StartBuffer>>1);
rLCDSADDR2=M5D((((U32)Video_StartBuffer +(SCR_XSIZE*LCD_YSIZE))>>1)) | (MVAL<<21)|1<<29;
rLCDSADDR3= (LCD_XSIZE/2) | ( ((SCR_XSIZE-LCD_XSIZE)/2)<<9 );
rREDLUT =0xfdb96420;
rGREENLUT=0xfdb96420;
rBLUELUT =0xfb40;
rDITHMODE=0x0;
rDP1_2 =0xa5a5;
rDP4_7 =0xba5da65;
rDP3_5 =0xa5a5f;
rDP2_3 =0xd6b;
rDP5_7 =0xeb7b5ed;
rDP3_4 =0x7dbe;
rDP4_5 =0x7ebdf;
rDP6_7 =0x7fdfbfe;
rDITHMODE=0x12210;
rLCDCON1=(1)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<12);
break;
default:
return 1;
}
return 0;
}
2.中断向量的初始化:
void KeyINT_Init(void) {
if ((rINTPND & BIT_EINT4567))
{
SPC = BIT_EINT4567;
}
rINTMSK = ~(BIT_GLOBAL|BIT_EINT4567);
}
3.RTC的初始化:
void Rtc_Tick_Init(void)
{
if ((rINTPND & BIT_TICK))
{
rI_ISPC = BIT_TICK;
}
rINTMSK &= ~(BIT_GLOBAL | BIT_TICK);
rRTCCON = 0x0;
rTICINT = 1 | (1<<7)
}
void Rtc_Tick_Init0(void)
{
if ((rINTPND & BIT_TICK))
{
rI_ISPC = BIT_TICK;
}
rINTMSK &= ~(BIT_GLOBAL | BIT_TICK);
rRTCCON = 0x0;
rTICINT = 1 | (1<<6);
}
二、 功能模块
1.画指针模块
int SpaceXS[61]={110,115,120,125,130,135,
139,143,147,151,155,
156,157,158,159,160,
159,158,157,156,155,
151,147,143,139,135,
130,125,120,115,110,
105,100,95,90,85,
81,77,73,69,65,
64,63,62,61,60,
61,62,63,64,65,
69,73,77,81,85,
90,95,100,105,110,
},
SpaceYS[61]={30,31,32,33,34,
35,39,43,47,51,
55,60,65,70,75,
80,85,90,95,100,
105,109,113,117,121,
125,126,127,128,129,
130,129,128,127,126,
125,121,117,113,109,
105,100,95,90,85,
80,75,70,65,60,
55,51,47,43,39,
35,34,33,32,31,30},
SpaceXM[61]={110,114,118,122,126,130,133,136,139,142,
145,146,147,148,149,150,149,148,147,146,
145,142,139,136,133,130,126,122,118,114,
110,106,102,98,94,90,87,84,81,78,
75,74,73,72,71,70,71,72,73,74,
75,78,81,84,87,90,94,98,102,106,
110
},
SpaceYM[61]={40,41,42,43,44,45,48,51,54,57,
60,64,68,72,76,80,84,88,92,96,
100,103,106,109,112,115,116,117,118,119,
120,119,118,117,116,115,112,109,106,103,
100,96,92,88,84,80,76,72,68,64,
60,57,54,51,48,45,44,43,42,41,
40
},
SpaceXH[13]={110,125,135,140,135,125,110,95,85,80,85,95,110},
SpaceYH[13]={50,55,65,80,95,105,110,105,95,80,65,55,50},
2、显示模块
void show1()
{
Set_Color(GUI_GREEN);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"姓名:唐 蔚"CN_end,47,170);
Set_Color(GUI_GREEN);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"学号:"CN_end,163,170);
Set_Color(GUI_GREEN);
Set_Font (&GUI_Font8x16);
Disp_String ("1062910122",211,170);
Set_Color(GUI_GREEN);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"姓名:郭志中"CN_end,47,190);
Set_Color(GUI_GREEN);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"学号:"CN_end,163,190);
Set_Color(GUI_GREEN);
Set_Font (&GUI_Font8x16);
Disp_String ("1062910110",211,190);
Set_Color(GUI_BLUE);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"专业:电子科学与技术"CN_end,82,150);
Set_Color(GUI_BLUE);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"嵌入式课程设计"CN_end,105,5);
Set_Color(GUI_BLUE);
Set_Font(&GUI_Font8x16);
}
void show2()
{
Set_Color(GUI_BLUE);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"姓名:唐 蔚"CN_end,47,170);
Set_Color(GUI_BLUE);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"学号:"CN_end,163,170);
Set_Color(GUI_BLUE);
Set_Font (&GUI_Font8x16);
Disp_String ("1062910122",211,170);
Set_Color(GUI_BLUE);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"姓名:郭志中"CN_end,47,190);
Set_Color(GUI_BLUE);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"学号:"CN_end,163,190);
Set_Color(GUI_BLUE);
Set_Font (&GUI_Font8x16);
Disp_String ("1062910110",211,190);
Set_Color(GUI_GREEN);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"专业:电子科学与技术"CN_end,82,150);
Set_Color(GUI_GREEN);
Set_Font (&CHINESE_FONT16);
Disp_String (CN_start"嵌入式课程设计"CN_end,105,5);
Set_Color(GUI_GREEN);
Set_Font(&GUI_Font8x16);
}
void Shows()
{
Set_Color(GUI_GRAY); //擦除上一秒的
Draw_Line(x_line,y_line,*Placex,*Placey);
Placex=Placex+1;
Placey=Placey+1;
Set_Color(GUI_YELLOW); //显示下一秒的
Draw_Line(x_line,y_line,*Placex,*Placey);
Set_Color(GUI_RED); //显示下一分的
Draw_Line(x_line,y_line,*Placexm,*Placeym);
Set_Color(GUI_GREEN); //显示下一时的
Draw_Line(x_line,y_line,*Placexh,*Placeyh);
if(Placex==&SpaceXS[60]&&Placey==&SpaceYS[60])//复位
{
Placex=&SpaceXS[0];
Placey=&SpaceYS[0];
}
}
void Showm()
{
Set_Color(GUI_GRAY); //擦除上一分的
Draw_Line(x_line,y_line,*Placexm,*Placeym);
Placexm=Placexm+1;
Placeym=Placeym+1;
Set_Color(GUI_RED); //显示下一分的
Draw_Line(x_line,y_line,*Placexm,*Placeym);
Set_Color(GUI_GREEN); //显示下一时的
Draw_Line(x_line,y_line,*Placexh,*Placeyh);
if(Placexm==&SpaceXM[60]&&Placeym==&SpaceYM[60])
{
Placexm=&SpaceXM[0];
Placeym=&SpaceYM[0];
}
}
void Showh()
{
Set_Color(GUI_GRAY); //擦除上一时的
Draw_Line(x_line,y_line,*Placexh,*Placeyh);
Placexh=Placexh+1;
Placeyh=Placeyh+1;
Set_Color(GUI_GREEN); //显示下一时的
Draw_Line(x_line,y_line,*Placexh,*Placeyh);
if(Placexh==&SpaceXH[12]&&Placeyh==&SpaceYH[12])
{
Placexh=&SpaceXH[0];
Placeyh=&SpaceYH[0];
}
}
3、计时模块
void Task_1(void *pdata)
{
for(;;)
{
/***********全屏颜色设计**************/
/*************时 钟 位 置************/
Show_Color();
Show_ht();
/*********点 的 坐 标***************/
Shouw_Cricle();
/*************设定背景颜色API*************/
Set_Color(GUI_YELLOW); //显示
Draw_Line(x_line,y_line,*Placex,*Placey);
Display_Time(106, 160);//时间
do
{
show1();
Delay(600);
show2();
Delay(600);
sec++;
Shows();
if (sec >= 60)
{
sec = 0;
min++;
Showm();
if (min >= 60)
{
min = 0;
hour++;
Showh();
if (hour >= 23)
{
hour = 0;
day++;
if(day >=31)
{
day = 1;
mon++;
if(mon >= 12)
{
mon = 1;
yea1++;
}
}
}
}
}
Display_Time(106, 160);//时间 日期
}while(1);
}
}
第二章 实验(测试)结果及讨论
第一节 proteus7.1仿真调试
在应用这个软件的过程中发现了我们写好的程序在上面老是出现编译错误,在处理之后还是有4个错误,使我们无法编译通过,我们在网上搜索资料,其他同志在使用时也遇到类似的错误,很多人都说是兼容性问题。我们就把时间花在了实验想的调试上面。
第二节 S3C44B0X系统板调试
我们将编译软件ADS1.2生成的axf文件烧写到S3C44B0系统板上,效果如下页图所示。该LCD电子时钟能够动态显示当前的时间,包括:年、月、日、时、分、秒,时针、分针和秒针为动态实时指示当前的时间。
第三节 实际效果图
生成Hex文件后即可用串口连接实验箱观察实验现象。LCD液晶显示出现如下画面:动态显示时钟表盘界面、数字时钟同步显示、显示年月日、小组成员姓名显示。其中时间、日期、小组成员姓名的位置可通过调节坐标改变。
第三章 结 论
综合效果图:
以上为protues部分设计的,ads程序见附录。
心得体会
说实话,到目前为止所做的课设中,这次的嵌入式课设最不尽人意。
刚开始毫无头绪,即使在查阅了大量相关资料的基础上。后来,手上有了一份参考程序,打开一看,顿时懵了。当时想如果纯粹靠我自己或者和同学讨论,恐怕很难完成这次课设吧。于是,实验室刚开放,我就立刻去调试程序,通过观察试验箱上显示的结果来理解程序。一个模块一个模块对应的理解下去之后,思路开始清晰起来。每当遇到一行程序不懂或者有疑问时,比如这行程序起什么作用、可不可以删掉或者可不可以换个位置,我都通过程序的相关改动结合实验结果的观察将这些疑问解决掉了。同时,同学的帮助也给了我很多的启发,非常感谢他们。
但不得不承认,关于μC/OS-II操作系统方面理解的很不透彻。验收时,我只是把时钟界面的构建部分理解了,没有过多的加深对操作系统μC/OS-II的学习,所以验收时对于老师的提问也是磕磕绊绊。老师让我充分认识到了自己在这次课设中的不足,谢谢老师。
因而,在编写这份报告前,我又认真地上网搜索了μC/OS-II操作系统的简介,尤其是它的优点和任务调度方面。在写这份报告时,我也许还没能完全弄懂μC/OS-II操作系统,但我相信,只要努力过,总会有收获。
回顾整个课程设计过程,感慨颇多,从理论到实践,我学到很多东西,不仅巩固了以前所学过的理论知识,而且学到了很多在书本上学不到的东西。也更深刻得明白ARM的应用领域,我们可以运用ARM技术来做些什么。通过本次课设,增强了动手实践能力,也懂得了,光学习理论知识是远远不够的,必须把它运用到实际中去,充分发挥所学知识的作用。
通过此次实时时钟的设计,C语言的编程,我们开始了ARM的实际应用的学习,一方面,是我们养成了遵循ARM的嵌入式系统项目开发步骤的习惯;另一方面,使我们能够利用所学的ARM的知识设计出一些简单的东西,为以后进行更深层次的学习打下基础。
参考文献
[1] 谢自美,电子线路设计、实验、测试,华中理工大学出版社,2003。
[2] 宋春荣,通用集成电路速查手册,山东科学技术出版社,1995。
[3] Arnold Berger,嵌入式系统设计,吕骏 译, 北京:电子工业出版社, 2002
[4] 桑楠. 嵌入式系统原理及应用开发技术,北京:北京航空航天大学出版社, 2002
附 录
一、 源程序:
void c_init()
{
wr_circle(123,79,1,1);
wr_circle(123,79,2,1);
wr_circle(63,139,1,1);
wr_circle(63,139,2,1);
wr_circle(3,79,1,1);
wr_circle(3,79,2,1);
wr_circle(63,19,1,1);
wr_circle(63,19,2,1);
wr_circle(115,109,1,1);
wr_circle(93,131,1,1);
wr_circle(33,131,1,1);
wr_circle(11,109,1,1);
wr_circle(11,49,1,1);
wr_circle(33,27,1,1);
wr_circle(93,27,1,1);
wr_circle(115,49,1,1);
wr_point(c_ox,c_oy,1);
wr_circle(c_ox,c_oy,2,1);
wr_circle(c_ox,c_oy,62,1);
}
void move(unsigned char n)
{
line(c_ox,c_oy,sec[2*n],sec[2*n+1],1);
}
#define fpclk 2764800
unsigned char min_n;
unsigned int hou_n;
void rtc_init()
{
PREINT=fpclk/32768-1;
PREFRAC=fpclk-(fpclk/32768)*32768;
YEAR=2010;
MONTH=1;
DOM=15;
HOUR=11;
MIN=1;
SEC=36;
CIIR=0x01;
ILR=0x01;
CCR=0x01;
}
void __irq rtc_int()
{
ILR=0x01;
wr_char(9,6,0x10+HOUR/10);
wr_char(9,7,0x10+HOUR%10);
wr_char(9,8,0x1a);
wr_char(9,9,0x10+MIN/10);
wr_char(9,10,0x10+MIN%10);
wr_char(9,11,0x1a);
wr_char(9,12,0x10+SEC/10);
wr_char(9,13,0x10+SEC%10);
wr_char(11,5,0x10+YEAR/1000);
wr_char(11,6,0x10+YEAR%1000/100);
wr_char(11,7,0x10+YEAR%100/10);
wr_char(11,8,0x10+YEAR%10);
wr_char(11,9,0xf);
wr_char(11,10,0x10+MONTH/10);
wr_char(11,11,0x10+MONTH%10);
wr_char(11,12,0xf);
wr_char(11,13,0x10+DOM/10);
wr_char(11,14,0x10+DOM%10);
if(SEC==0)
{
line(c_ox,c_oy,sec[59*2],sec[59*2+1],0);
line(c_ox,c_oy,sec[0],sec[1],1);
}
else
{
line(c_ox,c_oy,sec[SEC*2-2],sec[SEC*2-1],0);
line(c_ox,c_oy,sec[SEC*2],sec[SEC*2+1],1);
}
if(MIN==0)
{
line(c_ox,c_oy,min[59*2],min[59*2+1],0);
line(c_ox,c_oy,min[0],min[1],1);
}
else
{
line(c_ox,c_oy,min[MIN*2-2],min[MIN*2-1],0);
line(c_ox,c_oy,min[MIN*2],min[MIN*2+1],1);
}
if(HOUR>11)
hou_n=((HOUR-12)*60+MIN)/12;
else
hou_n=(HOUR*60+MIN)/12;
if(hou_
展开阅读全文