单片机课程设计多功能定时器一、设计目的:1、在理论学习的基础上,通过完成一个涉及MCS-51单片机多种资源应用并具有综合功能的小系统目标板的设计与编程应用;2、能够对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,在软件编程、排错调试、相关仪器设备的使用技能等方面得到较全面的锻炼和提高;3、使学生增进对单片机的感性认识,加深对单片机理论方面的理解。
使学生掌握单片机的内部功能模块的应用,如定时器/计数器、中断、片内外存贮器、I/O口、串行口通信等;4、使学生了解和掌握单片机应用系统的软硬件设计过程、方法及实现,为以后设计和实现单片机应用系统打下良好基础。
二、设计功能说明数字钟是采用数字电路实现对时,分,秒,数字显示的计时装置,由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表的报时功能。
数字钟已成为人们日常生活中的必需品,本设计可实现如下功能:1、使用实时时钟芯片写入及读取时间2、用LCD显示,可显示年、月、日、时、分、秒、星期、农历日期、节日3、选择蜂鸣器电路,实现两个闹钟设置和事件提示功能4、实现时钟校正功能,12小时/24小时切换功能5、显示当前时间为上午时间或下午时间6、整点报时功能按键功能如下:1、对显示时间的设置按键0:进入设置模式,实现秒(S)、分(M)、时(H)、年(Y)、月(m)、日(D)、星期(W)设置的切换,并在LCD右下角显示所设置的项目,当各项目设置完毕后,再按下按键0则返回主界面正常显示时间;按键1:每按一次按键1,对所设置的时间加1,当设置的时间超过它的最大值时,该项自动为0,例如:当设置秒为59时,秒自动清零;按键2:每按一次按键:2,对所设置的时间减1,当设置的时间小于0时,该项自动为它的最大值;按键3:设置完成后的确认键并可按此键中途退出设置,时间按用户设置值正常计时;按键7:实现时钟校正功能,12小时/24小时切换功能。
2、对闹钟的设置按键4:进入闹钟1的设置,并在LCD右上方显示“CLOCK1”并通过按键0、1、2设置用户所需闹钟时间,完成闹钟1的设置后,通过按键0进入闹钟2的设置,并在LCD右上方显示“CLOCK2”,若无需设置闹钟2,则通过按键3退出闹钟设置,返回主界面正常显示时间;按键5:设置闹钟是否开启,例如:当设置闹钟1为开启状态时,在LCD右上方显示“*CLOCK1”当闹钟,并在返回主界面后显示“C1”表示闹钟1开启;三、整体设计思路这部分主要介绍工作安排和整体设计的思想。
工作过程规划如下:四、主程序流程图五、电气原理图(见附图)六、实验程序1、键盘程序(Keyprocess)键盘与848相连接,采用矩阵键盘的方式P2用于列扫描,P1用于行扫描,经过消抖及等待键释放的程序,将最终正确的结果置于getkey();程序实现如下:#include"aduc848.h"void KeyDelay(unsigned int KeyJsTime); //键盘扫描延时函数声明unsigned char GetKey(); //扫描后获取键值unsigned char GetKey(){static unsigned char KeyHaveFree=1;static unsigned int KeyJs=0;unsigned char temp,KeyTemp=0xff;P1&=0xf0;P2&=0xf0; // 将低四位置零做I/O口temp=P1&0x0f;if(KeyHaveFree){if(temp!=0x0f){KeyDelay(1000); //延时消除抖动if(temp==(P1&0x0f)) //延时后确认是否有键按下,并获取具体键值{P2|=0x0e;switch(P1&0x0f){case 0x0e:KeyTemp=3;break;case 0x0d:KeyTemp=7;break;case 0x0b:KeyTemp=11;break;case 0x07:KeyTemp=15;break;case 0x0f:break;default:KeyTemp= 0x80;break;}P2&=0xf0;P2|=0x0d;switch(P1&0x0f){case 0x0e:KeyTemp= 2;break;case 0x0d:KeyTemp= 6;break;case 0x0b:KeyTemp= 10;break;case 0x07:KeyTemp= 14;break;case 0x0f:break;default:KeyTemp= 0x81;break;}P2&=0xf0;P2|=0x0b;switch(P1&0x0f){case 0x0e:KeyTemp= 1;break;case 0x0d:KeyTemp= 5;break;case 0x0b:KeyTemp= 9;break;case 0x07:KeyTemp= 13;break;case 0x0f:break;default:KeyTemp= 0x82;break;}P2&=0xf0;P2|=0x07;switch(P1&0x0f){case 0x0e:KeyTemp= 0;break;case 0x0d:KeyTemp= 4;break;case 0x0b:KeyTemp= 8;break;case 0x07:KeyTemp= 12;break;case 0x0f:break;default:KeyTemp= 0x83;break;}KeyHaveFree=0; //LCDPrintNumber(6,11,5,KeyTemp);}}}else{KeyJs++;if(KeyJs>70){KeyHaveFree=1;KeyJs=66;}if(temp==0x0f){KeyHaveFree=1;KeyJs=0;}KeyTemp=0xf0;}return KeyTemp;}void KeyDelay(unsigned int KeyJsTime){unsigned char temp;unsigned int JsKeyDelay;for(JsKeyDelay=0;JsKeyDelay<KeyJsTime;JsKeyDelay++)temp++; }2、Lcd程序(1602)#include "aduc848.h"sbit RS=P3^6;sbit RW=P3^5;//位定义sbit EN=P3^3;void delay(unsigned int z);延时函数声明void write_(unsigned char );LCD显示位置函数声明void write_data(unsigned char date);写数据函数声明void init();{RS=0;RW=0;EN=0;write_(0x38);write_(0x0f);write_(0x06);}void delay(unsigned int z) //延时函数延时时间=Z*110{unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_(unsigned char ) //{RS=0;RW=0;P0=;delay(5);EN=1;delay(5);EN=0;}void write_data(unsigned char date){RS=1;RW=0;P0=date;delay(5);EN=1;delay(5);EN=0;}3、iic程序(RTC)//实时时钟#include"aduc848.h"void iic_start(void);void iic_stop(void);void iic_ack(void);bit read_ack(void);void iic_nack();unsigned char get_byte(void);void out_byte(unsigned char dd);void IIC_Delay_us(unsigned int times);void ReadTime(unsigned char TIME[7]); void SetTime(unsigned char TIME[7]);void SwitchRTC(unsigned char SWITCH);void ReadTime(unsigned char TIME[7]) {bit EATemp;unsigned char temp;EATemp=EA;iic_start();out_byte(0xd0);read_ack();out_byte(0x00);read_ack();iic_stop();IIC_Delay_us(1);iic_start();out_byte(0xd1);read_ack();TIME[0]=get_byte();iic_ack();TIME[1]=get_byte();iic_ack();TIME[2]=get_byte();iic_ack();TIME[3]=get_byte();iic_ack();TIME[4]=get_byte();iic_ack();TIME[5]=get_byte();iic_ack();TIME[6]=get_byte();iic_nack();iic_stop();IIC_Delay_us(1);TIME[0]=((TIME[0]&0x7f)>>4)*10+(TIME[0]&0x0f); //second TIME[1]=((TIME[1]&0x7f)>>4)*10+(TIME[1]&0x0f); //minuteif(TIME[2]&0x40){if(TIME[2]&0x20)temp=0x80;else temp=0x40;TIME[2]=((TIME[2]&0x1f)>>4)*10+(TIME[2]&0x0f); //hour TIME[2]|=temp;}else{TIME[2]=((TIME[2]&0x3f)>>4)*10+(TIME[2]&0x0f);}TIME[3]=TIME[3]&0x07; //week TIME[4]=((TIME[4]&0x3f)>>4)*10+(TIME[4]&0x0f); //dateTIME[5]=((TIME[5]&0x1f)>>4)*10+(TIME[5]&0x0f); //monthTIME[6]=(TIME[6]>>4)*10+(TIME[6]&0x0f); //yearEA=EATemp;}void SetTime(unsigned char TIME[7]){bit EATemp;unsigned char temp=0;unsigned char TimeTemp[7];EATemp=EA;for(temp=0;temp<7;temp++)TimeTemp[temp]=TIME[temp];temp=0;TimeTemp[6]=((TimeTemp[6]/10)<<4)+(TimeTemp[6]%10); //Year TimeTemp[5]=((TimeTemp[5]/10)<<4)+(TimeTemp[5]%10); //Month TimeTemp[4]=((TimeTemp[4]/10)<<4)+(TimeTemp[4]%10); //Day TimeTemp[3]=((TimeTemp[3]/10)<<4)+(TimeTemp[3]%10); //Weekif((TimeTemp[2]&0xc0)==0x00) //Hour{TimeTemp[2]=((TimeTemp[2]/10)<<4)+(TimeTemp[2]%10);}else{if((TimeTemp[2]&0xc0)==0x01)temp=0x40;else temp=0x60;TimeTemp[2]&=0x3f;TimeTemp[2]=((TimeTemp[2]/10)<<4)+(TimeTemp[2]%10);TimeTemp[2]|=temp;}TimeTemp[1]=((TimeTemp[1]/10)<<4)+(TimeTemp[1]%10); //Minute TimeTemp[0]=((TimeTemp[0]/10)<<4)+(TimeTemp[0]%10); //Second TimeTemp[0]&=0x7f;iic_start();out_byte(0xd0);read_ack();out_byte(0x00);read_ack();out_byte(TimeTemp[0]);read_ack();out_byte(TimeTemp[1]);read_ack();out_byte(TimeTemp[2]);read_ack();out_byte(TimeTemp[3]);read_ack();out_byte(TimeTemp[4]);read_ack();out_byte(TimeTemp[5]);read_ack();out_byte(TimeTemp[6]);read_ack();iic_stop();IIC_Delay_us(1);EA=EATemp;}void SwitchRTC(unsigned char SWITCH) {unsigned char temp;bit EATemp;EATemp=EA;iic_start();out_byte(0xd0);read_ack();out_byte(0x00);read_ack();iic_stop();//IIC_Delay_us(1);iic_start();out_byte(0xd1);read_ack();temp=get_byte();iic_nack();iic_stop();//IIC_Delay_us(1);if(SWITCH)temp&=0x7f;else temp|=0x80;iic_start();out_byte(0xd0);read_ack();out_byte(0x00);read_ack();out_byte(temp);read_ack();iic_stop();//IIC_Delay_us(1);EA=EATemp;}void iic_start(void){MDE=1;MDO=1;//IIC_Delay_us(2);MCO=1;//IIC_Delay_us(2);MDO=0;//IIC_Delay_us(2); }void iic_stop(void){MDE=1;MDO=0;//IIC_Delay_us(2);MCO=1;//IIC_Delay_us(2);MDO=1;}void iic_ack(void){MDE=1;MCO = 0;MDO = 0;//IIC_Delay_us(2);MCO = 1;//IIC_Delay_us(2);MCO = 0;//IIC_Delay_us(1);MDO = 1;}bit read_ack(void){bit flag;MCO = 0;//IIC_Delay_us(2);MDE=1;MDO = 1;MCO = 1;//IIC_Delay_us(2);MDE=0;flag = MDI;MCO = 0;return flag;}void iic_nack(){MDE=1;MDO = 1;//IIC_Delay_us(2);MCO = 1;//IIC_Delay_us(2);MCO = 0;}/************************************************************************** ********** 函数名: get_byte;* 描述: 从IIC总线获取一个字节;* 输入: none;* 返回值: 一字节数据;* 注释: none;*************************************************************************** *********/unsigned char get_byte(void) //输入一个字节{unsigned char dd;int i;dd=0;MDE=1;MDO = 1;MDE=0;for (i=0;i<8;i++){MCO = 0;IIC_Delay_us(1);MCO = 1;//IIC_Delay_us(1);dd<<=1;if (MDI)dd|=0x01;}MCO = 0;return(dd);}/************************************************************************** ********** 函数名: out_byte;* 描述: 向IIC总线输出一个字节;* 输入: 一字节数据* 返回值: none;* 注释: none;*************************************************************************** *********/void out_byte(unsigned char dd) //输出一个字节{unsigned char i;MDE=1;for(i=0;i<8;i++){MCO = 0;//IIC_Delay_us(0);MDO = (dd & 0x80)>>7;IIC_Delay_us(1);MCO = 1;//IIC_Delay_us(3);dd <<= 1;}MCO = 0;}/************************************************************************** ********** 函数名: IIC_Delay_us;* 描述: IIC总线延时函数;* 输入: 延时参数* 返回值: none;* 注释: none;*************************************************************************** *********/void IIC_Delay_us(unsigned int times){unsigned int i;unsigned char DelayJs;for (i=0; i<times; i++)DelayJs++;}4、主程序(Prj6)#include"aduc848.h"#include"KeyProcess.h"#include"rtc.h"#include"LCD1602.h"unsigned char CurrentTime[7]={55,59,21,6,23,04,11};unsigned char ClockSetSave1[3]={10,00,22},ClockSetSave2[3]={20,00,22};unsigned char code table[7]={0x53,0x4d,0x48,0x59,0x6d,0x44,0x57};unsigned char code table1[4]={0x20,0x53,0x4d,0x48};unsigned char KeyValue,ClockKeyValue,shijianzhi=0;unsigned char SetMode=0;unsigned char ShowMode=0;unsigned char Clock=1,ClockSet=0,FinishClockSet1=0,FinishClockSet2=0,ClockEn1=0,ClockEn2=0; unsigned int i=0;void KeyProcess();void stop(){P1&=0xf0;P2|=0x0f;P2&=0xfe;if((P1&0x08)==0){P2&=0xfe;}}void main(){PLLCON&=0xf8;//设置频率为12.58MHzCFG848|=0x01;//使用片内xraminit();I2CCON=0xE8;//配置IIC 为软件主发送模式SetTime(CurrentTime);SwitchRTC(1);write_(0x82); //写冒号write_data(0x3A);write_(0x85); //写冒号write_data(0x3A);write_(0xc2); //写短横线write_data(0x2D);write_(0xc5); //写短横线write_data(0x2D);write_(0xc8); //写短横线write_data(0x2D);while(1){stop();if(SetMode==0)ReadTime(CurrentTime);write_(0x80);write_data(CurrentTime[2]/10+48); //Hourwrite_data(CurrentTime[2]%10+48);write_(0x83);write_data(CurrentTime[1]/10+48); //Minutewrite_data(CurrentTime[1]%10+48);write_(0x86);write_data(CurrentTime[0]/10+48); //Secondwrite_data(CurrentTime[0]%10+48);write_(0xc0);write_data(CurrentTime[6]/10+48); //Yearwrite_data(CurrentTime[6]%10+48);write_(0xc3);write_data(CurrentTime[5]/10%10+48); //Monthwrite_data(CurrentTime[5]%10+48); write_(0xc6); write_data(CurrentTime[4]/10%10+48); //Day write_data(CurrentTime[4]%10+48);switch(CurrentTime[3]) //Week{case1:{write_(0xc9);write_data(0x4D);write_data(0x6f);write_data(0x6e);break;}//显示Moncase2:{write_(0xc9);write_data(0x54);write_data(0x75);write_data(0x65);break;}//显示Tuecase3:{write_(0xc9);write_data(0x57);write_data(0x65);write_data(0x64);break;}//显示Wencase4:{write_(0xc9);write_data(0x54);write_data(0x68);write_data(0x75);break;}//显示Thucase5:{write_(0xc9);write_data(0x46);write_data(0x72);write_data(0x69);break;}//显示Fricase6:{write_(0xc9);write_data(0x53);write_data(0x61);write_data(0x74);break;}//显示Satcase7:{write_(0xc9);write_data(0x53);write_data(0x75);write_data(0x6e);break;}//显示Sundefault: break;}KeyProcess();if((CurrentTime[0]==ClockSetSave1[0]&&CurrentTime[1]==ClockSetSave1[1]&&CurrentT ime[2]==ClockSetSave1[2])&&ClockEn1==1 || (CurrentTime[0]==ClockSetSave2[0]&&CurrentTime[1]==ClockSetSave2[1]&&CurrentTime[2] ==ClockSetSave2[2])&&ClockEn2==1) //与闹铃时间相同则闹铃响{PWM1H=62;PWM1L=100;PWMCON=0x31;KeyDelay(333);PWM1H=0;PWM1L=0;PWMCON=0x00;KeyDelay(333);}if(CurrentTime[0]==0&&CurrentTime[1]==0) //整点报时{PWM1H=62;PWM1L=100;PWMCON=0x21; //对闹铃响铃时长和音调等的设定KeyDelay(333);PWM1H=0;PWM1L=0;PWMCON=0x00;KeyDelay(333);}if(ClockEn1==1) //如果闹铃1被设置则显示C1 {write_(0x8c);write_data(0x43);write_data(0x31);}else //否则清显{write_(0x8c);write_data(0x20);write_data(0x20);}if(ClockEn2==1) //如果闹铃2被设置则显示C1 {write_(0x8e);write_data(0x43);write_data(0x32);}else //否则清显{write_(0x8e);write_data(0x20);write_data(0x20);}}}void KeyProcess() //按键处理,启动按键扫描{KeyValue=GetKey();switch(KeyValue){case 0: //按键0进入设置模式{write_(0xcf);write_data(table[SetMode]); //显示被设置项if(SetMode==0)SwitchRTC(0); //进入设置,则停止计时SetMode++;if(SetMode>7) //如果设置完了,则开始计时{SetMode=0;SetTime(CurrentTime);if(SetMode==0)SwitchRTC(1);write_(0xcf);write_data(0x20);}}break;case 1: //按键1:加{switch(SetMode) //执行按键1是在进入设置的模式下{case1:write_(0xcf);write_data(0x53);CurrentTime[0]++;if(CurrentTime[0]>59)CurrentTime[0]=0;brea k;//miaocase2:write_(0xcf);write_data(0x4d);CurrentTime[1]++;if(CurrentTime[1]>59)CurrentTime[1]=0;brea k;//fencase3:write_(0xcf);write_data(0x48);CurrentTime[2]++;if(CurrentTime[2]>23)CurrentTime[2]=0;brea k;//shicase4:write_(0xcf);write_data(0x59);CurrentTime[6]++;if(CurrentTime[6]>99)CurrentTime[6]=0;brea k;//yearcase5:write_(0xcf);write_data(0x6d);CurrentTime[5]++;if(CurrentTime[5]>12)CurrentTime[5]=1;brea k;//monthcase 6://day{write_(0xcf);write_data(0x44);CurrentTime[4]++;switch(CurrentTime[5]){case 1:case 3:case 5:case 7:case 8:case 10:case 12:if(CurrentTime[4]>31)CurrentTime[4]=1;break;case 4:case 6:case 9:case 11:if(CurrentTime[4]>30)CurrentTime[4]=1;break;case 2: if(CurrentTime[6]%4)if(CurrentTime[4]>28)CurrentTime[4]=1;else if(CurrentTime[4]>29)CurrentTime[4]=1;break;default:break;}}break;case7:write_(0xcf);write_data(0x57);CurrentTime[3]++;if(CurrentTime[3]>7)CurrentTime[3]=1;break; //weekdefault:break;}}break;case 2: //按键2:减{switch(SetMode){case1:CurrentTime[0]--;if(CurrentTime[0]>254)CurrentTime[0]=59;break;//miaocase2:CurrentTime[1]--;if(CurrentTime[1]>254)CurrentTime[1]=59;break;//fencase3:CurrentTime[2]--;if(CurrentTime[2]>254)CurrentTime[2]=23;break;//shicase4:CurrentTime[6]--;if(CurrentTime[6]>254)CurrentTime[6]=99;break;//yearcase5:CurrentTime[5]--;if(CurrentTime[5]>254)CurrentTime[5]=12;break;//monthcase 6://day{CurrentTime[4]--;switch(CurrentTime[5]){case 1:case 3:case 5:case 7:case 8:case 10:case 12:if(CurrentTime[4]>254)CurrentTime[4]=31;break;case 4:case 6:case 9:case 11:if(CurrentTime[4]>254)CurrentTime[4]=30;break;case 2: if(CurrentTime[6]%4)if(CurrentTime[4]>254)CurrentTime[4]=28;else if(CurrentTime[4]>254)CurrentTime[4]=29;break;default:break;}}break;case 7:CurrentTime[3]--;if(CurrentTime[3]>7)CurrentTime[3]=1;break; //weekdefault:break;}}break;case 3: //按键3中途退出设置模式{if(SetMode!=0) //在设置模式中中途退出{SetTime(CurrentTime);SetMode=0;SwitchRTC(1); //开计时write_(0xcf);write_data(0x20);}}break;case 4: //按键4设置闹铃{write_(0xcf);write_data(0x20);while(Clock!=0) //用Clock来进行判断闹铃设置完否{switch(Clock){case 1: { //****************闹铃1while(FinishClockSet1!=1){write_(0x80);write_data(ClockSetSave1[2]/10+48); //Hourwrite_data(ClockSetSave1[2]%10+48);write_(0x83);write_data(ClockSetSave1[1]/10+48); //Minutewrite_data(ClockSetSave1[1]%10+48);write_(0x86);write_data(ClockSetSave1[0]/10+48); //Secondwrite_data(ClockSetSave1[0]%10+48);write_(0x8a); //闹铃设置序号显示write_data(0x43);write_data(0x4c);write_data(0x4f);write_data(0x43);write_data(0x4b);write_data(0x31);if(ClockEn1==0){write_(0x89);write_data(0x20);}else{write_(0x89);write_data(0x2a);}ClockKeyValue=GetKey();switch(ClockKeyValue){case 0: //按键0设置闹钟{ClockSet++;write_(0xcf);write_data(table1[ClockSet]);if(ClockSet>3) //设置键按完三次自动进入下一个闹铃设置{ClockSet=0;FinishClockSet1=1;Clock++;write_(0xcf);write_data(0x20);}}break;case 1: //闹铃设置+{switch(ClockSet){case1:write_(0xcf);write_data(0x53);ClockSetSave1[0]++;if(ClockSetSave1[0]>59)ClockSetSave1[0] =0;break;//miaocase2:write_(0xcf);write_data(0x4d);ClockSetSave1[1]++;if(ClockSetSave1[1]>59)ClockSetSave1[1] =0;break;//fencase3:write_(0xcf);write_data(0x48);ClockSetSave1[2]++;if(ClockSetSave1[2]>23)ClockSetSave1[2] =0;break;//shidefault:break;}}break;case 2: //闹铃设置2{switch(ClockSet){case1:write_(0xcf);write_data(0x53);ClockSetSave1[0]--;if(ClockSetSave1[0]>254)ClockSetSave1[0] =59;break;//miaocase2:write_(0xcf);write_data(0x4d);ClockSetSave1[1]--;if(ClockSetSave1[1]>254)ClockSetSave1[1] =59;break;//fencase3:write_(0xcf);write_data(0x48);ClockSetSave1[2]--;if(ClockSetSave1[2]>254)ClockSetSave1[2] =23;break;//shidefault:break;}}break;case 3: //中途退出闹铃设置{FinishClockSet1=1;Clock=0;write_(0x89); //闹铃设置序号清除显示write_data(20);write_data(20);write_data(20);write_(0x8e);write_data(20);write_data(20);write_(0xcf);write_data(0x20);}break;case 5: { //是否开启闹钟,并予以显示if(ClockEn1==0){ClockEn1=1;write_(0x89);write_data(0x2a);}else{ClockEn1=0;write_(0x89);write_data(0x20);}}break;default:break;} //case4->case1 end}}break;case 2 :{ //****************闹铃2 while(FinishClockSet2!=1){write_(0x80);write_data(ClockSetSave2[2]/10+48); //Hourwrite_data(ClockSetSave2[2]%10+48);write_(0x83);write_data(ClockSetSave2[1]/10+48); //Minutewrite_data(ClockSetSave2[1]%10+48);write_(0x86);write_data(ClockSetSave2[0]/10+48); //Secondwrite_data(ClockSetSave2[0]%10+48);write_(0x8a); //闹铃设置序号显示write_data(0x43);write_data(0x4c);write_data(0x4f);write_data(0x43);write_data(0x4b);write_data(0x32);if(ClockEn2==0){write_(0x89);write_data(0x20);}else{write_(0x89);write_data(0x2a);}ClockKeyValue=GetKey();switch(ClockKeyValue){case 0:{ClockSet++;write_(0xcf);write_data(table1[ClockSet]);if(ClockSet>3){ClockSet=0;FinishClockSet2=1;Clock=0;write_(0x89); //闹铃设置序号清除显示write_data(20);write_data(20);write_data(20);write_(0x8e);write_data(20);write_data(20);write_(0xcf);write_data(0x20);}}break;case 1:{switch(ClockSet){case1:write_(0xcf);write_data(0x53);ClockSetSave2[0]++;if(ClockSetSave2[0]>59)ClockSetSave2[0] =0;break;//miaocase2:write_(0xcf);write_data(0x4d);ClockSetSave2[1]++;if(ClockSetSave2[1]>59)ClockSetSave2[1] =0;break;//fencase3:write_(0xcf);write_data(0x48);ClockSetSave2[2]++;if(ClockSetSave2[2]>23)ClockSetSave2[2] =0;break;//shidefault:break;}}break;case 2:{switch(ClockSet){case1:write_(0xcf);write_data(0x53);ClockSetSave2[0]--;if(ClockSetSave2[0]>254)ClockSetSave2[0] =59;break;//miaocase2:write_(0xcf);write_data(0x4d);ClockSetSave2[1]--;if(ClockSetSave2[1]>254)ClockSetSave2[1] =59;break;//fencase3:write_(0xcf);write_data(0x48);ClockSetSave2[2]--;if(ClockSetSave2[2]>254)ClockSetSave2[2] =23;break;//shidefault:break;}}break;case 3:{FinishClockSet2=1;Clock=0;write_(0x89); //闹铃设置序号清除显示write_data(20);write_data(20);write_data(20);write_(0x8e);write_data(20);write_data(20);write_(0xcf);write_data(0x20);}break;case 5: {if(ClockEn2==0){ClockEn2=1;write_(0x89);write_data(0x2a);}else{ClockEn2=0;write_(0x89);write_data(0x20);}}break;default:break;} //case4->case2 end}}break;default:break;}}}break;case 7: { //12小时与24小时进制进行转换if((CurrentTime[2]>12)){CurrentTime[2]=CurrentTime[2]-12;SetTime(CurrentTime);}else{CurrentTime[2]=CurrentTime[2]+12;SetTime(CurrentTime);}}break;default:break;}}七、心得体会经过两周的的课程设计,过程曲折可谓一语难尽。