基于STM32F103可调时钟万年历的实现

基于STM32F103可调时钟万年历的实现

  • 前言
  • 二、话不多说代码垒起
    • 1.主函数
    • 2.时钟调时程序代码
    • 3.闹钟设置程序代码
  • 总结

前言


一、如何用STM32F103内部RTC实现可调时钟万年历?

通常我们都是利用单片机驱动外设来实现可调时钟万年历的,但是如果手里没有相应的外设又想做一个可调时钟万年历怎么办,先不要着急,找一个STM32单片机我们利用其内部RTC就可以实现,是不是方便了好多呀。

二、话不多说代码垒起

1.主函数

 int main(void)
 {	 
 	u8 t=0;	
	u8 keynum;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	LCD_Init();	
	BEEP_Init();		 	//初始化蜂鸣器IO
	EXTIX_Init(); 
//	usmart_dev.init(SystemCoreClock/1000000);	//初始化USMART	
//	alarmclock.hour =17;
//	alarmclock.min =43 ;
//	alarmclock.sec =00;
	RTC_Init();	  			//RTC初始化
	POINT_COLOR=RED;//设置字体为红色 
	//LCD_ShowString(60,50,200,16,16,"Elite STM32");	
	//LCD_ShowString(60,70,200,16,16,"RTC TEST");	
	//LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
	//LCD_ShowString(60,110,200,16,16,"2021/2/14");		
	//显示时间
	
	POINT_COLOR=BLUE;//设置字体为蓝色
	LCD_ShowString(60,130,200,16,16,"    -  -  ");	   
	LCD_ShowString(60,162,200,16,16,"  :  :  ");
  
	while(1)
	{		
		POINT_COLOR=BLUE;
		if(t!=calendar.sec)
		{
			t=calendar.sec;
			LCD_ShowNum(60,130,calendar.w_year,4,16);									  
			LCD_ShowNum(100,130,calendar.w_month,2,16);									  
			LCD_ShowNum(124,130,calendar.w_date,2,16);	 
			switch(calendar.week)
			{
				case 0:
					LCD_ShowString(60,148,200,16,16,"Sunday   ");
					break;
				case 1:
					LCD_ShowString(60,148,200,16,16,"Monday   ");
					break;
				case 2:
					LCD_ShowString(60,148,200,16,16,"Tuesday  ");
					break;
				case 3:
					LCD_ShowString(60,148,200,16,16,"Wednesday");
					break;
				case 4:
					LCD_ShowString(60,148,200,16,16,"Thursday ");
					break;
				case 5:
					LCD_ShowString(60,148,200,16,16,"Friday   ");
					break;
				case 6:
					LCD_ShowString(60,148,200,16,16,"Saturday ");
					break;  
			}
			LCD_ShowNum(60,162,calendar.hour,2,16);									  
			LCD_ShowNum(84,162,calendar.min,2,16);									  
			LCD_ShowNum(108,162,calendar.sec,2,16);
			LED0=!LED0;
			
		keynum = KEY_Scan(0);
		if(keynum==1)//设置
		{
			BEEP=0;
			main_Set();//时钟万年历调时函数
		}
		else if(keynum==3)//设置
		{
			BEEP=0;
			alarm_Set();//调闹钟
		}
		else if(keynum==2) //关声音
		{
			BEEP=0;
		}
		}	
		
		delay_ms(10);								  
	};  
 }

2.时钟调时程序代码

