1/26单片机课程设计题目:多功能定时装置日期:2011年6月2/26一、设计要求:1)选择LED或LCD显示,可显示年、月、日、时、分、秒、星期、农历日期、节日、节气等(根据实际情况,选择部分或全部功能实现)2)会使用实时钟芯片3)选择蜂鸣器电路,实现闹钟设置和报警功能4)选择按键功能,设计实现时钟校正功能5)整点报时功能6)上电或RESET后能自动显示当前时间(时:分:秒):首次上电复位显示0时0分0秒,以后每次RESET均显示正确的当前时间附加实现功能:1)可以显示0.1—100s的秒表,最小单位为0.1秒2)通过按键控制秒表清零、暂停、继续、退出等功能3)秒表可以分组存储(最多10组),批量显示4)具有倒计时功能二、所使用的硬件1.ADUC848管脚图ADUC848管脚图如图1所示。3/26图1ADUC848管脚2.电源模块电源模块原理图如图2所示。图2电源模块4/263.数码管该模块原理如图3所示。图3数码管驱动电路4.RS232串口串口连接原理图如图4所示。图4RS232串口模块5/265.蜂鸣器该模块原理图如图5所示。图5蜂鸣器6.按键输入该模块原理如图6所示。图6按键模块三、程序流程图1)主流程图如图8所示:6/26图8主程序流程图当前时间是否等于闹钟设置时间en=0x55?(无键)或en=0x80?(无效键)开始读取当前时间读取键值,键值为en开启闹钟YNYen=1?en=2?en=3?en=4?en=8?en=9?en=13?en=14?显示年月日星期显示时分秒秒表正计时子程序秒表倒计时子程序显示正计时的记录值设置北京时间关闹钟1设置闹钟1en=0?设置闹钟2继续当前显示闹钟1开?开闹钟1en=13?关闹钟2闹钟2开?开闹钟2YYYYYYYYYYYNNNNNNNNNNN7/262)秒表正计时子程序流程图如图9所示:图9秒表正计时流程图3)秒表倒计时子程序流程图如图10所示图10秒表倒计时流程图正计时子程序启动定时器扫描键值,键值等于5?扫描键值,键值等于6?扫描键值,键值等于7?返回是否记录了十组值?记录当前时间显示当前时间YNYYYNNNY秒表倒计时子程序输入时间初值启动定时器蜂鸣报警,关定时器返回扫描键值,键值等于5?当前时间等于0?YNYN显示当前时间8/26四、程序1.主程序(miao_biao.c)如下:#includeaduc848.h#includekeypp.h#includeiic.h#defineucharunsignedchar#defineuintunsignedintunsignedcharb[7]={45,59,11,2,7,6,11},clock1[2]={12,0},clock2[2]={12,1};codeunsignedchartab[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x19,0x00};//共阴数码管0-9显示codeunsignedchartab2[]={0x39,0xff};//、全灭voiddelay(unsignedintcnt);//延时子程序unsignedchargetkey1();unsignedchargetkey2();//读键盘voidtim(void);//中断voidKeyDelay(unsignedintKeyJsTime);//键盘扫描延时voiddisplay(ucharbit7,ucharbit6,ucharbit5,ucharbit4,ucharbit3,ucharbit2,ucharbit1,ucharbit0);//显示子程序voidReadTime(unsignedcharTIME[7]);//DS1307读时间voidSetTime(unsignedcharTIME[7]);//设置时间初值voidSwitchRTC(unsignedcharSWITCH);voidiicdelay(unsignedinttimes);voidiicstart(void);voidiicstop(void);voidiicack(void);bitiicreadack();voidiicnack();voidiicwriteda(unsignedcharda);unsignedchariicreadda();voidiicdelay(unsignedintt);uchardis_num_h;//显示记录数据的组别十位uchardis_num_l;//显示记录数据的组别个位uchardis_min_h;//要显示的分的十位;uchardis_min_l;//要显示的分的个位;uchardis_sec_h;//要显示的秒的十位;uchardis_sec_l;//要显示的秒的个位;uchardis_dsec;//要显示的0.1秒;ucharmin=0x00;ucharsec=0x00;uchardsec=0x00;ucharen,i,clocken1=0,clocken2=0;main()9/26{unsignedcharquzhi,xianshi,symbol=0x55,set,set1=0x55,ce;unsignedcharc[30];unsignedcharnum,num1,j,k,stop=1;PLLCON&=0xf8;//设置频率为12.58MHzTMOD=0x01;//定时器工作模式设置TH0=0xce;//设定初值TL0=0x00;IE=0x82;//中断控制,10000010,EA=1开总中断,ET0=1:定时器0中断允许I2CCON=0xE8;//开启iic通信;SetTime(b);//设定初始时间;SwitchRTC(1);while(1){ReadTime(time);if(((clock1[0]==time[1])&&(clock1[1]==time[2])&&(clocken1==0)&&stop)||((clock2[0]==time[1])&&(clock2[1]==time[2])&&(clocken2==0)&&stop))//闹钟时间到{PWM0H=205;PWM1L=500;PWMCON=0x21;//蜂鸣器响KeyDelay(333);//延时PWM1H=0;PWM1L=0;PWMCON=0x00;KeyDelay(333);if(getkey1()==12)//键12按下时蜂鸣器停止蜂鸣stop=0;//无12键按下时,响一分钟后自动停止}if((time[1]==clock1[0]+1)||(time[1]==clock1[0]+1))stop=1;//一分钟后重新开启蜂鸣使能,以便下次闹钟顺利反应if((time[0]==0)&&(time[1]==0))//整点时,蜂鸣提醒{i=1;while(i){PWM0H=50;PWM1L=100;PWMCON=0x21;//蜂鸣器响KeyDelay(333);//延时PWM1H=0;PWM1L=0;PWMCON=0x00;//蜂鸣器关KeyDelay(333);i++;//控制蜂鸣器响的时间if(i==5)i=0;}}en=getkey1();if((en==0x80)||(en==0x55))//无键按下或有多个键按下时,视为无效,en仍为之前按键值en=symbol;if(xianshi==8)display(dis_num_h,dis_num_l,dis_min_h,dis_min_l,dis_sec_h,dis_sec_l,0xff,dis_dsec);//显示已记录的值///////////////////////////////////////////////////////////////////////////////////10/26if(en==1)//按键1按下,显示北京时间,年月日星期{symbol=1;display(tab[time[6]/10],tab[time[6]%10],tab[time[5]/10],tab[time[5]%10],tab[time[4]/10],tab[time[4]%10],0xff,tab[time[3]%10]);}////////////////////////////////////////////////////////////////////////////////////elseif(en==2)//按键2按下,显示北京时间,时分秒{symbol=2;display(tab2[clocken1],tab2[clocken2],tab[time[2]/10],tab[time[2]%10],tab[time[1]/10],tab[time[1]%10],tab[time[0]/10],tab[time[0]%10]);}////////////////////////////////////////////////////////////////////////////////////elseif(en==3)//按键3按下,秒表进入正计时工作模式{min=0;sec=0;dsec=0;num=1;symbol=3;while(1){quzhi=getkey1();if(num11)//最多可取值十组display(dis_min_h,dis_min_l,0xff,0xff,dis_sec_h,dis_sec_l,0xff,dis_dsec);else//取值多于十组时将“FULL”送显示display(0x71,0x83,0xe3,0xe3,0xff,0xff,0xff,0xff);if(quzhi==5)//按键5按下时,启动或关闭定时器,赋取值组别num初值{quzhi=0x55;if(TR0==1)TR0=0;elseTR0=1;}elseif(quzhi==6)//按键6按下时,秒表读值{quzhi=0x55;c[3*(num-1)+2]=dsec;//读出的值放在c[]中,依次存放各组的分、秒、十分秒c[3*(num-1)+1]=sec;c[3*(num-1)+0]=min;num++;}elseif(quzhi==7)//按键7按下,计时结束,清零,赋读值组别num1初值{TR0=0;num1=1;symbol=0x55;min=0;sec=0;dsec=0;break;11/26}}}//////////////////////////////////////////////////////////////////////////////////////elseif(en==4)//按键4按下,秒表进入倒计时模式{symbol=4;j=0;for(i=0;i=30;i++)c[i]=0;//将数组c清零while(1){display(dis_min_h,dis_min_l,0xff,0xff,dis_sec_h,dis_sec_l,0xff,dis_dsec);set=getkey1();//送入倒计时初值while(j5)//依次输入分十位、分个位、秒十位、秒个位、十分秒,设置初值{ce=getkey1();display(tab[c[0]],tab[c[1]],0xff,0xff,tab[c[2]],tab[c[3]],0xff,tab[c[4]]);if((ce!=0x55)&&(ce!=0x80))//按键有效时将值存入c中{if(ce9)ce=0;c[j]=ce;j++;}min=c[0]*10+c[1];//转化为分、秒及十分秒sec=c[2]*10+c[3];dsec=c[4];}dis_min_h=tab[min/10];//分、秒及十分秒显示值的处理dis_min_l=tab[min%10];dis_sec_h=tab[sec/10];dis_sec_l=tab[sec%10];dis_dsec=tab[dsec];if(set==5)//按键5按下,倒计时开始