else break; } else temp-=365; //平年 temp1++; } timer.w_year=temp1;//得到年份 temp1=0; while(temp>=28)//超过了一个月 { if(Is_Leap_Year(timer.w_year)&&temp1==1)//当年是不是闰年/2月份 { if(temp>=29)temp-=29;//闰年的秒钟数 else break; } else { if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年 else break; } temp1++; } timer.w_month=temp1+1;//得到月份 timer.w_date=temp+1; //得到日期 } temp=timecount?400; //得到秒钟数 timer.hour=temp/3600; //小时 timer.min=(temp600)/60; //分钟 timer.sec=(temp600)`; //秒钟 timer.week=RTC_Get_Week(timer.w_year,timer.w_month,timer.w_date);//获取星期 return 0; }
//获得现在是星期几
//功能描述:输入公历日期得到星期(只允许1901-2099年) //输入参数:公历年月日 //返回值:星期号
u8 RTC_Get_Week(u16 year,u8 month,u8 day) { u16 temp2; u8 yearH,yearL; yearH=year/100; yearL=year0; // 如果为21世纪,年份数加100 if (yearH>19)yearL+=100;
// 所过闰年数只算1900年之后的 temp2=yearL+yearL/4; temp2=temp2%7; temp2=temp2+day+table_week[month-1]; if (yearL%4==0&&month<3)temp2--; return(temp2%7); }
//比较两个字符串指定长度的内容是否相等 //参数:s1,s2要比较的两个字符串;len,比较长度 //返回值:1,相等;0,不相等
u8 str_cmpx(u8*s1,u8*s2,u8 len) { u8 i; for(i=0;i extern const u8 *COMPILED_DATE;//获得编译日期 extern const u8 *COMPILED_TIME;//获得编译时间 const u8 Month_Tab[12][3]={\}; //自动设置时间为编译器时间 void Auto_Time_Set(void) { u8 temp[3]; u8 i; u8 mon,date; u16 year; u8 sec,min,hour; for(i=0;i<3;i++)temp[i]=COMPILED_DATE[i]; for(i=0;i<12;i++)if(str_cmpx((u8*)Month_Tab[i],temp,3))break; mon=i+1;//得到月份 if(COMPILED_DATE[4]==' ')date=COMPILED_DATE[5]-'0'; else date=10*(COMPILED_DATE[4]-'0')+COMPILED_DATE[5]-'0'; year=1000*(COMPILED_DATE[7]-'0')+100*(COMPILED_DATE[8]-'0')+10*(COMPILED_DATE[9]-'0')+COMPILED_DATE[10]-'0'; hour=10*(COMPILED_TIME[0]-'0')+COMPILED_TIME[1]-'0'; min=10*(COMPILED_TIME[3]-'0')+COMPILED_TIME[4]-'0'; sec=10*(COMPILED_TIME[6]-'0')+COMPILED_TIME[7]-'0'; RTC_Set(year,mon,date,hour,min,sec) ; //printf(\ %d:%d:%d\\n\} Hardware文件夹下 exit。C #include \#include \#include \#include \#include \#include \#include \ ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //Mini STM32开发板 //外部中断 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2010/12/01 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 正点原子 2009-2019 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //外部中断0服务程序 void EXTI0_IRQHandler(void) { delay_ms(100);//消抖 if(KEY2==1) //按键2 { count++; if(count<7) { while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH&=~(0X01); //允许秒中断 while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 } switch(count) { case 1 : LCD_ShowString(2,4,\设置秒\ case 2 : LCD_ShowString(2,4,\设置分\ case 3 : LCD_ShowString(2,4,\设置时\ case 4 : LCD_ShowString(2,4,\设置日\ case 5 : LCD_ShowString(2,4,\设置月\ case 6 : LCD_ShowString(2,4,\设置年\ case 7 { RTC_Set(timer.w_year,timer.w_month,timer.w_date,timer.hour,timer.min,timer.sec); : while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH|=0X01; //允许秒中断 while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 LCD_ShowString(2,4,\设置IP \ case 8 : LCD_ShowString(3,0,\ case 9 : LCD_ShowString(3,0,\ case 10 : LCD_ShowString(3,0,\ case 11 : count=0;LCD_ShowString(3,0,\ \ \ } } EXTI->PR=1<<0; //清除LINE0上的中断标志位 } //外部中断15~10服务程序 void EXTI15_10_IRQHandler(void) { delay_ms(100); //消抖 if(KEY0==0) //按键0 { LED1=!LED1; switch(count) { case 1 : timer.sec--;if(timer.sec==0)timer.sec=59;LCD_Shownum(1,4,timer.sec);LCD_ShowString(2,7,\;break; case 2 : timer.min--;if(timer.min==0)timer.min=59;LCD_Shownum(1,2,timer.min);LCD_ShowString(2,7,\ case 3 : timer.hour--;if(timer.hour==0)timer.hour=12;LCD_Shownum(1,0,timer.hour);LCD_ShowString(2,7,\ case 4 : timer.w_date--;if(timer.w_date==0)timer.w_date=31;LCD_Shownum(0,4,timer.w_date);LCD_ShowString(2,7,\ case 5 : timer.w_month--;if(timer.w_month==0)timer.w_month=12;LCD_Shownum(0,2,timer.w_month);LCD_ShowString(2,7,\ case 6 : timer.w_year--;if(timer.w_year==0)timer.w_year=2099;LCD_Shownum(0,0,(timer.w_year0));LCD_ShowString(2,7,\ case 7 : Addres_1--;if(Addres_1==0) Addres_1=99;disp_IP();break; case 8 : Addres_2--;if(Addres_2==0) Addres_2=9;disp_IP();break; case 9 : Addres_3--;if(Addres_3==0)Addres_3=200;disp_IP();break; case 10 : Addres_4--;if(Addres_4==0)Addres_4=200;disp_IP();break; } }else if(KEY1==0)//按键1 {LED0=!LED0; switch(count) { case 1 : timer.sec++;if(timer.sec==60)timer.sec=0;LCD_Shownum(1,4,timer.sec);LCD_ShowString(2,7,\\ case 2 : timer.min++;if(timer.min==60)timer.min=0;LCD_Shownum(1,2,timer.min);LCD_ShowString(2,7,\break; case 3 : timer.hour++;if(timer.hour==12)timer.hour=0;LCD_Shownum(1,0,timer.hour);LCD_ShowString(2,7,\ case 4 : timer.w_date++;if(timer.w_date==32)timer.w_date=0;LCD_Shownum(0,4,timer.w_date);LCD_ShowString(2,7,\ case 5 : timer.w_month++;if(timer.w_month==32)timer.w_month=0;LCD_Shownum(0,2,timer.w_month);LCD_ShowString(2,7,\ case 6 : timer.w_year++;if(timer.w_year==2099)timer.w_year=2014;LCD_Shownum(0,0,(timer.w_year0));LCD_ShowString(2,7,\ case 7 : Addres_1++;if(Addres_1==100)Addres_1=0;disp_IP();break; case 8 : Addres_2++;if(Addres_2==10)Addres_2=0;disp_IP();break; case 9 : Addres_3++;if(Addres_3==1000)Addres_3=0;disp_IP();break; case 10: Addres_4++;if(Addres_4==1000)Addres_4=0;disp_IP();break; } } EXTI->PR=1<<13; //清除LINE13上的中断标志位 EXTI->PR=1<<15; //清除LINE15上的中断标志位 } //外部中断初始化程序 //初始化PA0,PA13,PA15为中断输入. void EXTIX_Init(void) { RCC->APB2ENR|=1<<2; //使能PORTA时钟 JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入 GPIOA->CRL|=0X00000008; GPIOA->CRH&=0X0F0FFFFF;//PA13,15设置成输入 GPIOA->CRH|=0X80800000; GPIOA->ODR|=1<<13; //PA13上拉,PA0默认下拉 GPIOA->ODR|=1<<15; //PA15上拉 Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发 Ex_NVIC_Config(GPIO_A,13,FTIR);//下降沿触发 Ex_NVIC_Config(GPIO_A,15,FTIR);//下降沿触发 MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2 MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2 } void disp_IP(void) { LCD12864_Pos(3,2); LCD12684_Wdat(Addres_4/100+0x30); LCD12684_Wdat((Addres_40)/10+0x30); LCD12684_Wdat((Addres_40)+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,4); LCD12684_Wdat(Addres_3/100+0x30); LCD12684_Wdat((Addres_30)/10+0x30); LCD12684_Wdat((Addres_30)+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,6); LCD12684_Wdat(Addres_2+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,7); LCD12684_Wdat(Addres_1/10+0x30); LCD12684_Wdat(Addres_1+0x30); } 其他文件用原子rtc时钟的程序就行