单片机课程设计说明书_第1页
单片机课程设计说明书_第2页
单片机课程设计说明书_第3页
单片机课程设计说明书_第4页
单片机课程设计说明书_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

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

文档简介

/单片机原理及应用课程设计说明书题目:电子钟学生姓名:学号:院(系):专业:指导教师:年月日目录TOC\o"1-3"\h\u10232一、选题背景 2323741、设计任务 283372、设计内容 213233二、总体设计 239471、系统总体设计 2308751.1

功能设计 2217281.2

参考元器件 245482、系统硬件电路设计 3231522.1单片机MCU 3258732.2复位电路 3120782.3数码管 428222.4键盘 482902.5蜂鸣器 580223、系统软件设计 5308013.1系统软件总计架构设计 5294503.2任务划分 672543.3程序框架 653043.3.1底层驱动 7196323.3.2界面层 719553.3.3应用层 870763.3.5主函数 1122444.操作步骤 1179194.1基本操作 11309704.2菜单选择操作 12137314.3时间校准操作(P-1) 12322564.4秒表(P-2) 12199194.5闹钟(P-3) 1214301三、设计体会和总结 13124671、设计体会 1358532、设计总结 1320815附录A:实物图展示 1432346附录B:程序 1814465参考文献 51一、选题背景1、设计任务(1)基本功能:设计一个时钟电路,能显示年月日和时分秒;通过功能键完成年月日时分秒的切换与对时功能;

(2)附加功能:添加秒表功能,能通过键盘进行时间和秒表功能切换。(3)系统硬件设计要求:根据任务要求,完成单片机最小系统及其扩展设计,组成功能完整的系统;(4)系统软件设计:根据系统功能要求,完成程序的编写与调试;(5)说明书:功能介绍、系统说明、模块说明、使用说明;须改进之处及体会;参考文献:参考书、资料、网站等;附件:系统原理图及程序清单。2、设计内容(1)设计一个时钟电路,能显示年月日和时分秒;通过功能键完成年月日时分秒的切换与对时功能。(2)添加秒表功能,能通过键盘进行时间和秒表功能切换;(3)添加闹钟功能,通过按键控制开关;二、总体设计1、系统总体设计1.1

功能设计 电子时钟的单片机芯片选用89C51作为主控芯片,显示模块采用LED数码管。本系统使用定时器产生的时基实现时钟、秒表、闹钟等功能。在本系统中,主要有四大主要功能,分别实现不同功能。具体功能如下:(1)、第一个功能是实现时钟、年份、月日、星期几以及秒状态的显示与切换。(2)、第二个功能,即第一大菜单下,实现时钟、年份、月日和星期几的校准。(3)、第三个功能,即在第二大菜单下,实现秒表功能。秒表功能中,可以正常跑秒,也可随时暂停或者清零。(4)、第四个功能,即第三大菜单下可实现闹钟的功能。可先选择打开或是关闭闹钟,若选择关闭,系统跳出闹钟界面。若选择打开闹钟,则可设置时间。1.2

