毕业设计论文基于凌阳单片机的电子时钟设计.doc
目 录一 摘要2二 引言3三 系统设计43.1 方案论证43.1.1 Lcd显示模块43.1.2 语音模块(A/D)53.1.4 Led模块53.1.5 触键唤醒模块53.2 硬件设计53.2.1 Lcd的电路73.2.2 Led电路83.2.3 按键电路93.2.4 语音电路(A/D)103.2.5 电源电路113.3 软件设计及流程图(主要是主程序及Led部分)113.3.1 系统主体(main.c)113.3.2 Led程序:153.3.4 lcd22四 总结及心得体会24参考文献:25一 摘要 近年来随着科技的飞速发展,单片机的应用正在不断深入,同时带动传统控制检测技术日益更新。在实时检测和自动控制的单片机应用系统中,单片机往往作为一个核心部件来使用。随着人类科技文明的发展,人们对于时钟的要求在不断地提高。时钟已不仅仅被看成一种用来显示时间的工具,在很多实际应用中它还需要能够实现更多其它的功能。高精度、多功能、小体积、低功耗,是现代时钟发展的趋势。在这种趋势下,时钟的数字化、多功能化已经成为现代时钟生产研究的主导设计方向。我们小组正是基于这种设计方向,以单片机为控制核心,设计制作一个多功能数字时钟。本设计基于单片机技术原理,以SPCE061A单片机作为核心控制器,通过硬件电路的制作以及软件程序的编制,设计制作出一个多功能数字时钟系统。该时钟系统主要由时钟模块、计时模块、语音播报模块、液晶显示模块、键盘控制模块组成。系统具有简单清晰的操作界面,能够准确显示时间以及日期,并且实现同步播报功能,可随时进行时间调整,同时系统还具有闹钟时间设置、闹钟开/关、止闹功能以及秒表的应用。设计以硬件软件化为指导思想,充分发挥单片机功能,大部分功能通过软件编程来实现,电路简单明了,系统稳定性高。同时,该时钟系统还具有功耗小、成本低的特点,具有很强的实用性,而且系统具有一定的可扩展性。关键字:单片机、电子时钟、阴历查询、液晶显示、语音播报Abstract:With the rapid development of science and technology in recent years, SCM applications are deepening at the same time promote the growing of traditional control detection technology updates. In real-time detection and automatic control of the microcomputer application system, the microcontroller is often used as a core component. With the development of technological society, people demand the clock continues to improve. The clock has not only seen as a tool used to display the time, in many practical applications, it needs to be able to achieve more other features. High-precision, multifunction, small size, low power consumption, the development trend of the modern clock. In this trend,Clock digital, multi-functional clock production research has become a modern leading design direction. Our group is based on this design direction for the control of single-chip microcomputer core, designed a multi-function digital clock.The design is based on principles of microcomputer technology in order to SPCE061A MCU as the core controller, through the production of the hardware circuits and software programming for the design to produce a multi-functional digital clock system. The clock system mainly consists of the clock module, timer module, voice broadcast module, liquid crystal display module, keyboard control module. System has a simple and clear interface, the ability to accurately display the time and date, and to achieve simultaneous broadcast capabilities, they can always be time to adjust, while the system also has alarm time settings, alarm on / off, only the downtown functions and stopwatch applications.Design hardware and software into the guiding ideology, give full play to microcontroller functions, most of the functionality through software programming to implement, the circuit simple and clear, high stability of the system. Meanwhile, the clock system also has a power consumption and low cost features, has a strong practicality, and the system has a certain degree of scalability.Keywords: microcontroller, electronic clock, lunar query, liquid crystal display, voice broadcast二 引言单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。单片机具有体积小、重量轻、抗干扰能力强、环境要求不高、价格低廉、可靠性高、灵活性好、开发较为容易。目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。单片机具有体积小、功耗低、控制功能强、扩展灵活、微型化和使用方便等优点,广泛应用于仪器仪表中,结合不同类型的传感器,可实现诸如电压、功率、频率、湿度、温度、流量、速度、厚度、角度、长度、硬度、元素、压力等物理量的测量。采用单片机控制使得仪器仪表数字化、智能化、微型化,且功能比起采用电子或数字电路更加强大。例如精密的测量设备(功率计,示波器,各种分析仪)。用单片机可以构成形式多样的控制系统、数据采集系统。例如工厂流水 线的智能化管理,电梯智能化控制、各种报警系统,与计算机联网构成二级控制系统等。甚至可以这样说,现在的家用电器基本上都采用了单片机控制,从电饭褒、洗衣机、电冰箱、空调机、彩电、其他音响视频器材、再到电子秤量设备,五花八门,无所不在。 1957年,Ventura发明了世界上第一个电子表,从而奠定了电子时钟的基础,电子时钟开始迅速的发展。现代的电子时钟是基于单片机的一种计时工具,采用延时程序产生一定的时间中断,用于一秒的定义,通过计数方式进行满六十秒进一,满六十分进一,满二十四小时清零,从而达到计时的功能,是人民日常生活不可缺少的工具。电子钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显示直观、无机械传动装置等优点,因而得到广泛应用。随着人们生活环境的不断改善和美化,在许多场合可以看到数字电子钟。在城市的主要营业场所、车站、码头等公共场所使用LCD数字电子钟已经成为一种时尚。但目前市场上各式各样的LCD数字电子钟大多数用全硬件电路实现,电路结构复杂,功率损耗大等缺点。因此有必要对数字电子钟进行改进。本设计基于单片机技术原理,以SPCE061A单片机作为核心控制器,通过硬件电路的制作以及软件程序的编制,设计制作出一个LCD多功能数字时钟系统。该时钟系统主要由时钟模块、计时模块、语音播报模块、液晶显示模块、键盘控制模块组成。系统具有简单清晰的操作界面,能够准确显示时间以及日期,并且实现同步播报功能,可随时进行时间调整。三 系统设计3.1 方案论证3.1.1 Lcd显示模块这一模块可以使用lcd或者led数码管来实现。我组最后选择用lcd液晶显示来显示时间以及日期。之所以选择lcd来实现,是因为它具有很多优点。低压微功耗,平板型结构,被动显示型(无眩光,不刺激人眼,不会引起眼睛疲劳)而且 显示信息量大(因为像素可以做得很小) 无电磁辐射(对人体安全,利于信息保密)。 具体的实现方法是利用C语言的编程(代码见程序system.c)。下面的硬件设计将详细的介绍lcd的模块的接口电路以及具体的接线方法。3.1.2 语音模块(A/D) 凌阳单片机本身具备语音识别功能,不需要外扩语音识别模块,虽然具有一点点DSP功能,就能做到语音识别功能。凌阳压缩算法中SACM_A2000、SACM_S480、SACM_S240主要是用来放音,可用于语音提示,而DVR则用来录放音。对于音乐合成MS01,该算法较繁琐,而且需要具备音乐理论、配器法及和声学知识。凌阳的SPCE061A是16位单片机,具有DSP功能,有很强的信息处理能力,最高时钟频率可达到49MHz,具备运算速度高的优势等等,这些都无疑为语音的播放、录放、合成及辨识提供了条件。本小组使用的是SACM_S480模块。利用C语言对其进行编程(代码为speak.c)。本模块是本设计的关键环节,因为电子时钟的功能就是正确的显示时间。具体的计时实现是利用SPCE061A自带的定时器以及计数器功能。通过C语言编程,采用延时程序产生一定的时间中断,用于一秒的定义,通过计数方式进行满六十秒进一,满六十分进一,满二十四小时清零,从而达到计时的功能。3.1.4 Led模块由于Lcd,led对IO口的占用,使得本小组的Led设计不得不使得其与其他的模块分开执行。同时由于不可能再去利用Led再去设计一个系统所以只实现了简单的功能(简单的计数)。3.1.5 触键唤醒模块触键唤醒中断源主要是在系统进入睡眠状态后,通过A口低八位的按键来唤醒系统的时钟,同时 进入触键唤醒中断,恢复睡眠时的PC指针。在进行程序编写的时候,要注意只有当IOA7IOA0内的控制字为000、001、010时,相应位才有唤醒功能。3.2 硬件设计试验箱总体接线3.2.1 Lcd的电路这部分的主要接线如下:IOA8-15接液晶显示模块DB0-DB7IOB4接液晶显示模块AOIOB5接液晶显示模块的R/WIOB6接液晶显示模块的EPDB0-DB7为双向数据口,AO为数据/使命控制位,R/w为读/写信号,EP是全能端(低电平有效)要这部分工作时Key接线与IOA低八位相连就可以了。Lcd模块接口电路程序下载后会显示日期、时间。按Key1可以进入时间调整界面。3.2.2 Led电路连线:IOA口低8位连接agIOB2IOB5连接数码管片选段 6位led数码管引脚图硬件连接3.2.3 按键电路按键电路简单,易于控制;按键控制接口部分由9个按键组成 : 调整时间/闹钟键、时钟开/关键、小时按键、分钟按键、加记数键、减记数键、确定键、切换温度/频率和电压键、接触式止闹键 按键功能说明:1、调整时间/闹钟键:按一次:开始设置时间;按两次:开始设置闹钟;依次循环。 2、小时按键:调整时间/闹钟状态下,此键开始有效。按一次表示开始设置相应的小时; 3、分钟按键:调整时间/闹钟状态下,此键开始有效。按一次表示开始设置相应的分钟; 、加、减计数键在时间调整时,按一下,分钟或小时数加减一、确定键调整完后按此键确认、切换温度/频率和电压键,切换屏幕、接触试止闹键,当闹铃响时,按下此键,停止振动按键电路直接与IOA口连接。其原理图如下:3.2.4 语音电路(A/D)下图为音频输入电路连接的时候就使用实验箱默认的接法上图的作用就是完成语音的输出响应。3.2.5 电源电路3.3 软件设计及流程图(主要是主程序及Led部分)3.3.1 系统主体(main.c)Key1初始化键扫描键处理键按下下调整时间播日期播时间Key2Key3NY主程序框图主程序(main.c):编写首先进行函数声明,定义文件中用到的变量以及常数数组,再编写真正的主体部分。首先进行键盘以及液晶显示的初始化。置2hz的中断,开2hz的中断。keyinitial(); LCD501_Init(0); LCD501_Circle(64,32,15,1);LCD501_ClrScreen(0);LCD501_FontSet(0) *P_INT_Ctrl_New = *P_INT_Ctrl_New | 0x0004; _asm("INT IRQ"); 然后进行键盘扫描。如果Key1键按下,接着调用清屏函数,进而显示调整界面、显示鼠标位置。再进行键盘扫描,如果是Key1按下则进入相应的调整。利用Switch语句判断此时的鼠标指向。编写程序鼠标指向的方向。如果按下Key2,则鼠标指向下移,同理按下Key3,鼠标指向上移,而且在每一步之后修改箭头的坐标,这一部分在lcd子程序中详细的介绍。如果开始的时候按下的是Key2则播报时间,此过程调用时间播报函数。如果开始的时候按下的是Key3则播报时间,此过程调用日期播报函数。最后清看门狗。程序如下:int main(void) int i=0,j=1,k;*P_IOB_Dir=0xffff;*P_IOB_Attrib=0xffff;*P_IOB_Data=0x0000;for(i=0;i<8;i+) k=1000;while(k-);j=j<<1;*P_Watchdog_Clear=1;keyinitial(); LCD501_Init(0); LCD501_Circle(64,32,15,1);LCD501_ClrScreen(0);LCD501_FontSet(0);*P_INT_Ctrl_New = *P_INT_Ctrl_New | 0x0004; _asm("INT IRQ"); while(1) int i=0; display(); if(min=0 && sec=0) speaktime(); keyscan(); *P_Watchdog_Clear=0x0001; if(keyvalue=0x0001) keyflag1=1; LCD501_ClrScreen(0); while(keyflag1=1) nextdisplay(); LCD501_Bitmap(15,mousei,(unsigned int*)encoding_mouse); keyscan(); *P_Watchdog_Clear=0x0001; switch(keyvalue) case 0x0001: switch(i) case 0: setday(); break; case 1: LCD501_ClrScreen(0);keyflag1=0; break; break; case 0x0002: LCD501_Bitmap(15,mousei,(unsigned int*)encoding_empty); if(i=3) i=0; else i=+i; LCD501_Bitmap(15,mousei,(unsigned int*)encoding_mouse); break; case 0x0004: LCD501_Bitmap(15,mousei,(unsigned int*)encoding_empty); if(i=0) i=3; else i=-i; LCD501_Bitmap(15,mousei,(unsigned int*)encoding_mouse); break; else if(keyvalue=0x0002) peaktime(); else if(keyvalue=0x0004) / speakday() ; else *P_Watchdog_Clear=0x0001; 3.3.2 Led程序:流程图开始系统初始化、I/O设置显示全0循环显示09前面提及了一下,由于IO口的限制所以Led这部分我们拿出来,单独的编写了一段小程序。其原理为首先对I/O口初始化,显示全零,然后1秒后从第一位数码管开始从09刷新,直到最后的一个数码管。中断分别使用了IRQ4和IRQ5-2hz。首先定义了变量g_uiFirst,g_uiFlag,分别控制1s延时以及控制数码管。定义g_Data11,g_uiSeg分别表示数据和指针。unsigned int g_uiFirst = 0x0000;unsigned int g_uiFlag;unsigned int g_Data11 = 0x0000,0x003f,0x0006,0x005b,0x004f,0x0066,0x006d,0x007d,0x0007,0x007f,0x006f;unsigned int g_uiSeg;进入主函数,先开2hz的中断,然后显示初始化并且开IRQ4hz的中断,然后编写一个循环,设置数码管全为零,并且刷新六位的数码管,清看门狗。源程序:int main(void)unsigned int Dis16 = 0x003f,0x003f,0x003f,0x003f,0x003f,0x003f;unsigned int uiIntStatus;uiIntStatus = *P_INT_Ctrl_New; uiIntStatus |= C_IRQ5_2Hz;*P_INT_Ctrl = uiIntStatus;g_uiFlag = 0x0000;g_uiSeg = 0;DIG_Init();while(1) if(g_uiFlag = 0x0000) DIG_SetAll(Dis1); if(g_uiFlag != 0x0000) DIG_Set(g_uiFlag,g_Datag_uiSeg);*P_Watchdog_Clear = 0x0001;3.3.3 语音播报及AD语音播报:#include "SPCE061A.h"#include "s480.h" /以下是注解:#define C_T00 0 voice中的文件0#define C_T01 1 voice中的文件1 #define C_T02 2 voice中的文件2 #define C_T03 3 voice中的文件3#define C_T04 4 voice中的文件4#define C_T05 5 voice中的文件5#define C_T06 6 voice中的文件6#define C_T07 7 voice中的文件7#define C_T08 8 voice中的文件8#define C_T09 9 voice中的文件9#define C_T10 10 voice中的文件10#define C_DIAN 11 #define C_MIN 12 /报分钟 #define C_YEAR 13 /报年 #define C_MONTH 14 /报月#define C_DAY 15 /报日#define C_BELL 16 /铃声extern unsigned int year;extern unsigned int gmonth;extern unsigned int gday;extern unsigned int hour;extern unsigned int min;void PlayRespond(unsigned int Result) SACM_S480_Initial(1);*P_INT_Ctrl_New = *P_INT_Ctrl_New | 0x0004; /使初始化后不影响2KZ中断 SACM_S480_Play(Result,3,3); while(SACM_S480_Status()&0x0001) != 0) SACM_S480_ServiceLoop(); *P_Watchdog_Clear=0x0001; SACM_S480_Stop();void PlaySpeakYear(int YearTemp) /年的播报 PlayRespond(YearTemp/1000); /千位数字 PlayRespond(YearTemp%1000)/100); /百位数字 PlayRespond(YearTemp%100)/10); /十位数字 PlayRespond(YearTemp%10); /各位数字 PlayRespond(C_YEAR); void PlaySpeakMonth(int MonthTemp) /月的播报 if(MonthTemp<10) /小于10PlayRespond(MonthTemp); /报原值else if(MonthTemp=10) /报10 PlayRespond(C_T10);else if(MonthTemp=11) PlayRespond(C_T10); /报10再报1PlayRespond(C_T01);else if(MonthTemp=12) PlayRespond(C_T10); /报10再报2 PlayRespond(C_T02); PlayRespond(C_MONTH); void PlaySpeakDay(int DayTemp) /日的播报 if(DayTemp/10)> 1) PlayRespond(DayTemp/10+C_T00); /十位>1报 if(DayTemp/10)>0) PlayRespond(C_T10); /报十,十位为1不报1 if(DayTemp%10)!= 0) PlayRespond(DayTemp%10+C_T00); PlayRespond(C_DAY); void PlaySpeakHour(int DayTemp) /小时的播报 if(DayTemp<10) /值小于10就直接报PlayRespond(DayTemp); else if(DayTemp=10) PlayRespond(C_T10);else if(DayTemp>10 && DayTemp<20) /大于10小于20PlayRespond(C_T10); /先报10再报个位数PlayRespond(DayTemp%10); else if(DayTemp=20)PlayRespond(C_T02); /报2再报10 PlayRespond(C_T10);else if(DayTemp>20)PlayRespond(C_T02); /报2再报10再报个位的数PlayRespond(C_T10); PlayRespond(DayTemp%20); PlayRespond(C_DIAN); /点 void PlaySpeakMinute(int MinTemp) /分钟的播报 if(MinTemp=0) PlayRespond(C_T00); if(MinTemp/10)>1) PlayRespond(MinTemp/10); /分十位 if(MinTemp/10) >0) PlayRespond(C_T10); /分的十位大于1报,为1不报1 if(MinTemp%10)!=0) PlayRespond(MinTemp%10); /分的个位不为0则报 PlayRespond(C_MIN); /分 void speaktime()PlayRespond(C_BELL); /报时声 PlaySpeakHour(hour); /时 PlaySpeakMinute(min); /分void speakday()PlaySpeakYear(