void main_Set()//时钟万年历调时函数
{
	u8 keynum ,state=1;
	LCD_ShowString(16,112,200,16,16,"Calendar Set:");//显示字符Calendar Set:可进行相应的时钟设置
	LCD_ShowNum(108,162,calendar.sec,2,16);//定格到当前所在秒
	while(1)
	{
		keynum = KEY_Scan(0);
		if(keynum==1)
		{
			if(state>=6)
				state=0;
			else
				state++;
			switch(state)
			{
				case 0:
				case 1:	POINT_COLOR=RED;
								LCD_ShowNum(108,162,calendar.sec,2,16);
								break;//秒
				case 2:	POINT_COLOR=RED;
								LCD_ShowNum(84,162,calendar.min,2,16);	
								break;//分
				case 3:	POINT_COLOR=RED;
								LCD_ShowNum(60,162,calendar.hour,2,16);	
								break;//时
				case 4:	POINT_COLOR=RED;
								LCD_ShowNum(124,130,calendar.w_date,2,16);	
								break;//日
				case 5:	POINT_COLOR=RED;
								LCD_ShowNum(100,130,calendar.w_month,2,16);
								break;//月
				case 6:	POINT_COLOR=RED;
								LCD_ShowNum(60,130,calendar.w_year,4,16);	
								break;//年
				default:break;
			}	
			
		}
		else if(keynum>1)
		{
			if(keynum==4)
			{
			}
			if(state==1)//设置秒,我这里秒不作为可设置开放所以注释掉了
			{
//				if(keynum==3)
//					calendar.sec++;
//				else if(keynum==2)
//					calendar.sec--;
//				if(calendar.sec>=60)
//					calendar.sec=0;
//				else if(calendar.sec<0)
//					calendar.sec=59;
//				POINT_COLOR=BLUE;
//				LCD_ShowNum(108,216,calendar.sec,2,16);
			}
			else if(state==2)//设置分
			{
				if(keynum==3)
					calendar.min++;
				else if(keynum==2)
					calendar.min--;
				if(calendar.min>=60)
					calendar.min=0;
				else if(calendar.min<=0)
					calendar.min=59;
				POINT_COLOR=BLUE;
				LCD_ShowNum(84,162,calendar.min,2,16);
				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
				RTC_ExitConfigMode(); //退出配置模式  				
			}
			else if(state==3)//设置时
			{
				if(keynum==3)
					calendar.hour++;
				else if(keynum==2)
					calendar.hour--;
				if(calendar.hour>=24)
					calendar.hour=0;
				else if(calendar.hour<=0)
					calendar.hour=23;
				POINT_COLOR=BLUE;
				LCD_ShowNum(60,162,calendar.hour,2,16);	
				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
				RTC_ExitConfigMode(); //退出配置模式  
			}
//			else if(state==4)//设置周,我这里周不作为可设置开放所以注释掉了
//			{
//				if(keynum==3)
//					calendar.week++;
//				else if(keynum==2)
//					calendar.week--;
//				if(calendar.week>=7)
//					calendar.week=1;
//				else if(calendar.week<=1)
//					calendar.week=7;
//				POINT_COLOR=BLUE;
//				LCD_ShowNum(84,216,calendar.week,2,16);
//				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
//				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
//				RTC_ExitConfigMode(); //退出配置模式  				
//			}
			else if(state==4)//设置日
			{
				if(keynum==3)
					calendar.w_date++;
				else if(keynum==2)
					calendar.w_date--;
				if(calendar.w_date>=32)
					calendar.w_date=1;
				else if(calendar.w_date<=1)
					calendar.w_date=31;
				POINT_COLOR=BLUE;
				LCD_ShowNum(124,130,calendar.w_date,2,16);
				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
				RTC_ExitConfigMode(); //退出配置模式 
			}
			else if(state==5)//设置月
			{
				if(keynum==3)
					calendar.w_month++;
				else if(keynum==2)
					calendar.w_month--;
				if(calendar.w_month>12)
					calendar.w_month=1;
				else if(calendar.w_month<1)
					calendar.w_month=12;
				POINT_COLOR=BLUE;
				LCD_ShowNum(100,130,calendar.w_month,2,16);	
				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
				RTC_ExitConfigMode(); //退出配置模式 
			}
			else if(state==6)//设置年,这里年只开放2000-2025年的设置
			{
				if(keynum==3)
					calendar.w_year++;
				else if(keynum==2)
					calendar.w_year--;
				if(calendar.w_year>2025)
					calendar.w_year=2000;
				else if(calendar.w_year<=2000)
					calendar.w_year=2025;
				POINT_COLOR=BLUE;
				LCD_ShowNum(60,130,calendar.w_year,4,16);	
				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
				RTC_ExitConfigMode(); //退出配置模式 				
			}
			else
			{
				break;//退出循环
			}
		}
		if(state==0)
		{
			LCD_Clear(WHITE);//清屏
			POINT_COLOR=BLUE;//字体变蓝
			LCD_ShowString(60,130,200,16,16,"    -  -  ");	   
			LCD_ShowString(60,162,200,16,16,"  :  :  ");
			break;	
		}
	}
}

3.闹钟设置程序代码