参考元器件(1)51系列单片机SST89E516RD(2)4个共阳数码管(3)蜂鸣器(4)4个按键2、系统硬件电路设计2.1单片机MCU89C52内置8位中央处理单元、256字节内部数据存储器RAM、8k片内程序存储器(ROM)32个双向输入/输出(I/O)口、3个16位定时/计数器和5个两级中断结构,一个全双工串行通信口,片内时钟振荡电路。图2-1单片机MCU最小系统2.2复位电路 图中RST接单片机的复位引脚RST,形成复位电路。平时RST端口是高电平,当按键按下后,RST端口为低电平,实现低电平复位。图2-2复位电路2.3数码管 数码管显示电路如图所示,段选端口接到复用端口P1上,在数码管显示电路中,将J11—J18跳线的2、3短接,就可以进行段选。数码管的公共端COM1—COM4是经PNP三极管9012接单片机的P0.0—P0.3口上的,属于共阳极的接法,当COM端有低电平时,选中数码管的某个位。图2-3数码管 J11J12J13J14图2-4跳线2.4键盘本次采用的是独立式键盘,8个按键一端分别接P2[0-7]口,并通过10K的电阻上拉,另一端地。没有按键状态下,P2口为高电平,当有按键按下时,为低电平状态。 电子时钟面板中设有4个按键(S2-S5),用于用户设定参数及执行各项操作。具体操作见用户使用说明书。图2-5键盘2.5蜂鸣器为了方便用户操作,在本系统中,加入蜂鸣器,作为按键和闹钟的提示音。如图为蜂鸣器驱动电路,蜂鸣器一端接VCC,另一端通过三极管9012接P0.4口,当P0.4口有低电平时,三极管导通,驱动蜂鸣器工作。图2-6蜂鸣器3、系统软件设计3.1系统软件总计架构设计 软件设计首先要考虑的是程序的结构和设计方法。一般来说,程序设计的方法可以有三种:模块化程序设计方法、自顶向下的程序设计方法和结构化的程序设计方法。针对微控器应用系统设计的特点,综合三种设计方法各自的优点,同时考虑到程序的可维护性和可移植性,本系统采用一种层次化的软件设计方法。整个系统可分为三层,即应用层、界面层和底层驱动层。图3-1给出了电子时钟系统软件的层次结构图。图3-1电子时钟系统软件的层次结构图底层驱动层是指包含直接和硬件相关的驱动程序,如LCD显示、按键、时钟芯片、AD转换器、中断和定时等。界面层主要提供数据交互,为应用层和底层驱动之间以及底层驱动层各模块之间提供数据的交互。应用层主要完成具体功能的实现,它要通过界面层控制底层驱动层各模块来完成所需功能,而不能越过界面层直接访问底层驱动层。按照层次化设计的原则,底层模块要求有相对的独立性和完整性。所谓独立性是指底层的各个模块间不产生直接的数据交互,底层也不直接访问应用层,如果有需要,都必须通过界面层进行数据交互。所谓完整性是指驱动层内将与硬件相关的操作全部包装起来,应用层不再考虑和硬件有关的任何操作。界面层的数据交互是通过数据缓冲区BUFFER或先进先出寄存器FIFO实现的。它们实际上都是一系列数据存储器单元。应用层对底层的访问以及子程序模块间的交互,要通过都必须通过界面层进行沟通。3.2任务划分(1)时基处理函数mn_Timer_Base(),在主函数里循环调用。(2)蜂鸣器报警,在应用层app.c和key.c里循环执行,在按键确认按下或者闹钟时间到了作提示音。(3)按键的键值扫描任务,每50ms执行一次,并在主函数里循环调用。(4)数码管led_tube的显示任务,每5ms扫描一次。(5)应用层状态转换任务,和各个功能函数。各个功能函数在mn_App()里状态转换时调用,mn_App()在主函数里循环调用。3.3程序框架结合上述层次化设计方法,本系统程序主要包括主程序、应用层程序、以及底层驱动程序,下面将结合程序设计设计过程作详细介绍。3.3.1底层驱动BEEP驱动蜂鸣器驱动程序主要包括蜂鸣器的初始化,即IO口设置为输出,使能上拉,默认输出高电平。在本系统中,蜂鸣器作为按键和闹钟的提示音。按键驱动按键驱动主要包括按键初始化(配置引脚为输入,使能上拉)、读取按键键值、按键防抖,以及按键键值转化。其中按键消抖采用定时器方式,能大大释放CPU资源。另外添加了连击(即按键长按)功能,同样是在定利用定时器法方式实现的。键值转化将键值写入FIFO中,在应用层函数中读出键值,并做相应处理。数码管显示模块为了节约硬件资源,降低系统的设计成本,采用动态扫描,软件译码的方式来实现数码管显示。在数据存储区建立一个显示缓冲区,存储单元的个数与数码管个数相等,也就是4个。每次执行显示任务时,只进行一个数码管显示,下一次调用显示子程序时,显示下一位数码管,以此类推。这样当每次退出数码管显示程序后,由于I/O口的锁存作用相应的数码管一直点亮。这就是数码管动态扫描函数ledScan_Display(),本系统中,每5ms扫描一次数码管。用led_Disp_init()函数对数码管缓冲区进行初始化。另外加入小数点亮、灭的函数:dot_On(),dot_Off()。若想使第二个数码管的小数点亮,则可调用dot_On(DOT_TWO)实现。定时器 本系统使用定时器0。对定时器0进行初始化,初始化应完成如下工作: (1)、设置定时器/计数器的工作模式TMOD(常用的是模式1:TMOD=0x01); (2)、装入预置数到TH0和TL0中(THx=TLx=MAX(8192/65536/256)-计数次数); (3)、如果工作在中断方式,则需要开定时器/计数器的中断TCON中的标志位:TF0/TF1=0/1; (4)、启动定时器/计数器:TR0/TR1=1; 定时器初始化1ms的定时,定时器0的中断函数里使1ms标志位置1,这样就可以在时基产生函数mn_Timer_Base()里产生多个时间的定时标志位,可在不停的时间赶不同的事,尽量不浪费CPU的运行效率。3.3.2界面层 界面层主要由各种寄存器、标志位和缓冲区组成,其功能是用于提供数据交互。各个底层模块都有自己相应的变量及标志,这些变量是底层与应用层或是底层与其他底层模块对话的接口。 界面层主要变量的说明,如表3-1。表3-1界面层主要变量的说明变量名称说明sys_State系统状态缓冲区,用于存放系统工作状态event_FIFO系统事件缓冲区,用于存放系统的各种事件led_Disp_Buff数码管显示缓冲区keyVluBuf键值缓冲区,用于存放键值beep_Time蜂鸣器响的时间缓冲区watch_stop秒表跑秒/暂停标志位clock_stop闹钟开/关标志位(所有时间标志位)作时间标志,当标志位置1或达到条件时,做相应的任务。3.3.3应用层 应用层主要实现电子时钟的具体功能,通过界面层的各个变量及标志位的操作控制底层驱动层各个模块来实现所需功能,而并不越过界面层直接访问底层驱动层。对于本系统的状态转换首先列出菜单如下图:图3-2系统菜单示意图根据以上功能菜单那表列出状态转换表:(1)、系统状态分析表3-2系统状态分析状态名称编号状态说明状态10x10显示菜单P-1状态20x20显示菜单P-2状态30x30显示菜单P-3状态40x11显示年状态状态50x12显示月日状态状态60x13显示周状态状态70x14显示时分状态状态80x15显示秒状态状态90x16设置年状态100x17设置月状态110x18设置日状态120x19设置周状态130x1a设置时状态140x1b设置分状态150x21秒表状态160x31显示ON/OFF状态170x32设置闹钟小时状态180x33设置闹钟分钟(2)、系统事件分析表3-3系统事件分析编号事件名称1确认键按下(S2)2DOWN键按下(S3)3UP键按下(S4)4菜单键(S5)(3)、系统状态转换分析表3-4系统状态装换分析事件转换状态状态1状态2状态3状态4状态5状态6状态7状态8状态9状态10状态11状态12状态13状态14状态15状态16状态17状态18onoff确认键按下(S2)到状态9到状态15到状态16到状态4到状态5到状态5到状态6到状态7到状态7到状态7到状态18/到状态3到状态18到状态17DOWN键按下(S3)到状态2到状态3到状态1到状态5到状态6到状态7到状态8到状态4UP键按下(S4)到状态3到状态1到状态2到状态8到状态4到状态5到状态6到状态7菜单键(S5)到状态7到状态7到状态7到状态1到状态1到状态1到状态1到状态1到状态11到状态12到状态10到状态14到状态7到状态13--到状态3到状态3到状态3到状态33.3.5主函数主函数包括系统初始化,在while(1)里调用时基处理函数、按键相关程序、以及应用程序,见附件4.操作步骤4.1基本操作 打开单片机时,界面首先出现的是时间分钟显示,如图1。此时按键S3和S4可用来切换时钟、年份、月日、星期几以及秒状态,各界面示例图如下图4-1时分显示图4-2年份显示图4-3月日显示图4-4星期六显示4.2菜单选择操作 S5按键可进入菜单选择界面,此时界面出现P-1的字样,如图5,代表此时是菜单一。此时按键S3和S4可用来切换菜单1、2、3的显示。从前面知道每个菜单下,有不同的功能。菜单选好之后,S2键表示确定进入。图4-5系统菜单主界面4.3时间校准操作(P-1) 确认进入菜单1便是进入校准状态,在此状态下,S5键进行切换要调试的部位,调试的部分会有1s的间隔闪烁给调试者提醒。例如此时年份2015在闪烁,说明此时调试的部分是年份,若想调试的是时间,便按S5进行切换。切换的顺序是:年份—>日—>月—>星期—>分钟—>时间。 调好时按S2确认。4.4秒表(P-2) 确认进入菜单2便是进入秒表功能,界面初始状态是0000,如图6。S5键可以进行跑秒的开始于暂停,S4与S3是秒表清零键,S2可返回上一级。若没有进行清0操作就退出秒表状态的话,再次进入秒表状态时,会保留上一次的值。图4-6秒表4.5闹钟(P-3) 确认进入菜单3(P-3)便是进入闹钟功能,首先可按S4或者S3选择闹钟开或者关,S2是确认键。若闹钟选择关(OFF),界面图如图7。确认键按下后,系统跳回上一级即菜单选择界面;若闹钟选择开(ON),界面图如图8。确认键按下后,系统进入设置闹钟时间,S3(down)和S4(up)键可上调或者下调时间,此界面可按S5进行切换设置小时或者分钟。设置好之后按确认键(S2)返回上一级。 闹钟响时,可按任意键关闭闹钟,若无手动关闭闹钟,一分钟后闹钟自动关闭。图4-7关闭闹钟界面图4-8开闹钟界面三、设计体会和总结1、设计体会课程设计需要很大的耐心,尤其是在写程序的时候,如果基础不扎实,再加上不细心的话,根本就做不出来。写程序是本次课程设计遇到的最大的问题,因为需要实现很多功能,还要控制不同的按键来实现不同的操作,这些对学单片机并不是很久的我们着实是一个挑战,但也同时给了我们一个平台,让我们有机会接触到单片机在实际生活中的运用,也是一次很好的经验,对以后要从事单片机方面的工作的同学是一个很好的机会。2、设计总结这次的课程设计把我们上学期学的单片机的知识运用到了实践中,在课本中学到的定时器/计数器,串行口,中断等等,都在这次的课程设计中有了更深的体会和领悟。在做课设的时候,也需要查一些资料,通过查资料,会获得一些在课堂上学不到的知识,扩展了我们的知识面。附录A:实物图展示菜单1:(显示年月日、时间、星期)显示年:(2016年)显示月.日:(3月26号)显示星期:(星期六)菜单2:(秒表功能)显示5.03秒显示3.78秒菜单3:(闹钟功能)显示闹钟开:显示闹钟关:附录B:程序1.app.c#include "app.h"#include "Int_Deal.h"#include "led_Tube.h"#include "beep.h"//#include "key.h"uchar data event_FIFO[8]; //事件缓冲区uchar data *event_WrIp=event_FIFO; //写指针uchar data *event_RdIp=event_FIFO; //度指针uchar data current_Event=0;uchar data sys_State=0x14;uchar data count_Second=0;char data count_Minute=37; char data count_Hour=10;uchar data count_Week=6;uchar data count_Day=28;uchar data count_Mouth=11;uint data count_Year=2015;bit data flag_1hour;bit data flag_1day=0;uchar data flag_1mouth=0;bit data watch_stop=0;bit data clock_stop=0;uint data count_Watch=0;char data alarm_Clock_Hour=10;char data alarm_Clock_Minute=38;uchardataflag_Clock=0;void write_Event(ucharcmd){ *event_WrIp=cmd; if(event_WrIp==(event_FIFO+7))event_WrIp=event_FIFO; elseevent_WrIp++;}uchar read_Event(void){ uchartemp; if(event_RdIp!=event_WrIp) //读事件 { temp=*event_RdIp; if(event_RdIp==(event_FIFO+7))event_RdIp=event_FIFO; elseevent_RdIp++; return temp; } else return(0);}void mn_App(void){// ucharcurrent_Event=0; current_Event=read_Event(); //key_Deal(); ledScan_Display(); timer_Deal(); dot_Off(DOT_TWO); alarm_Clock_Beep();// beep_Off(); switch(sys_State) { case0x00:break;//菜单,母状态 case0x10:{meau1_Display();break;}//显示菜单P-1 case0x20:{meau2_Display();break;} //显示菜单P-2 case0x30:{meau3_Display();break;} //显示菜单P-3//时钟子状态 case0x11:{year_Display();break;} //显示年 case0x12:{month_Display();break;} //显示月日 case0x13:{week_Display();break;} //显示周 case0x14:{hour_Display();break;} //显示时分 case0x15:{second_Display();break;} //显示秒 case0x16:{year_Set();break;} //设置年 case0x17:{month_Set();break;} //设置月 case0x18:{day_Set();break;} //设置日 case0x19:{week_Set();break;} //设置周 case0x1A:{hour_Set();break;} //显示时 case0x1B:{minute_Set();break;} //显示分 //秒表子状态 case0x21:{stop_Watch();break;} //秒表功能 // case0x22: //// case0x23: ////闹钟子状态 case0x31:{alarm_Clock_Open();break;} //显示on/off case0x32:{alarm_Clock_Hour_Set();break;} //设置时 case0x33:{alarm_Clock_Minute_Set();break;} //设置分 default:break; }}voidmeau1_Display(void) //菜单1,校准时间功能{ switch(current_Event) { case0:break; case1:{sys_State=0x16;break;} //确认键进入年设置 case2:{sys_State=0x20;break;} //菜单下翻建,P-2 case3:{sys_State=0x30;break;} //菜单上翻建,P-3 case4:{sys_State=0x14;break;} //返回时间显示 default:break; } led_Disp_Buff[0]=10; //显示 led_Disp_Buff[1]=17; led_Disp_Buff[2]=21; led_Disp_Buff[3]=1;}voidmeau2_Display(void) //菜单2,秒表功能{ switch(current_Event) { case0:break; case1:{sys_State=0x21;break;} //确认进入秒表状态 case2:{sys_State=0x30;break;} //菜单下翻建,P-3 case3:{sys_State=0x10;break;} //菜单上翻建,P-1 case4:{sys_State=0x14;break;} //返回时间显示 default:break; } led_Disp_Buff[0]=10; //显示 led_Disp_Buff[1]=17; led_Disp_Buff[2]=21; led_Disp_Buff[3]=2;}voidmeau3_Display(void) //菜单3,闹钟功能{ switch(current_Event) { case0:break; case1:{sys_State=0x31;break;} //确认进入闹钟状态 case2:{sys_State=0x10;break;} //菜单下翻建,P-1 case3:{sys_State=0x20;break;} //菜单上翻建,P-2 case4:{sys_State=0x14;break;} //返回时间显示 default:break; } led_Disp_Buff[0]=10; //显示 led_Disp_Buff[1]=17; led_Disp_Buff[2]=21; led_Disp_Buff[3]=3;}voidyear_Set(void){ if(flag_Flash) //校准时年数闪烁 { led_Disp_Buff[0]=count_Year/1000; led_Disp_Buff[1]=count_Year/100%10; led_Disp_Buff[2]=count_Year/10%10; led_Disp_Buff[3]=count_Year%10; } else { led_Disp_Buff[0]=10; //显示为空 led_Disp_Buff[1]=10; led_Disp_Buff[2]=10; led_Disp_Buff[3]=10; } switch(current_Event) { case0x00:break; case0x01:{sys_State=0x11;break;} case0x02:{count_Year--;break;} case0x03:{count_Year++;break;} case0x04:{sys_State=0x18;break;} //确认调好年份,可切换进入调试日 case0x42:{count_Year--;flag_Flash=1;break;}//连击使年数连续减,且数码管不再以1S闪烁 case0x43:{count_Year++;flag_Flash=1;break;} default:break; } }void month_Set(void){ switch(current_Event) { case0x00:break; case0x01:{sys_State=0x12;break;} //调好月份时,确认进入月显示 case0x02:{count_Mouth--;break;} case0x03:{count_Mouth++;break;} case0x04:{sys_State=0x19;break;} //确认调好月,可切换进入调试周状态 case0x42:{count_Mouth--;flag_Flash=1;break;}//连击 case0x43:{count_Mouth++;flag_Flash=1;break;} default:break; } if(count_Mouth==13) //使月份12周期循环 { count_Mouth=1; } if(count_Mouth==0) { count_Mouth=12; } led_Disp_Buff[2]=count_Day/10; led_Disp_Buff[3]=count_Day%10; if(flag_Flash) //使月显示闪烁 { led_Disp_Buff[0]=count_Mouth/10; led_Disp_Buff[1]=count_Mouth%10; } else { led_Disp_Buff[0]=10; led_Disp_Buff[1]=10; } dot_On(DOT_TWO); //月日调试时小数点常亮}void day_Set(void) //设置天{ switch(current_Event) //在该状态下读键值 { case0x00:break; case0x01:{sys_State=0x12;break;} //调好日时,确认进入月日显示状态 case0x02:{count_Day--;break;} case0x03:{count_Day++;break;} case0x04:{sys_State=0x17;break;} //切换进入调试月状态 case0x42:{count_Day--;flag_Flash=1;break;} //实现连击 case0x43:{count_Day++;flag_Flash=1;break;} default:break; } if(count_Day==31) { count_Day=1; } if(count_Day==0) { count_Day=30; } led_Disp_Buff[0]=count_Mouth/10; led_Disp_Buff[1]=count_Mouth%10; if(flag_Flash) { led_Disp_Buff[2]=count_Day/10; led_Disp_Buff[3]=count_Day%10; } else { led_Disp_Buff[2]=10; led_Disp_Buff[3]=10; } dot_On(DOT_TWO); //月日调试时小数点常亮}void week_Set(void) //周设置{ //在该状态下读键值 switch(current_Event) { case0x00:break; case0x01:{sys_State=0x13;break;} //调好周时,确认进入周显示状态 case0x02:{count_Week--;break;} case0x03:{count_Week++;break;} case0x04:{sys_State=0x1B;break;} //切换进入调试分钟状态 case0x42:{count_Week--;flag_Flash=1;break;} case0x43:{count_Week++;flag_Flash=1;break;} default:break; } if(count_Week==8) //7天循环 { count_Week=1; } if(count_Week==0) { count_Week=1; } led_Disp_Buff[0]=21; led_Disp_Buff[1]=21; led_Disp_Buff[2]=21; if(flag_Flash) //周闪烁 { led_Disp_Buff[3]=count_Week%8; } else { led_Disp_Buff[3]=10; }}void hour_Set(void){ //设置时间 switch(current_Event) //在该状态下读键值 { case0x00:break; case0x01:{sys_State=0x14;break;} //调好时间时,确认进入时间显示状态 case0x02:{count_Hour--;break;} case0x03:{count_Hour++;break;} case0x04:{sys_State=0x14;break;}//全部调好后,退出设置状态进入时间显示状态 case0x42:{count_Hour--;flag_Flash=1;break;} case0x43:{count_Hour++;flag_Flash=1;break;} default:break; } if(count_Hour>=24) { count_Hour=0; } if(count_Hour<0) { count_Hour=23; } led_Disp_Buff[2]=count_Minute/10; led_Disp_Buff[3]=count_Minute%10; if(flag_Flash) { led_Disp_Buff[0]=count_Hour/10; led_Disp_Buff[1]=count_Hour%10; } else { led_Disp_Buff[0]=10; led_Disp_Buff[1]=10; } if(flag_Flash) //在时间设置时,第二个数码管的小数点闪烁 { dot_On(DOT_TWO); } else { dot_Off(DOT_TWO); }}void minute_Set(void) //分钟设置{ switch(current_Event) //读键值 { case0x00:break; case0x01:{sys_State=0x14;break;} //调好分钟时,确认进入时间显示状态 case0x02:{count_Minute--;break;} case0x03:{count_Minute++;break;} case0x04:{sys_State=0x1A;break;}//全部调好后,退出设置状态进入时间显示状态 case0x42:{count_Minute--;flag_Flash=1;break;} case0x43:{count_Minute++;flag_Flash=1;break;} default:break; } if(count_Minute==60) { count_Minute=0; } if(count_Minute<0) { count_Minute=59; } led_Disp_Buff[0]=count_Hour/10; led_Disp_Buff[1]=count_Hour%10; if(flag_Flash) { led_Disp_Buff[2]=count_Minute/10; led_Disp_Buff[3]=count_Minute%10; } else { led_Disp_Buff[2]=10; led_Disp_Buff[3]=10; } if(flag_Flash) //小数点闪烁 { dot_On(DOT_TWO); } else { dot_Off(DOT_TWO); }}voidyear_Display(void) //年显示状态{ switch(current_Event) { case0:{break;} case1: break; case2:{sys_State=0x12;break;} //down,切换至月日显示 case3:{sys_State=0x15;break;} //up,切至秒显示 case4:{sys_State=0x10;break;} //进入菜单P-1 default:break; } led_Disp_Buff[0]=count_Year/1000; //年显示 led_Disp_Buff[1]=count_Year/100%10; led_Disp_Buff[2]=count_Year/10%10; led_Disp_Buff[3]=count_Year%10;}void month_Display(void){ switch(current_Event) { case0:break; case1:break; case2:{sys_State=0x13;break;} //down,切换至周显示 case3:{sys_State=0x11;break;} //up,切至年显示 case4:{sys_State=0x10;break;} //进入菜单P-1 default:break; } led_Disp_Buff[0]=count_Mouth/10; //月日显示 led_Disp_Buff[1]=count_Mouth%10; led_Disp_Buff[2]=count_Day/10; led_Disp_Buff[3]=count_Day%10; dot_On(DOT_TWO); //小数点常亮}void week_Display(void){ switch(current_Event) { case0:break; case1:break; case2:sys_State=0x14;break; //down,切换至时间显示 case3:sys_State=0x12;break; //up,切至月日显示 case4:{sys_State=0x10;break;} //进入菜单P-1 default:break; } led_Disp_Buff[0]=21; led_Disp_Buff[1]=21; led_Disp_Buff[2]=21; led_Disp_Buff[3]=count_Week%8; }void hour_Display(void){ switch(current_Event) { case0:{break;} case1:{break;} case2:{sys_State=0x15;break;} //down,切换至秒显示 case3:{sys_State=0x13;break;} //up,切至周显示 case4:{sys_State=0x10;break;} //进入菜单P-1 default:{break;} } led_Disp_Buff[0]=count_Hour/10; led_Disp_Buff[1]=count_Hour%10; led_Disp_Buff[2]=count_Minute/10; led_Disp_Buff[3]=count_Minute%10; if(flag_Flash) //小数点闪烁 { dot_On(DOT_TWO); } else { dot_Off(DOT_TWO); }}void second_Display(void){ switch(current_Event) { case0:break; case1:break; case2:{sys_State=0x11;break; } //down,切换至年显示 case3:{sys_State=0x14;break; } //up,切至时间显示 case4:{sys_State=0x10;break;} //进入菜单P-1 default:break; } led_Disp_Buff[0]=10; led_Disp_Buff[1]=10; led_Disp_Buff[2]=count_Second/10; led_Disp_Buff[3]=count_Second%10; }void stop_Watch(void) //秒表{ switch(current_Event) { case0:break; case1:{sys_State=0x14;break; } //返回显示时间 case2:{count_Watch=0;break; } case3:{count_Watch=0;break; } //秒表清0 case4:{watch_stop=~watch_stop;break;} //秒表暂停 default:break; } if(watch_stop) //跑秒标志位打开时,进行跑秒 { if(flag_10ms) { flag_10ms=0; if(count_Watch!=1000) { count_Watch ++; } else { count_Watch=0; } } } led_Disp_Buff[0]=count_Watch/1000; led_Disp_Buff[1]=count_Watch/100%10; led_Disp_Buff[2]=count_Watch/10%10; led_Disp_Buff[3]=count_Watch%10; }void alarm_Clock_Open(void){ switch(current_Event) { case0:break; case1:{if(clock_stop)sys_State=0x33;elsesys_State=0x30;break;} //如果闹钟设置开,进入设置时间状态 case2:{clock_stop=0;break; } //闹钟关 case3:{clock_stop=1;break; } //开闹钟 case4:{sys_State=0x30;break;} //退出菜单P-3 default:break; } if(clock_stop) //若闹钟开,显示on { led_Disp_Buff[0]=10; led_Disp_Buff[1]=0; led_Disp_Buff[2]=29; led_Disp_Buff[3]=10; } else //否则显示off { led_Disp_Buff[0]=10; led_Disp_Buff[1]=0; led_Disp_Buff[2]=16; led_Disp_Buff[3]=16; } }void alarm_Clock_Hour_Set(void) //闹钟的时间设置{ switch(current_Event) { case0:break; case1:{sys_State=0x30;break;} //确认设置好时间时,退出菜单P-3 case2:{alarm_Clock_Hour--;break;} case3:{alarm_Clock_Hour++;break;} //设置闹钟时间 case4:{sys_State=0x33;break;} //切换至闹钟调分钟 default:break; } if(alarm_Clock_Hour>=24) { alarm_Clock_Hour=0; } if(alarm_Clock_Hour<0) { alarm_Clock_Hour=23; } led_Disp_Buff[2]=alarm_Clock_Minute/10; led_Disp_Buff[3]=alarm_Clock_Minute%10; if(flag_Flash) { //小时闪烁 led_Disp_Buff[0]=alarm_Clock_Hour/10; led_Disp_Buff[1]=alarm_Clock_Hour%10; } else { led_Disp_Buff[0]=10; led_Disp_Buff[1]=10; }}void alarm_Clock_Minute_Set(void) //闹钟的分钟设置{ switch(current_Event) { case0:break; case1:{sys_State=0x30;break;} //确认设置好时间时,退出菜单P-3 case2:{alarm_Clock_Minute--;break;} //设置闹钟分钟 case3:{alarm_Clock_Minute++;break;} case4:{sys_State=0x32;break;} //切换至闹钟调时间 default:break; } if(alarm_Clock_Minute==60) { alarm_Clock_Minute=0; } if(alarm_Clock_Minute<0) { alarm_Clock_Minute=59; } led_Disp_Buff[0]=alarm_Clock_Hour/10; led_Disp_Buff[1]=alarm_Clock_Hour%10; if(flag_Flash) //分钟闪烁 { led_Disp_Buff[2]=alarm_Clock_Minute/10; led_Disp_Buff[3]=alarm_Clock_Minute%10; } else { led_Disp_Buff[2]=10; led_Disp_Buff[3]=10; }}{ static bit data alarm_Cnt=1; if(clock_stop==0) return; if(flag_Clock==1) { if(flag_Beep) //蜂鸣器间隔响 { beep_Ms(12000); } else{beep_Off();} } elseif(beep_Time==0) //闹钟响关闭后,不影响按键的提示音 { beep_Off(); } if((alarm_Clock_Hour==count_Hour)&(alarm_Clock_Minute==count_Minute)&alarm_Cnt) { alarm_Cnt=0; //检测完一次闹钟到时,关闭alarm_Cnt,避免再次检测闹钟 flag_Clock=1; //闹钟响标志位 } if((alarm_Clock_Minute!=count_Minute)) //若无人按下暂停键,1minute后自动停止 { alarm_Cnt=1; flag_Clock=0; } if(flag_Clock==0)return; switch(current_Event) //若闹钟响了,可按任意键停 { case0:break; case1: case2: case3:// case4:// if(beep_Time==0) { beep_Off(); flag_Clock=0; } break;// default:break; } } void timer_Deal() //时间处理{//秒处理 if(1==flag_1s) { flag_1s=0; if(count_Second!=59) { count_Second++; } else { count_Second=0; } }//分处理 if(1==flag_1min) { flag_1min=0; if(count_Minute!=59) { count_Minute++; } else { count_Minute=0; flag_1hour=1; } }//时处理 if(1==flag_1hour) { flag_1hour=0; if(count_Hour!=23) { count_Hour++; } else { count_Hour=0; flag_1day=1; } }//周处理 if(1==flag_1day) { flag_1day=0; if(count_Week!=7) { count_Week++; } else { count_Week=1; } //天处理 if(count_Day!=30) { count_Day++; } else { count_Day=0; flag_1mouth=1; } } //月处理 if(flag_1mouth==1) { if(count_Mouth!=12) { count_Mouth++; } else { count_Mouth=0; count_Year++; //年处理 } }}Beep.c//======================================================//文件名称:蜂鸣器//功能说明://===================包含头文件=========================#include "beep.h"uint data beep_Time=0;void beep_On(){ buzBit=0;}void beep_Off(){ buzBit=1;}void beep_Ms(uintnum){ beep_On(); beep_Time=num/5;}void deBeepTime(){ if(beep_Time) { beep_Time--; } else { beep_Off(); }}Int_Deal.c//==================================================================//文件名称: 时基处理//资源说明:12M晶体//==================================================================#include "Int_Deal.h"#include "key.h"#include "beep.h"bit dataflag_5ms;bitdataflag_led_5ms;bitdataflag_10ms;bitdataflag_500ms;bitdataflag_1s;bitdataflag_10s;bitdataflag_1min;bitdataflag_10min;//bitdataflag_1hour;bitdataflag_10hours;bitdataflag_Flash;bitdataflag_Beep;uchardatacount_10ms;uchardatacount_500ms;uchardatacount_1s;uchardatacount_10s;uchardatacount_1min;uchardatacount_10min;uchardatacount_1hour;uchardatacount_10hours;voidTimer0_init(void){ TMOD=0x01; TH0=0xee; TL0=0x00; ET0=1; EA=1; TR0=1; }voidT0_ISR(void)interrupt1{ TR0=0; TH0=0xee; TL0=0x00; flag_5ms=1; TR0=1;}voidmn_Timer_Base(void){ if(flag_5ms==1) { flag_5ms=0; count_10ms++; count_1s++; count_500ms++; deBeepTime(); flag_led_5ms=1; if(count_10ms==2) { count_10ms=0; flag_10ms=1; deKeyTime(); } if(count_500ms==100) { count_500ms=0; flag_500ms=~flag_500ms; flag_Flash=~flag_Flash; flag_Beep=~flag_Beep; } if(count_1s==200) { count_1s=0; flag_1s=1; count_10s++; } if(count_10s==10) { count_10s=0; flag_10s=~flag_10s; count_1min++; } if(count_1min==6) { count_1min=0; flag_1min=1; count_10min++; } if(count_10min==10) { count_10min=0; flag_10min=1; count_1hour++; } } }Key.c//==================================================================//文件名称:按键扫描//功能说明:直入式8键键盘===============================================#include "key.h"#include "beep.h"#include "app.h"#define KeyPort P2 //按键端口#define KeyNumber 8 //按键数目#define KeyTime 5 //防抖定时时间,10*5msuchar data KeyInBuf; //读入当前键值缓冲区uchar data KeyChkBuf; //待确认的键uint data KeyTimeBuf; //防抖动时间处理单元//uchar data KeyCvtBuf; //确认后的有效键值//uchar data KeyOldBuf; //旧键状态缓冲区//bit bdata KeyFlag; //键按下标志位uchar data Key_state; //键状态//uchardata KeyvluBuf=0; //键值寄存器void key_Init(void){ //配置IO// P3M&=0x00; //P3口设置为输入// P3UR|=0xff; //使能上拉 KeyTimeBuf=0; // KeyChkBuf=0;}void mn_Key(void){ keyIn(); keyScan();}void keyIn(void){ uchartemp; KeyInBuf=KeyPort; KeyInBuf^=0xff; //按位取反 if(KeyInBuf) { temp=1; while((KeyInBuf&0x01)==0) { KeyInBuf>>=1; //若不是,则将转换寄存器的值左移一位,键值寄存器加1 temp++; //短按键值会有 } KeyInBuf=temp; }}void keyScan(void){ switch(Key_state) { case0: //检测是否有键按下 { if(KeyInBuf) //按键按下 { KeyChkBuf=KeyInBuf; KeyTimeBuf=KeyTime; Key_state=1; } else //按键弹起 { KeyChkBuf=KeyInBuf; } break; } case1: { if(KeyInBuf==KeyChkBuf) { if(KeyTimeBuf==0) //消抖完成,进入长短按检测状态 { beep_Ms(50); //KeyCvtBuf=KeyChkBuf; Key_state=2; KeyTimeBuf=(30*KeyTime); //装载长按时间值,30*10*5=1500ms } } else { //KeyCvtBuf=0;//转换寄存器清0 KeyChkBuf=0;//检测寄存器清0 Key_state=0;//回到状态0 KeyTimeBuf=0; } break; } case2: { if(KeyInBuf==KeyChkBuf) //长按跳转 { if(KeyTimeBuf==0) { Key_state=3; beep_Ms(50); KeyTimeBuf=(20*KeyTime); //装载长按到连击间隔时间,20*10*5=1000ms } } if(KeyInBuf!=KeyChkBuf) //检测短按 { if(KeyTimeBuf!=0) { write_Event(KeyChkBuf); KeyChkBuf=0; Key_state=0; KeyTimeBuf=0; //清除长按时间 } } break; } case3: { if(KeyInBuf==KeyChkBuf) //检测跳转 { if(KeyTimeBuf==0) { //KeyCvtBuf=KeyChkBuf; Key_state=4; beep_Ms(50); write_Event(0x40|KeyChkBuf); //写初次连击事件 KeyTimeBuf=(4*KeyTime); //装载连击间隔时间,4*10*5=200ms } } if(KeyInBuf!=KeyChkBuf) //检测长按,未到连击 { if(KeyTimeBuf!=0) { write_Event(0x80|KeyChkBuf); //写长按事件 KeyChkBuf=0; Key_state=0; KeyTimeBuf=0; //清除连击检测时间 } } break; } case4: { if(KeyInBuf==KeyChkBuf) //检测连击 { if(KeyTimeBuf==0) { beep_Ms(50); write_Event(0x40|KeyChkBuf); //写连击事件 KeyTimeBuf=(4*KeyTime); //装载连击间隔时间,4*10*5=200ms } } if(KeyInBuf!=KeyChkBuf) //检测连击 { if(KeyTimeBuf!=0) { //KeyCvt

温馨提示

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

评论

0/150

提交评论