#include #include "ds1302.h" //包含DS1302头文件 #include "music_two_tiger.h" //#include "AT25F4096.h" sfr P0M1 = 0X93; sfr P0M0 = 0X94; sfr P1M1 = 0X91; sfr P1M0 = 0X92; sfr P2M1 = 0X95; sfr P2M0 = 0X96; #define leddata P0 //定义LED数据口 sbit SET=P2^0; //按键定义,下同 sbit UP=P2^1; sbit DOWN=P2^2; sbit MODE=P2^3; sbit led0=P2^7; //LED位选,因为布线不是按顺序布的,程序定义一下就可以了,下同 sbit led1=P2^6; sbit led2=P2^5; sbit led3=P2^4; sbit SYSLED=P1^4; sbit COL=P1^3; volatile SYSTEMTIME SysTime; unsigned char s_state = HOU_MIN; //sbit led4=P2^6; //sbit led5=P2^5; //**************函数声明***************** void delays(unsigned char); void display(void); void Scan_Key(void); void id_case1_key(); void id_case2_key(); void Set_id(unsigned char ,unsigned char); //*************变量定义****************** bit If_start_run_ringtime=0; char per_run_time = _PER_RUN_TIME; //每首曲子运行2次 char ring_space_1min = _RING_SPACE_1MIN; //每遍间隔1分钟 char ring_run_time = _RING_RUN_TIME; //重复5遍 char ring_flash_countdown = _RING_FLASH_COUNTDOWN/50; //闪烁3秒 unsigned char Ringtime_HOU=0xFF,Ringtime_MIN=0xFF,Ringtime_HOU_tmp=0xFF,Ringtime_MIN_tmp=0xFF; unsigned char id=0,timecount=0,re_disp=0,second_time=0; //定义用到的变量,id为调整模式用,不为0时表示调整模式,调整哪个量由id值确定 //timecount用于500ms定时记数,时间到取反flag标志位,re_disp记数200次共10s,调整状态下按键无操作10s自动返回正常显示状态 bit hour,minute,second,month,days,years_1,years_2,flag,flag_1302_1s,system_1s_flag; //定义位变量,hour,minute,second分别为调整时闪烁标志位,flag 500ms取反一次,调整位闪烁及冒号闪烁用 unsigned char system_26s_flag; unsigned char set_flash_flag = 0xFF; bit If_play_music = 0; bit If_start_flash = 0; bit If_Into_set_ringtime = 0; //1进入,0退出 //unsigned char code tab[]={0x48,0xEE,0x54,0xC4,0xE2,0xC1,0x41,0xEC,0x40,0xC0,0x60}; //LED码表,根据硬件修改 unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char inittime[7]={0x00,0x00,0x12,0x16,0x07,0x29,0x24}; //初始化1302时用到的初始化数据 年2014-1990=24 // 秒 分钟 小时 日 月 星期 年 /* void t0(void) interrupt 1 using 0 //中断处理程序,主要用于取反标志位,返回正常显示状态 { TH0=(65535-50000)/256; //50ms定时 TL0=(65535-50000)%256; timecount++;re_disp++;second_time++; if(timecount == 9) //10*50ms == 500ms { flag=~flag; timecount = 0; } if(second_time == 19) //20*50ms == 1000ms { flag_1302_1s=~flag_1302_1s; second_time = 0; system_26s_flag++; if(system_26s_flag > 25) system_26s_flag = 0; } if(re_disp>200){re_disp=0;if(id)id=0;} }*/ void delays(unsigned char k) //延时函数 { unsigned char i,j; for(i=0;imax) item=mini; if(item2)set_i=0; //id加1,后面根据id值对应调整项目 id = set_i; s_state=SET_HOU_MIN; } if(id==0){hour=0;minute=0;set_ringtime_case0();} //根据id值跳到相应处理函数 if(id==1){hour=1;set_ringtime_case1();} //id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同 else if(id==2){hour=0;minute=1;set_ringtime_case1();} } } void Scan_Key(void) //键盘检测函数 { display(); //程序开头调用显示函数 if(!SET) { while(!SET)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断 re_disp=0; //清除记数,重新开始10s定时 id++;if(id>7)id=0; //id加1,后面根据id值对应调整项目 switch(id) { case 0: s_state=HOU_MIN;break; case 1: s_state=HOU_MIN;break; case 2: s_state=HOU_MIN;break; case 3: s_state=MON_DAY;break; case 4: s_state=MON_DAY;break; case 5: s_state=YEAR_S;break; case 6: s_state=YEAR_S;break; case 7: s_state=SET_HOU_MIN;break; default:break; } } switch(id) { case 0: hour=0;minute=0;second=0;month=0;days=0;years_1=0;years_2=0;id_case2_key();break; //根据id值跳到相应处理函数 case 1: hour=1;id_case1_key();break; //id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同 case 2: hour=0;minute=1;id_case1_key();break; case 3: minute=0;month=1;id_case1_key();break; case 4: month=0;days=1;id_case1_key();break; case 5: days=0;years_1=1;id_case1_key();break; case 6: years_1=0;years_2=1;id_case1_key();break; case 7: years_2=0;Into_set_ringtime();break; default:break; } //if(id==3){minute=0;second=1;id_case1_key();} } void id_case1_key(void) //键盘处理函数,只有按下set键时才会进入, { display(); if (!DOWN) //减少 { while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断 re_disp=0; //清除记数,重新开始10s定时 Set_id(id,0); //跳到加减判断函数,下同, } if (!UP) //增加 { while(!UP)display(); re_disp=0; Set_id(id,1); } } void id_case2_key(void) //键盘处理函数,只有id==0时才会进入, { static char DOWN_key_add = HOU_MIN; display(); if (!DOWN) // { while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断 DOWN_key_add ++; if(DOWN_key_add > 2) DOWN_key_add = 0; if(DOWN_key_add == 0) s_state = HOU_MIN; else if(DOWN_key_add == 1) s_state = MON_DAY_HOU_MIN; else if(DOWN_key_add == 2) s_state = MIN_SECOND; } if (!UP) // { while(!UP)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断 DOWN_key_add --; if(DOWN_key_add < 0) DOWN_key_add = 2; if(DOWN_key_add == 0) s_state = HOU_MIN; else if(DOWN_key_add == 1) s_state = MON_DAY_HOU_MIN; else if(DOWN_key_add == 2) s_state = MIN_SECOND; } if (!MODE) { while(!MODE)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断 Into_set_ringtime(); } } //根据选择调整相应项目并写入DS1302 void Set_id(unsigned char sel,unsigned char sel_1) //执行调整项目的函数 { signed char max,mini,address,item; switch(sel) { case 1: address=DS1302_HOUR; max=23;mini=0;break; //小时 //根据id值确定要调整的项,并确定调整上下限,下同 case 2: address=DS1302_MINUTE; max=59;mini=0;break; //分钟 case 3: address=DS1302_MONTH; max=12;mini=1;break; //月 case 4: address=DS1302_DAY; max=31;mini=0;break; //日 case 5: address=DS1302_YEAR; max=20;mini=20;break; //年20 case 6: address=DS1302_YEAR; max=99;mini=0;break; //年14 default:break; } //if(sel==3) {address=sec; max=0;mini=0;} //秒 item=Read1302(address|DS1302_READ)/16*10+Read1302(address|DS1302_READ)%16; //从相应的地址读取当前数据并转换为十进制 if (sel_1==0) item--; else item++; //确定是对项目加还是减,并对越限处理 if(item>max) item=mini; if(item= 9) //10*50ms == 500ms { flag=~flag; if(set_flash_flag > 3) set_flash_flag = 0; if(If_start_flash == 1) set_flash_flag ++; timecount = 0; } if(second_time >= 19) //20*50ms == 1000ms { second_time = 0; system_1s_flag=~system_1s_flag; //系统读秒1302 system_26s_flag++; if(system_26s_flag > 25) system_26s_flag = 0; } if(re_disp>200){re_disp=0;if(id)id=0;} } void InitialT0T1(void) // { TMOD=0x11; //初始化定时器 方式2 波特率发生器 //TH0=0xFF; //T0高八位 //TL0=0xFF; //T0低八位 TH1=(65535-50000)/256; //T1高八位 TL1=(65535-50000)%256; //T1低八位 EA=1; //总中断开关 ET0=1; //T0中断 //TR0=0; //定时器T0 不开始计时 ET1=1; //T1中断 TR1=1; //定时器T1 开始计时 } /* void InitialT1(void) // { TMOD|=0x10; //初始化定时器 方式2 波特率发生器 TH1=(65535-50000)/256; //T0高八位 TL1=(65535-50000)%256; //T0低八位 EA=1; //总中断开关 ET1=1; //T0中断 TR1=1; //定时器T0 开始计时 }*/ void main() //主函数 { //配置播放器T0 模式3下 占用T1资源,所以 只能用T1(波特率发生器) //配置定时器T1 //InitialT1(); InitialT0T1(); //初始化,并启动DS1302的时钟 Write1302(0x90,0xa0);//关闭充电二级管,不能对后备电池进行充电,防止发胀,原来的程序是打开的请关闭 Write1302(0x8e,0x80);//写保护,禁止写操作 Initial_DS1302(); if(!UP&!DOWN)Set1302(inittime); //如果同时按下UP和DOWN键则初始化1302,该语句在while(1)前,只执行一次,需要复位,防止误操作 //配置P0口,全部推挽输出 01 P0M0 = 0x00; P0M1 = 0xFF; //延时稳定 SYSLED = 0; //系统灯开 delays(100); SYSLED = 1; //系统灯关 while(1) { SYSLED = system_1s_flag; //系统灯闪 DS1302_GetTime(&SysTime); //获取时间 Scan_Key(); //键盘检测和显示 if(!P3_0) { while(!P3_0)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断 If_play_music = 1; play_2tigers(); If_play_music = 0; } if(If_start_run_ringtime) { if(Ringtime_HOU == SysTime.Hour && Ringtime_MIN == SysTime.Minute) { if(ring_run_time--==0) //到了次数,不再播放 { Ringtime_HOU = 0xFF; Ringtime_MIN = 0xFF; If_start_run_ringtime = 0; ring_run_time = _RING_RUN_TIME; //初始化一下 下个5遍运行 ,不然ring_run_time--后,0xFF一直间隔响 } else //重装,间隔x分钟 ring_space_1min { Ringtime_HOU_tmp = Ringtime_HOU_tmp + (Ringtime_MIN_tmp + ring_space_1min)/59; Ringtime_MIN_tmp = (Ringtime_MIN_tmp + ring_space_1min)%59; Ringtime_HOU = Ringtime_HOU_tmp/10*16+Ringtime_HOU_tmp%10; //16进制保存 Ringtime_MIN = Ringtime_MIN_tmp/10*16+Ringtime_MIN_tmp%10; If_start_run_ringtime = 1; } If_play_music = 1; play_2tigers(); If_play_music = 0; } } } }