基于单片机的智能调光灯设计_第1页
基于单片机的智能调光灯设计_第2页
基于单片机的智能调光灯设计_第3页
基于单片机的智能调光灯设计_第4页
基于单片机的智能调光灯设计_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本科毕业设计论文题目基于单片机的智能调光灯设计专业名称自动化学生姓名指导教师毕业时间设计论文设计论文一、题目:基于单片机的智能调光灯设计二、指导思想和目的要求:通过毕业设计,使学生对所学电子工艺、电路基础知识、模电、数电、等电子基础课程的基本知识加深理解,掌握单片机的基本指令及基本结构,并将其与实际工程应用紧密结合起来,培养创新意识,增强分析问题解决问题能力,为尽快进入社会角色,熟悉相关开发工作流程、项目小组组成、分工、合作方式方法等。增强团队合作意识,提高基本工作技能,为即将踏入社会奠定理论和实践基础。内容:设计一电路,不仅亮度可调,还可以显示时间等功能。具体要求如下:1)显示当前的时间,24时制的时、分、秒;2)可调节时间;3)可调节LED光亮度;步骤:l、了解所设计系统的工作原理及要求。2、设计单片机工作的基本电路,如:晶振电路、复位电路。3、根据系统设计要求选择发光二极管、按键等模拟部件。4、设计系统基本电路。5、绘制PRTUSE电原理图并编写系统控制程序。6、联机进行系统仿真调试。 三、进度与要求:1.第一周~第一周收集设计系统相关资料。2.第二周~第三周用PROTUSE设计硬件原理图并进行器件选型。3.第四周~第六周编写系统各功能模块控制程序。4.第七周~第十周联机进行系统调试。5.第十一周~第十二周整理并组织论文。6.第十三周~第十四周完成修改稿,定稿,打印,交评阅。7.第十五周~第十六周评阅与答辩学生屈晓东指导教师李雪霞系主任史仪凯第一章绪论1.1选题意义现代人类生活中所用的几乎每件有电子器件的产品中都会集成有单片机。手机、电话、计算器、家用电器、电子玩具、掌上电脑以及鼠标等电子产品中都含有单片机。智能灯不是传统灯具,而是智能设备的一种,除了智能灯体,还有一个手持智能控制设备,智能灯控制设备具备计算能力和网络联接能力,通过应用程序,功能可以不断扩展。智能灯的核心功能是控制、灯光效果、创作、分享、光与音乐互动、光提升健康和幸福。开关灯的控制,不但可以通过控制器,手动遥控灯的开关,还可以进行定时开关灯的控制,可以设定不同的时间开灯关灯。其次是对光的控制,光的亮度,光的冷暖,光的色彩都可以连续手动控制或自动控制。白炽灯和金卤灯在调光领域应用得比较广泛,但随着节能减排的不断推广,LED可调光在攻克了调光技术障碍后,开始呈现发展趋势,LED可调光与LED红外智能灯管、LED声光控等一起统称为LED智能化系列,在LED普通灯具价格竞争日趋激烈的今天,LED智能化已经成为大型LED照明企业的发展方向。电子钟已成为人们日常生活中必不可少的物品,广泛用于个人家庭以及车站、码头、剧院、办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。随着技术的发展,人们已不再满足于钟表原先简单的报时功能,希望出现一些新的功能,诸如日历的显示、闹钟的非接触式止闹跑表功能、重要日期倒计时显示等,以带来更大的方便,而所有这些,又都是以数字化的电子时钟为基础的。因此,研究实用电子钟的应用,有着非常现实的意义,具有很大的实用价值。由于数字集成电路技术的发展和采用了先进的石英技术,使电子钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。现在市场上已有现成的电子钟集成电路芯片出售,价格便宜,使用也灵活,如可以随意设置时、分、秒的输出,改变显示数字的大小等,并且由于集成电路技术的发展,特别是MOS集成电路技术的发展,使电子钟具有体积小、携带方便的特点,这里介绍的实用电子钟可以满足使用者的一些基本要求,输出方式灵活、功耗低、计时准确、性能稳定、维护方便等优点。实用电子钟是一个时间控制系统,既能作为一般的时间显示器,也可作为一个定时控制器,驱动负载或显示信息,同时可以根据需要扩展其功能。在此项目的设计研究过程中需综合运用所学的数字电子技术、单片机原理与应用等课程的知识,掌握实用电子钟的设计、组装与调试方法,利用现代的单片机等新电子技术以及现代的设计手段,系统地培养了综合设计、操作调试、故障处理的能力,达到综合素质以及创新能力的提高。1.2设计要求1.2.1功能实现(1)LED调光灯功能:当按下按键K0、K1、K2分为一级亮度红灯、二级亮度黄灯和三级亮度绿灯来实现。(2)时间、日期显示:系统采用24小时制。正常情况下,系统显示当前日期、时间,由LCD显示。(3)设置功能:用户可以对LED灯光的亮度进行调节,对时间、日期、星期进行设置。用户依次进入日期设置、星期设置、时间设置。在进行设置时,光标停留在相应位,按下K4键、K5键对数值进行加、减调整。通过K3键,在各个数位间移动。 通过K6键,确定所设置的时间。1.2.2系统所需功能模块 由功能分析,台灯系统分为灯光模块、键盘模块、显示模块、时钟部分、电源模块和单片机模块,考虑成本时钟模块可由单片机内部计数器模拟实现。(1)灯光模块用D0~D12个LED灯实现。(2)按键模块分为调光3个按键和调节时间4个按键,分别是K0、K1、K2和K3、K4、K5、K6。(3)显示模块负责显示系统的日期、星期、时间。(4)电源模块采用+5V直流供电。(5)单片机模块内部计数器负责LED灯光和时钟,通过程序模拟生成亮度调节和时间走时。同时负责扫描键盘,并将时间送给LCD显示。1.3系统基本方案选择和论证1.3.1单片机芯片的选择方案和论证方案一:采用STC89C52芯片作为硬件核心,采用FlashROM,内部具有4KBROM存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。方案二:采用AT89C52,片内ROM全都采用FlashROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KBROM存储空间,同样具有STC89C52的功能,且具有在线编程可擦除技术,对所下载的程序能够加密,比较安全。当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。所以选择采用AT89C52作为主控制系统。1.3.2显示模块选择方案和论证方案一:采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以不用此种作为显示。方案二:采用LED数码管动态扫描,虽然LED数码管价格适中,但要显示多个数字所需要的个数偏多,功耗较大,所以也不用此种作为显示。方案三:采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,与普通数码管相比功耗较小,硬件连接简单。所以显示部分采用1602液晶显示。1.3.3时钟芯片的选择方案和论证方案一:直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。所以不采用此方案。方案二:采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、周、月、年以及闰年补偿的年进行计数,而且精度高,RAM作为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA。第二章系统的硬件设计2.1系统模块框图六大模块以AT89C52单片机为控制核心,实现了该智能台灯的各项要求,外接一个5V的直流电源,为整个系统供电。图2-1系统结构示意图2.2系统整体硬件图该设计是以AT89C52单片机为控制核心的集多种功能于一体的智能LED台灯。该台灯具有灯光亮度调节功能;具有时间显示功能。硬件设计分为单片机控制模块、按键模块、台灯模块、时钟模块、闹铃模块、显示模块等五个部分。单片机控制用AT89C52,显示模块用LCD1602液晶显示、时间、日期等内容,按键模块用来调整时间、日期、LED的亮度等,时钟用DS1302时钟芯片,台灯模块用13颗LED,通过按键K0、K1、K2调节灯光的亮度,分为一级亮度、二级亮度和三级亮度。图2-2系统整体硬件图2.3各模块电路的设计2.3.1单片机控制模块单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。从上世纪80年代,由当时的4位、8位单片机,发展到现在的300M的高速单片机。AT89C52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3,MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。图2-3AT89C52单片机控制模块2.3.2晶振/复位模块晶振是晶体振荡器的简称,在电气上它可以等效成一个电容和一个电阻并联再串联一个电容的二端网络,电工学上这个网络有两个谐振点,以频率的高低分其中较低的频率是串联谐振,较高的频率是并联谐振。由于晶体自身的特性致使这两个频率的距离相当的接近,在这个极窄的频率范围内,晶振等效为一个电感,所以只要晶振的两端并联上合适的电容它就会组成并联谐振电路。晶振是给单片机提供工作信号脉冲的。这个脉冲就是单片机的工作速度。单片机的工作频率是有范围的,不能太大。图中19与18引脚分别为XTAL1、XTAL2,他们分别接晶振的输入与输出,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.因为一个机器周期含有6个状态周期,而每个状态周期为2个振荡周期,所以一个机器周期共有12个振荡周期。本设计选择晶振频率为12MHz,输入芯片震荡周期为1/12μs,一个机器周期为1μs。图2-4晶振电路模块复位电路,就是利用它把电路恢复到起始状态。就像计算器的清零按钮的作用一样,以便回到原始状态,重新进行计算。和计算器清零按钮有所不同的是,复位电路启动的手段有所不同。一是在给电路通电时马上进行复位操作;二是在必要时可以由手动操作;三是根据程序或者电路运行的需要自动地进行。在RST复位输入引脚上接一电容至Vcc端,下接一个电阻到地即可。复位电路工作原理如下图所示,Vcc上电时,C3充电,在10K电阻上出现电压,使得单片机复位;几个毫秒后,C3充满,10K电阻上电流降为0,电压也为0,使得单片机进入工作状态。工作期间,按下K7,C3放电,在10K电阻上出现电压,使得单片机复位。K7松手,C3又充电,几个毫秒后,单片机进入工作状态。第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路。图2-5复位电路模块2.3.3台灯模块台灯模块用13颗LED作为发光系统,每一颗和一个220的电阻串联,用P1.4~P1.6口控制。电阻起限流作用,13个I/O均采用低电平有效方式,即给相应的I/O低电平LED工作。通过按键K0、K1、K2调节灯光的亮度,亮度分为三个等级:一级亮度控制红色的D0灯亮;二级亮度控制黄色的D1、D2、D3、D4灯亮;三级亮度控制绿色的D5、D6、D7、D8、D9、D10、D11、D12灯亮。图2-6台灯模块(1)图2-7台灯模块(2)2.3.4台灯调光按键模块图2-8台灯按键模块按键K0、K1、K2用来调节台灯的亮度,通过按下按键K0可以让台灯变亮,按下按键K1可以让台灯变的更亮,按下按键K2可以让台灯灯光达到最亮。3个I/O均采用低电平有效方式。2.3.5DS1302时钟电路模块下图示出DS1302的引脚排列图,其中Vcc1为后备电源,Vcc2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768KHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电动行时,在Vcc大于等于2.5V之前,RST必须保持低电平。中有在SCLK为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。SCLK始终是输入端。表1DS1302引脚功能表引脚号引脚名称功能1VCC2主电源2、3X1、X2振荡源,外接32768Hz晶振4GND地线5RST复位/片选线6I/O串行数据输入/输出端(双向)7SCLK串行时钟输入端8VCC1后备电源DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲。DS1302的控制字,此控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0。位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。DS1302的日历、时间寄存器内容:“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,“WP”必须为0。当“WP”为1时,写保护位防止对任一寄存器的写操作。图2-9DS1302时钟电路模块2.3.61602LCD显示模块字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。1602LCD分为背光和不带背光两种,基控制大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,引脚功能说明:表21602LCD功能表编号符号引脚说明编号符号引脚说明1Vss电源地9D2数据口2Vcc电源正极10D3数据口3VO液晶显示对比度调节端11D4数据口4RS数据/命令选择端(H/L)12D5数据口5R/W读写选择端(H/L)13D6数据口6E能使信号14D7数据口7D0数据口15BLA背光电源正极8D1数据口16BLK背光电源负极1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表2所示:第1脚:VSS为地电源。第2脚:VDD接5V正电源。第3脚:VEE为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄器。第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。第7~14脚:D0~D7为8位双向数据线。1602LCD的一般初始化(复位)过程延时15mS写指令38H(不检测忙信号)延时5mS写指令38H(不检测忙信号)延时5mS写指令38H(不检测忙信号)以后每次写指令、读/写数据操作均需要检测忙信号写指令38H:显示模式设置写指令08H:显示关闭写指令01H:显示清屏写指令06H:显示光标移动设置写指令0CH:显示开及光标设置LCD1602液晶显示,如下图所示:图2-101602LCD显示模块2.3.7调节时钟按键模块因为有年月日,时分秒几个参数要调,所以设置这几个参数的计数。当按下一个键时,单片机进行相应的操作。根据设计要求需要选择四个独立按键分别为选择、加、减、确定,按键用来调整时间和设置闹钟,调光亮度,各键功能在介绍硬件部分已描述。按键模块下图所示:图2-11调节时钟按键模块第三章系统的软件设计3.1系统软件编程工具C和C++3.1.1C简介C语言是一种计算机程序设计语言,它既具有高级语言的特点,又具有汇编语言的特点。它可以作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。它的应用范围广泛,具备很强的数据处理能力,不仅仅是在软件开发上,而且各类科研都需要用到C语言,适于编写系统软件、三维、二维图形和动画,具体应用例如单片机以及嵌入式系统开发。C程序是由一组变量或是函数的外部对象组成的。函数是一个自我包含的完成一定相关功能的执行代码段。我们可以把函数看成一个“黑盒子”,你只要将数据送进去就能得到结果,而函数内部究竟是如何工作的的,外部程序是不知道的。外部程序所知道的仅限于输入给函数什么以及函数输出什么。函数提供了编制程序的手段,使之容易读、写、理解、排除错误、修改和维护。C程序中函数的数目实际上是不限的,如果说有什么限制的话,那就是,一个C程序中必须至少有一个函数,而且其中必须有一个并且仅有一个以main为名,这个函数称为主函数,整个程序从这个主函数开始执行。C语言程序鼓励和提倡人们把一个大问题划分成一个个子问题,对应于解决一个子问题编制一个函数,因此,C语言程序一般是由大量的小函数而不是由少量大函数构成的,即所谓“小函数构成大程序”。这样的好处是让各部分相互充分独立,并且任务单一。因而这些充分独立的小模块也可以作为一种固定规格的小“构件”,用来构成新的大程序。 3.1.2C++C++是在C语言的基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言。应用较为广泛,是一种静态数据类型检查的,支持多重编程的通用程序设计语言。它支持过程化程序设计,数据抽象,面向对象设计,制作图标等多种程序设计风格。在操作系统和系统使用程序以及需要对硬件进行操作的场合,用C语言明显优于其它高级语言,但在编写大型程序时,C语言仍面临着挑战。C语言是C++的基础,C++和C语言在很多方面是兼容的。C语言是一个结构化语言,它的重点在于算法与数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事物)控制)。C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事物)控制。所以C语言和C++的最大区别在于它们解决问题的思想方法不一样。C++语言的主要特点表现在两个方面,一是尽量兼容C,二是支持面向对象的方法。它操持了C的简洁、高效的接近汇编语言等特点,对C的类型系统进行了改革的扩充,因此C++比C更安全,C++的编译系统能检查出更多的类型错误。另外,由于C语言的广泛使用,因而极大的促进了C++的普及和推广。C++由四个“子语言”组成:C子语言,C++支持C语言的几乎全部功能,主要是c89的部分,在语法上与C语言仅有极微妙的差别(如括号表达式的左右值性,具体请参考C++标准文献)。这部分功能对应于传统的面向过程的编程泛型,并提供了面向函数编程泛型的基础。面向对象的C++语言,C++语言原本不具备面向对象的设计功能,然而随着面向对象编程的概念的普及,C++语言也开发出了支持面向对象功能的版本。这部分功能对应于面向对象的编程泛型。泛型编程语言,C++强大(但容易失控的)模板功能使它能在编译期完成许多工作,从而大大提高运行期效率,并且大大提高了C++的表达能力。STL(C++标准模板库,StandardTemplateLibrary)是一个基于模板技术的库。随着STL的不断发展,它已经逐渐成为C++程序设计中不可或缺的部分,其效率可能比一般的native代码低些,但是其安全性与规范性使它大受欢迎。模板使C++能够支持泛型编程(genericprogramming)和生成式编程(generativeprogramming)的泛型。在C++0X中引入的Lambda,使得程序员可以定义匿名函数,完善了C++对于面向函数的编程泛型的支持。3.2主程序的设计流程图图3-1主程序流程图一给单片机上电,单片机就初始化。通过接收并处理,有人按下开关就工作。然后检开始LED工作显示时间、日期,按键按下,修正时间,设置闹钟系统初始化测按键是否按下,判断工作在那个模式下。液晶还显示当前的时间,日期,最后进入循环。3.3台灯模块编程 3.3.1台灯模块流程图该模块只需给LED红灯D0的P1.4口、黄灯D1到D4的P1.5口和绿灯D5到D12的P1.6口送低电平即可,再通过按键K0、K1、K2调LED灯光亮度。图3-2台灯模块流程图3.3.2台灯模块程序#include<AT89X51.H>sbitK0=P2^5;//调光灯亮度等级开关I/O口分配sbitK1=P2^6;sbitK2=P2^7;sbitD0=P1^4;//LED灯I/O口分配sbitD1=P1^5;sbitD2=P1^5;sbitD3=P1^5;sbitD4=P1^5;sbitD5=P1^6;sbitD6=P1^6;sbitD7=P1^6;sbitD8=P1^6;sbitD9=P1^6;sbitD10=P1^6;sbitD11=P1^6;sbitD12=P1^6;voidmain()//主程序{while(1){if(K0==0)//一级亮度调光开关被按下{D0=0;//D3灯亮}else{D0=1;//D3灯灭}if(K1==0)//二级亮度调光开关被按下{D1=0;//D1,D2,D3,D4灯亮D2=0;D3=0;D4=0;}else{D1=1;//D1,D2,D3,D4灯灭D2=1;D3=1;D4=1;}if(K2==0)//三级亮度调光开关被按下{D5=0;//D5,D6,D7,D8,D9,D10,D11,D12灯亮D6=0;D7=0;D8=0;D9=0;D10=0;D11=0;D12=0;}else{D5=1;//D5,D6,D7,D8,D9,D10,D11,D12灯灭D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;D12=1;}}}3.4LCD1602液晶显示3.4.1时钟设置流程图调整时间用4个调整按钮,1个作为选择控制用,另外3个分别作为加调整,减调整和确定用。图3-3时钟设置流程图3.4.2时钟程序#include<reg51.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedintsbitRS=P2^0; //LCD寄存器选择sbitRW=P2^1; //LCD读写控制sbitEN=P2^2; // LCD启动//*延时子程序*//voidDelayMS(uintK){uchari;while(K--){ for(i=0;i<120;i++); }}//*读取LCD的状态*//ucharRead_LCD_State(){ucharstate;RS=0;RW=1;EN=1;DelayMS(2);state=P0;EN=0;DelayMS(2);returnstate;}//*忙检查*//voidLCD_Busy_Wait(){while((Read_LCD_State()&0x80)==0x80); DelayMS(5);}//*写LCD命令*//voidWrite_LCD_Command(ucharcmd){LCD_Busy_Wait();RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(2);EN=0;}//*向LCD写入数据*//voidWrite_LCD_Data(uchardat){LCD_Busy_Wait();RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(2);EN=0;}//*LCD初始化*//voidInitialize_LCD1602()//液晶初始化函数{Write_LCD_Command(0x38);DelayMS(2); //功能设置,数据长度为8位,双行显示,5×7点阵字体Write_LCD_Command(0x01);DelayMS(2); //清屏Write_LCD_Command(0x06);DelayMS(2);//字符进入模式:屏幕不动,字符后移Write_LCD_Command(0x0c);DelayMS(2); //显示开,关光标}//*设置液晶显示位置*//voidSet_LCD_Position(ucharpos){Write_LCD_Command(pos|0x80); //设置7位的DDRAM地址值}//*在LCD上显示字符串*//voidLCD_Display(ucharp,uchar*str){uchari;Set_LCD_Position(p);for(i=0;i<16;i++){ Write_LCD_Data(str[i]); DelayMS(2); }}//*main.c源程序*////*用DS1302和1602液晶显示的实时时钟*//#include<reg51.h>#include<string.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedintvoidInitialize_LCD1602();//液晶初始化函数voidLCD_Display(ucharp,uchar*str);sbitSDA=P1^0; //DS1302数据线sbitCLK=P1^1; //DS1302时钟线sbitRST=P1^2; //DS1302 复位线sbitk1=P3^4; //选择按键sbitk2=P3^5; //加sbitk3=P3^6; // 减sbitk4=P3^7; // 确定uchartcount=0; ucharMonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};//一年中每个月的天数,二月的天数由年份决定uchar*Week[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};//周日,周一到周六//LCD显示缓冲ucharLCD_DSY_BUFFER1[]={"DATE00-00-00"};ucharLCD_DSY_BUFFER2[]={"TIME00:00:00"};ucharDateTime[7];//所读取的日期时间charAdjust_Index=-1;//当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)ucharChange_Flag[]="-MHDM-Y";//(分,时,日,月,年)不调节秒和周//函数声明voidWrite_Byte_TO_DS1302(ucharX);//向DS1302写入一个字节ucharRead_Byte_FROM_DS1302(); //从DS1302中读取一个字节ucharRead_Data_FROM_DS1302(ucharaddr);//从DS1302指定位置读取数据 ,读数据voidWrite_Data_TO_DS1302(ucharaddr,uchardat);//向DS1302指定位置写入数据,写数据voidSET_DS1302(); //设置时间voidGetTime(); //读取当前时间voidInitialization();//初始化函数//*主程序*//voidmain(){Initialization();while(1){ if(Adjust_Index==-1) GetTime(); }}//*初始化函数*//voidInitialization(){Initialize_LCD1602();//调用液晶初始化函数IE=0x83; //允许中断外部0中断和T0中断IP=0x01; // 设置中断优先级IT0=0x01; // 设置外部中断的脉冲触发方式TMOD=0x01;//设置定时器的工作方式,为方式1TH0=-50000/256;//写入初值TL0=-50000%256;//写入初值TR0=1;// 启动定时器}//*写字节函数,向DS1302写入一个字节*//voidWrite_Byte_TO_DS1302(ucharX)//向DS1302写入一个字节{uchari; for(i=0;i<8;i++) { SDA=X&1; CLK=1; CLK=0; X>>=1; }}//*读字节函数,从DS1302读取一个字节*//ucharRead_Byte_FROM_DS1302() //从DS1302中读取一个字节{uchari,byte,t;for(i=0;i<8;i++){ byte>>=1; t=SDA; byte|=t<<7; CLK=1; CLK=0; }////BCD码转换// returnbyte/16*10+byte%16;}////从DS1302指定位置读取数据,读数据//ucharRead_Data_FROM_DS1302(ucharaddr)//从DS1302指定位置读取数据 ,读数据{uchardat; RST=0; CLK=0; RST=1; Write_Byte_TO_DS1302(addr);//向DS1302写入一个地址 dat=Read_Byte_FROM_DS1302();//在上面写入的地址中读取数据 CLK=1; RST=0; returndat;}////向DS1302指定位置写入数据,写数据//voidWrite_Data_TO_DS1302(ucharaddr,uchardat)//向DS1302指定位置写入数据,写数据{CLK=0; RST=1; Write_Byte_TO_DS1302(addr); Write_Byte_TO_DS1302(dat); CLK=1; RST=0;}////设置时间//voidSET_DS1302() //设置时间{uchari;Write_Data_TO_DS1302(0x8E,0x00);//写控制字,取消写保护//分,时,日,月,年依次写入for(i=1;i<7;i++){ //分的起始地址是10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2 Write_Data_TO_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10)); }Write_Data_TO_DS1302(0x8E,0x80);//写控制字,加写保护}////读取当前时间//voidGetTime() //读取当前时间{uchari;for(i=0;i<7;i++){ DateTime[i]=Read_Data_FROM_DS1302(0x81+2*i); }}////日期与时间值转换为数字字符//voidFormat_DateTime(uchard,uchar*a){ a[0]=d/10+'0'; a[1]=d%10+'0';}////判断是否为闰年//ucharIs_Leapyear(uintyear){return(year%4==0&&year%100!=0)||(year%400==0);}//// 求自2000.1.1开始的任何一天是星期几?//voidRefresh_Week_Day(){uinti,d,w=5;//已知1999年12.31是星期五for(i=2000;i<2000+DateTime[6];i++){ d=Is_Leapyear(i)?366:365; w=(w+d)%7; }d=0;for(i=1;i<DateTime[4];i++){d+=MonthsDays[i];}d+=DateTime[3];//保存星期,0-6表示星期日,星期一至星期六,为了与DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1;}////年,月,日和时,分++/--//voidDatetime_Adjust(charX){switch(Adjust_Index){ case6: //年调整,00-99 if(X==1&&DateTime[6]<99) { DateTime[6]++; } if(X==-1&&DateTime[6]>0) { DateTime[6]--; } //获取2月天数 MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28; //如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]]; } Refresh_Week_Day();//刷新星期 break; case4://月调整01-12 if(X==1&&DateTime[4]<12) { DateTime[4]++; } if(X==-1&&DateTime[4]>1) { DateTime[4]--; } //获取2月天数 MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28; //如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]]; } Refresh_Week_Day();//刷新星期 break; case3: // 日调整00-28或00-29或00-30或00-31 //调节之前首先根据当前年份得出该年中2月的天数 MonthsDays[2]=Is_Leapyear(2000+DateTime[6])?29:28; //根据当前月份决定调节日期的上限 if(X==1&&DateTime[3]<MonthsDays[DateTime[4]]) { DateTime[3]++; } if(X==-1&&DateTime[3]>0) { DateTime[3]--; } Refresh_Week_Day();//刷新星期 break; case2: //时调整 if(X==1&&DateTime[2]<23) { DateTime[2]++; } if(X==-1&&DateTime[4]>0) { DateTime[2]--; } break; case1: //分调整 if(X==1&&DateTime[1]<59) { DateTime[1]++; } if(X==-1&&DateTime[4]>0) { DateTime[1]--; } break; }}//// 定时器0刷新LCD显示函数//voidT0_INT()interrupt1{ TH0=-50000/256;//写入初值TL0=-50000%256;//写入初值 if(++tcount!=2)return; tcount=0; //按指定格式生成待显示的日期时钟 Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); //星期 strcpy(LCD_DSY_BUFFER1+13,Week[DateTime[5]-1]); //时,分。秒 Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); //显示年、月、日、星期、时、分、秒 LCD_Display(0x00,LCD_DSY_BUFFER1); LCD_Display(0x40,LCD_DSY_BUFFER2);}//// 键盘中断处理函数//voidEX_INT0()interrupt0{if(k1==0) { while(k1==0); if(Adjust_Index==-1||Adjust_Index==-1) {Adjust_Index=7;} Adjust_Index--; if(Adjust_Index==5) {Adjust_Index=4;} //跳过对星期的调节 LCD_DSY_BUFFER2[13]='['; LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; LCD_DSY_BUFFER2[15]=']'; }elseif(k2==0) // 加 { while(k2==0); Datetime_Adjust(1); }elseif(k3==0) // 减 { while(k3==0); Datetime_Adjust(-1); }elseif(k4==0) { while(k4==0); SET_DS1302(); LCD_DSY_BUFFER2[13]=''; LCD_DSY_BUFFER2[14]=''; LCD_DSY_BUFFER2[15]=''; Adjust_Index=-1;//操作索引重设为-1,时间继续正常显示 }}第四章仿真结果4.1仿真软件PROTEUS和KEIL4.1.1PROTEUS仿真软件Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、AVR、ARM、8086和MSP430等,2010年又增加了Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MATLAB等多种编译器。Proteus可提供的仿真元器件资源:仿真数字和模拟、交流和直流等数千种元器件,有30多个元件库。Proteus可提供的仿真仪表资源:示波器、逻辑分析仪、虚拟终端、SPI调试器、I2C调试器、信号发生器、模式发生器、交直流电压表、交直流电流表。理论上同一种仪器可以在一个电路中随意的调用。除了现实存在的仪器外,Proteus还提供了一个图形显示功能,可以将线路上变化的信号,以图形的方式实时地显示出来,其作用与示波器相似,但功能更多。这些虚拟仪器仪表具有理想的参数指标,例如极高的输入阻抗、极低的输出阻抗。这些都尽可能减少了仪器对测量结果的影响。Proteus可提供的调试手段Proteus提供了比较丰富的测试信号用于电路的测试。这些测试信号包括模拟信号和数字信号。在PROTEUS绘制好原理图后,调入已编译好的目标代码文件:*.HEX,可以在PROTEUS的原理图中看到模拟的实物运行状态和过程。PROTEUS不仅可将许多单片机实例功能形象化,也可将许多单片机实例运行过程形象化。它的元器件、连接线路等却和传统的单片机实验硬件高度对应。由于PROTEUS提供了实验室无法相比的大量的元器件库,提供了修改电路设计的灵活性、提供了实验室在数量、质量上难以相比的虚拟仪器、仪表,因而也提供了培养学生实践精神、创造精神的平台。使用Proteus软件进行单片机系统仿真设计,是虚拟仿真技术和计算机多媒体技术相结合的综合运用,有利于培养学生的电路设计能力及仿真软件的操作能力,在使用Proteus进行系统仿真开发成功之后再进行实际制作,能极大提高单片机系统设计效率。4.1.2KEIL仿真软件KeilC51是美国KeilSoftware公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。Keil公司2005年由ARM公司收购。而后ARMKeil推出基于uVision界面,用于调试ARM7,ARM9,Cortex-M内核的MDK-ARM开发工具,用于为控制领域的开发。4.2PROTEUS仿真图4.2.1LED灯亮度仿真(1)一级亮度调节D0红灯亮图4-1一级亮度(2)二级亮度调节D1、D2、D3、D4黄灯亮图4-2二级亮度(3)三级亮

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论