void alarm_Set()//调闹铃函数
{
	int Keynum,State=1;
	LCD_ShowString(16,180,200,16,16,"AlarmClock:");
	LCD_ShowString(60,198,200,16,16,"    -  -  ");	 
	LCD_ShowString(60,216,200,16,16,"  :  :  ");	
	LCD_ShowNum(60,216,alarmclock.hour,2,16);	
	LCD_ShowNum(84,216,alarmclock.min,2,16);	
	LCD_ShowNum(108,216,alarmclock.sec,2,16);
	
	LCD_ShowNum(60,198,alarmclock.w_year ,4,16);	
	LCD_ShowNum(100,198,alarmclock.w_month,2,16);
	LCD_ShowNum(124,198,alarmclock.w_date,2,16);	
	POINT_COLOR=RED;
	LCD_ShowNum(108,216,alarmclock.sec,2,16);
	while(1)
	{
		Keynum = KEY_Scan(0);
		if(Keynum==1)//设置
		{
			if(State>=6)
				State=0;
			else
				State++;
			switch(State)
			{
				case 0:
				case 1:	POINT_COLOR=RED;LCD_ShowNum(108,216,alarmclock.sec,2,16);break;//秒
				case 2:	POINT_COLOR=RED;LCD_ShowNum(84,216,alarmclock.min,2,16);	break;//分
				case 3:	POINT_COLOR=RED;LCD_ShowNum(60,216,alarmclock.hour,2,16);	break;//时
				//case 4:
				case 4:	POINT_COLOR=RED;LCD_ShowNum(124,198,alarmclock.w_date,2,16);	break;//日
				case 5:	POINT_COLOR=RED;LCD_ShowNum(100,198,alarmclock.w_month,2,16);break;//月
				case 6:	POINT_COLOR=RED;LCD_ShowNum(60,198,alarmclock.w_year,4,16);	break;//年
				default:break;
			}	
			
		}
		else if(Keynum>1)
		{
			if(Keynum==4)
			{
			}
			if(State==1)//设置秒
			{
				if(Keynum==3)
					alarmclock.sec++;
				else if(Keynum==2)
					alarmclock.sec--;
				if(alarmclock.sec>=60)
					alarmclock.sec=0;
				else if(alarmclock.sec<0)
					alarmclock.sec=59;
				POINT_COLOR=BLUE;
				LCD_ShowNum(108,216,alarmclock.sec,2,16);
				RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
			}
			else if(State==2)//设置分
			{
				if(Keynum==3)
					alarmclock.min++;
				else if(Keynum==2)
					alarmclock.min--;
				if(alarmclock.min>=60)
					alarmclock.min=0;
				else if(alarmclock.min<=0)
					alarmclock.min=59;
				POINT_COLOR=BLUE;
				LCD_ShowNum(84,216,alarmclock.min,2,16);
				RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec ); //设置时间	
								
			}
			else if(State==3)//设置时
			{
				if(Keynum==3)
					alarmclock.hour++;
				else if(Keynum==2)
					alarmclock.hour--;
				if(alarmclock.hour>=24)
					alarmclock.hour=0;
				else if(alarmclock.hour<=0)
					alarmclock.hour=23;
				POINT_COLOR=BLUE;
				LCD_ShowNum(60,216,alarmclock.hour,2,16);	
				RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
			}
//			else if(state==4)//设置周
//			{
//				if(keynum==3)
//					calendar.week++;
//				else if(keynum==2)
//					calendar.week--;
//				if(calendar.week>=8)
//					calendar.week=1;
//				else if(calendar.week<=1)
//					calendar.hour=7;
//				POINT_COLOR=BLUE;
//				LCD_ShowNum(84,216,calendar.week,2,16);
//				RTC_WaitForLastTask();	//等待最近一次对RTC寄存器的写操作完成
//				RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec );  //设置时间	
//				RTC_ExitConfigMode(); //退出配置模式  				
//			}
			else if(State==4)//设置日
			{
				if(Keynum==3)
					alarmclock.w_date++;
				else if(Keynum==2)
					alarmclock.w_date--;
				if(alarmclock.w_date>=32)
					alarmclock.w_date=1;
				else if(alarmclock.w_date<=1)
					alarmclock.w_date=31;
				POINT_COLOR=BLUE;
				LCD_ShowNum(124,198,alarmclock.w_date,2,16);
				RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
			}
			else if(State==5)//设置月
			{
				if(Keynum==3)
					alarmclock.w_month++;
				else if(Keynum==2)
					alarmclock.w_month--;
				if(calendar.w_month>=13)
					alarmclock.w_month=1;
				else if(calendar.w_month<1)
					alarmclock.w_month=12;
				POINT_COLOR=BLUE;
				LCD_ShowNum(100,198,alarmclock.w_month,2,16);	
				RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
			}
			else if(State==6)//设置年
			{
				if(Keynum==3)
					alarmclock.w_year++;
				else if(Keynum==2)
					alarmclock.w_year--;
				if(alarmclock.w_year>2025)
					alarmclock.w_year=2000;
				else if(alarmclock.w_year<=2000)
					alarmclock.w_year=2025;
				POINT_COLOR=BLUE;
				LCD_ShowNum(60,198,alarmclock.w_year,4,16);	
				RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );			
			}
			else
			{
				break;//退出循环
			}
		}
		if(State==0)
		{
			LCD_Clear(WHITE);//清屏
			POINT_COLOR=BLUE;//字体变蓝
			LCD_ShowString(60,130,200,16,16,"    -  -  ");	   
			LCD_ShowString(60,162,200,16,16,"  :  :  ");
			break;	
		}
	}
}

总结

以上就是今天分享的内容,本文仅仅简单介绍了STM32如何实现可调万年历的方法及主要程序的思想,由于时间的原因,日后再行完善哈哈哈。

你可能感兴趣的:(stm32)