目录

一、前言

二、项目简介

1.功能详解

2.主要器件

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

六、实验效果 

项目分享


一、前言

项目成品图片:

哔哩哔哩视频链接:

https://www.bilibili.com/video/BV1QD421g7kn/?share_source=copy_web&vd_source=097fdeaf6b6ecfed8a9ff7119c32faf2

(资料分享见文末) 

二、项目简介

1.功能详解

基于STM32的万年历,功能如下:

  1. 实时时钟显示
  2. 时间设置,断电保存
  3. 闹钟设置,蜂鸣器报警
  4. 温湿度采集与显示,异常报警

2.主要器件

  • STM32F103C8T6最小系统板
  • DHT11温湿度传感器
  • OLED显示屏(7针SPI协议)
  • DS1302时钟模块
  • 蜂鸣器
  • LED灯
  • 三、原理图设计

    四、PCB硬件设计

    PCB图 

    五、程序设计 

    int main(void)
    	{		
    		delay_init();                 //延时函数 系统初始化
    		
    		LED_GPIO_Config();            //初始化GPIO接口
    		
    		KEY_Init();                   //按键初始化
    		
    		BEEP_Init();                  //蜂鸣器初始化
    	
        GENERAL4_TIM_Init();          //10ms 通用定时器3初始化   10ms
    	
    	  NVIC_Configuration();	        //中断优先级设置		
    		
    		ds1302_gpio_init();delay_ms(5); //初始化ds1302端口
    	
    		ds1032_read_realTime();    //读取此时时刻
    			
    		OLED_Init();		            	//初始化OLED  
    		OLED_Clear();                 //清屏
    	  delay_ms(100);		
    		
    		DHT11_Init();                 //传感器初始化
    			
    	 OLED_DrawBMP(0,0,128,8,BMP19);  //欢迎使用开机页面
    	
    	 delay_ms(1000);		
    		
    	 OLED_Clear();                 //清屏
    		
    	 RealTime_Display_Init();        //上电初始化显示实时时间
    
    	while(1)			
    		{  
    		
        delay_ms(200);                 //添加延时,保证检测的稳定性
    					
    	  ds1032_read_realTime();        //读取此时时刻
    		
    		RealTime_Display();            //实时时间日期实时刷新显示
    			
    			
    		if(DHT11_Data_Read_flag)       //6秒读取一次温湿度数据
    	 {
    	   DHT11_Read_Data(&temperature, &humidity);	//读取温湿度值	 
    		 DHT11_Data_Read_flag=0;              //复位读取DHT11数据标志
    	 }
    
    //************************闹钟报警程序段***********************************************//		
    			if(Alarm_Clock&&!Alarm_Manual_Stop_flag) 
    			{
    			   if((TimeData.hour==Alarm_Hour)&&(TimeData.minute==Alarm_Minute))
    				 {
    				     Alarm_Clock_flag=1;			 //闹钟报警标志位
    				 }
    				 
    						 else
    					{
    						 Alarm_Clock_flag=0;			 //闹钟报警标志位
    					}
    			
    			}
    			else
    			{
    			       Alarm_Clock_flag=0;			 //闹钟报警标志位
    			}
    		
    				if(!KEY_DEC)  	      //闹钟报警过程中停止按键  减少键  
    						
    				{
    							delay_ms(10);
    					
    						if(KEY_DEC==0)
    							{
    								while(!KEY_DEC);	
    								
    								Alarm_Manual_Stop_flag=1;
    															  
    						  }
    				}				
           				
    			 if(TimeData.minute!=Alarm_Minute)   //一旦设定值与当前时间不一致则手动终端报警复位
    			 {
    			      Alarm_Manual_Stop_flag=0;
    			 }
    //**************************按键修改时间和日期程序段***************************************//
    	if(!KEY_ADJ)  	  
    	 {
    		  delay_ms(10);
    		 
    		  if(KEY_ADJ==0)
    		  {
    		    while(!KEY_ADJ);
    
    			OLED_Clear();               //清屏
    				
    		  OLED_ShowChinese(0,0,21);   //年			
    		  OLED_ShowChinese(68,0,22);  //月				
    		  OLED_ShowChinese(0,3,23);   //日
    		  OLED_ShowChinese(68,3,24);  //时
    		  OLED_ShowChinese(0,6,25);   //分
    		  OLED_ShowChinese(68,6,26);  //周
    	
    			Show_Modify_Data(num);              //显示默认的时间日期设定参数
    				
    				
    				
    					while(1)
    					{
    						OLED_ShowNum(20,0,y,2,16);
    						OLED_ShowNum(88,0,m,2,16);
    						OLED_ShowNum(20,3,d,2,16);
    						OLED_ShowNum(88,3,h,2,16);
    						OLED_ShowNum(20,6,mi,2,16);
    						OLED_ShowNum(88,6,w,2,16);
    				
    						if(!KEY_ALM)  	  
    							{
    								delay_ms(10);
    									if(KEY_ALM==0)
    									{
    											while(!KEY_ALM);		 
    													num++;                    
    													if(num>5)
    														num= 0;
    													 Show_Modify_Data(num);
    									}
    								
    							}
    							
    							if(!KEY_ADD )  	  
    							{
    								delay_ms(10);
    									if(KEY_ADD ==0)
    									{
    											while(!KEY_ADD );		
    					  			 
    											switch(num)
    											{
    												case 0 : y++; break;
    												case 1 : m++; break;
    												case 2 : d++; break;
    												case 3 : h++; break;
    												case 4 : mi++; break;
    												case 5 : w++; break;
    											}
    											if(y>59)
    											y = 59;
    											if(m>12)
    												m=12;
    											if(d>31)
    												d=31;
    											if(h>23)
    												h=23;
    											if(mi>59)
    												mi=59;
    											if(w>7)
    												w=7;
    										}
    			          }
    							
    					if(!KEY_DEC)  	  
    							{
    								delay_ms(10);
    									if(KEY_DEC==0)
    									{
    											while(!KEY_DEC);		
    											switch(num)
    											{
    												case 0 : y--; break;
    												case 1 : m--; break;
    												case 2 : d--; break;
    												case 3 : h--; break;
    												case 4 : mi--; break;
    												case 5 : w--; break;
    											}
    												if(y<=1)
    													y=1;
    												if(m<1)
    													m=1;
    												if(d<1)
    													d=1;
    												if(h<1)
    													h=1;
    												if(mi<1)
    													mi=1;
    												if(w<1)
    													w=1;
    			             }
    			         }
    								
    							 
    							if(!KEY_ADJ)  	  
    	             {
    										delay_ms(10);
    										if(KEY_ADJ==0)
    										{
    										while(!KEY_ADJ); 
    										
    			 switch(y)//设置年
    		  {
    			  case 0  : time_buf[1]=0x00;break;
    			  case 1  : time_buf[1]=0x01;break;
    			  case 2  : time_buf[1]=0x02;break;
    			  case 3  : time_buf[1]=0x03;break;
    			  case 4  : time_buf[1]=0x04;break;
    			  case 5  : time_buf[1]=0x05;break;
    			  case 6  : time_buf[1]=0x06;break;
    			  case 7  : time_buf[1]=0x07;break;
    			  case 8  : time_buf[1]=0x08;break;
    			  case 9  : time_buf[1]=0x09;break;
    			  case 10 : time_buf[1]=0x10;break;
    			  case 11 : time_buf[1]=0x11;break;
    			  case 12 : time_buf[1]=0x12;break;
    			  case 13 : time_buf[1]=0x13;break;
    			  case 14 : time_buf[1]=0x14;break;
    			  case 15 : time_buf[1]=0x15;break;
    			  case 16 : time_buf[1]=0x16;break;
    			  case 17 : time_buf[1]=0x17;break;
    			  case 18 : time_buf[1]=0x18;break;
    			  case 19 : time_buf[1]=0x19;break;
    			  case 20 : time_buf[1]=0x20;break;
    			  case 21 : time_buf[1]=0x21;break;
    			  case 22 : time_buf[1]=0x22;break;
    			  case 23 : time_buf[1]=0x23;break;
    			  case 24 : time_buf[1]=0x24;break;
    			  case 25 : time_buf[1]=0x25;break;
    			  case 26 : time_buf[1]=0x26;break;
    			  case 27 : time_buf[1]=0x27;break;
    			  case 28 : time_buf[1]=0x28;break;
    			  case 29 : time_buf[1]=0x29;break;
    			  case 30 : time_buf[1]=0x30;break;
    			  case 31 : time_buf[1]=0x31;break;
    			  
    			  case 32 : time_buf[1]=0x32;break;
    			  case 33 : time_buf[1]=0x33;break;
    			  case 34 : time_buf[1]=0x34;break;
    			  case 35 : time_buf[1]=0x35;break;
    			  case 36 : time_buf[1]=0x36;break;
    			  case 37 : time_buf[1]=0x37;break;
    			  case 38 : time_buf[1]=0x38;break;
    			  case 39 : time_buf[1]=0x39;break;
    			  case 40 : time_buf[1]=0x40;break;
    			  case 41 : time_buf[1]=0x41;break;
    			  case 42 : time_buf[1]=0x42;break;
    			  case 43 : time_buf[1]=0x43;break;
    			  case 44 : time_buf[1]=0x44;break;
    			  case 45 : time_buf[1]=0x45;break;
    			  case 46 : time_buf[1]=0x46;break;
    			  case 47 : time_buf[1]=0x47;break;
    			  case 48 : time_buf[1]=0x48;break;
    			  case 49 : time_buf[1]=0x49;break;
    			  case 50 : time_buf[1]=0x50;break;
    			  case 51 : time_buf[1]=0x51;break;
    			  case 52 : time_buf[1]=0x52;break;
    			  case 53 : time_buf[1]=0x53;break;
    			  case 54 : time_buf[1]=0x54;break;
    			  case 55 : time_buf[1]=0x55;break;
    			  case 56 : time_buf[1]=0x56;break;
    			  case 57 : time_buf[1]=0x57;break;
    			  case 58 : time_buf[1]=0x58;break;
    			  case 59 : time_buf[1]=0x59;break;
    
    			  
    			  default : time_buf[5]=0x01;
    		  }
    			
    			  switch(m)//设置月
    		  {
    
    			  case 1 : time_buf[2]=0x01;break;
    			  case 2 : time_buf[2]=0x02;break;
    			  case 3 : time_buf[2]=0x03;break;
    			  case 4 : time_buf[2]=0x04;break;
    			  case 5 : time_buf[2]=0x05;break;
    			  case 6 : time_buf[2]=0x06;break;
    			  case 7 : time_buf[2]=0x07;break;
    			  case 8 : time_buf[2]=0x08;break;
    			  case 9 : time_buf[2]=0x09;break;
    			  case 10 : time_buf[2]=0x10;break;
    			  case 11 : time_buf[2]=0x11;break;
    			  case 12 : time_buf[2]=0x12;break;
    			  default : time_buf[2]=0x01;
    		  }
    		  		  switch(d)//设置日
    		  {
    
    			  case 1  : time_buf[3]=0x01;break;
    			  case 2  : time_buf[3]=0x02;break;
    			  case 3  : time_buf[3]=0x03;break;
    			  case 4  : time_buf[3]=0x04;break;
    			  case 5  : time_buf[3]=0x05;break;
    			  case 6  : time_buf[3]=0x06;break;
    			  case 7  : time_buf[3]=0x07;break;
    			  case 8  : time_buf[3]=0x08;break;
    			  case 9  : time_buf[3]=0x09;break;
    			  case 10 : time_buf[3]=0x10;break;
    			  case 11 : time_buf[3]=0x11;break;
    			  case 12 : time_buf[3]=0x12;break;
    			  case 13 : time_buf[3]=0x13;break;
    			  case 14 : time_buf[3]=0x14;break;
    			  case 15 : time_buf[3]=0x15;break;
    			  case 16 : time_buf[3]=0x16;break;
    			  case 17 : time_buf[3]=0x17;break;
    			  case 18 : time_buf[3]=0x18;break;
    			  case 19 : time_buf[3]=0x19;break;
    			  case 20 : time_buf[3]=0x20;break;
    			  case 21 : time_buf[3]=0x21;break;
    			  case 22 : time_buf[3]=0x22;break;
    			  case 23 : time_buf[3]=0x23;break;
    			  case 24 : time_buf[3]=0x24;break;
    			  case 25 : time_buf[3]=0x25;break;
    			  case 26 : time_buf[3]=0x26;break;
    			  case 27 : time_buf[3]=0x27;break;
    			  case 28 : time_buf[3]=0x28;break;
    			  case 29 : time_buf[3]=0x29;break;
    			  case 30 : time_buf[3]=0x30;break;
    			  case 31 : time_buf[3]=0x31;break;
    			  default : time_buf[3]=0x01;
    		  }
    		  
    		  		  		  switch(h)//设置时
    		  {
    			  case 0  : time_buf[4]=0x00;break;
    			  case 1  : time_buf[4]=0x01;break;
    			  case 2  : time_buf[4]=0x02;break;
    			  case 3  : time_buf[4]=0x03;break;
    			  case 4  : time_buf[4]=0x04;break;
    			  case 5  : time_buf[4]=0x05;break;
    			  case 6  : time_buf[4]=0x06;break;
    			  case 7  : time_buf[4]=0x07;break;
    			  case 8  : time_buf[4]=0x08;break;
    			  case 9  : time_buf[4]=0x09;break;
    			  case 10 : time_buf[4]=0x10;break;
    			  case 11 : time_buf[4]=0x11;break;
    			  case 12 : time_buf[4]=0x12;break;
    			  case 13 : time_buf[4]=0x13;break;
    			  case 14 : time_buf[4]=0x14;break;
    			  case 15 : time_buf[4]=0x15;break;
    			  case 16 : time_buf[4]=0x16;break;
    			  case 17 : time_buf[4]=0x17;break;
    			  case 18 : time_buf[4]=0x18;break;
    			  case 19 : time_buf[4]=0x19;break;
    			  case 20 : time_buf[4]=0x20;break;
    			  case 21 : time_buf[4]=0x21;break;
    			  case 22 : time_buf[4]=0x22;break;
    			  case 23 : time_buf[4]=0x23;break;
    
    			  default : time_buf[4]=0x01;
    		  }
    		  
    		  
    		   switch(mi)//设置分
    		  {
    			  case 0  : time_buf[5]=0x00;break;
    			  case 1  : time_buf[5]=0x01;break;
    			  case 2  : time_buf[5]=0x02;break;
    			  case 3  : time_buf[5]=0x03;break;
    			  case 4  : time_buf[5]=0x04;break;
    			  case 5  : time_buf[5]=0x05;break;
    			  case 6  : time_buf[5]=0x06;break;
    			  case 7  : time_buf[5]=0x07;break;
    			  case 8  : time_buf[5]=0x08;break;
    			  case 9  : time_buf[5]=0x09;break;
    			  case 10 : time_buf[5]=0x10;break;
    			  case 11 : time_buf[5]=0x11;break;
    			  case 12 : time_buf[5]=0x12;break;
    			  case 13 : time_buf[5]=0x13;break;
    			  case 14 : time_buf[5]=0x14;break;
    			  case 15 : time_buf[5]=0x15;break;
    			  case 16 : time_buf[5]=0x16;break;
    			  case 17 : time_buf[5]=0x17;break;
    			  case 18 : time_buf[5]=0x18;break;
    			  case 19 : time_buf[5]=0x19;break;
    			  case 20 : time_buf[5]=0x20;break;
    			  case 21 : time_buf[5]=0x21;break;
    			  case 22 : time_buf[5]=0x22;break;
    			  case 23 : time_buf[5]=0x23;break;
    			  case 24 : time_buf[5]=0x24;break;
    			  case 25 : time_buf[5]=0x25;break;
    			  case 26 : time_buf[5]=0x26;break;
    			  case 27 : time_buf[5]=0x27;break;
    			  case 28 : time_buf[5]=0x28;break;
    			  case 29 : time_buf[5]=0x29;break;
    			  case 30 : time_buf[5]=0x30;break;
    			  case 31 : time_buf[5]=0x31;break;
    			  
    			  case 32 : time_buf[5]=0x32;break;
    			  case 33 : time_buf[5]=0x33;break;
    			  case 34 : time_buf[5]=0x34;break;
    			  case 35 : time_buf[5]=0x35;break;
    			  case 36 : time_buf[5]=0x36;break;
    			  case 37 : time_buf[5]=0x37;break;
    			  case 38 : time_buf[5]=0x38;break;
    			  case 39 : time_buf[5]=0x39;break;
    			  case 40 : time_buf[5]=0x40;break;
    			  case 41 : time_buf[5]=0x41;break;
    			  case 42 : time_buf[5]=0x42;break;
    			  case 43 : time_buf[5]=0x43;break;
    			  case 44 : time_buf[5]=0x44;break;
    			  case 45 : time_buf[5]=0x45;break;
    			  case 46 : time_buf[5]=0x46;break;
    			  case 47 : time_buf[5]=0x47;break;
    			  case 48 : time_buf[5]=0x48;break;
    			  case 49 : time_buf[5]=0x49;break;
    			  case 50 : time_buf[5]=0x50;break;
    			  case 51 : time_buf[5]=0x51;break;
    			  case 52 : time_buf[5]=0x52;break;
    			  case 53 : time_buf[5]=0x53;break;
    			  case 54 : time_buf[5]=0x54;break;
    			  case 55 : time_buf[5]=0x55;break;
    			  case 56 : time_buf[5]=0x56;break;
    			  case 57 : time_buf[5]=0x57;break;
    			  case 58 : time_buf[5]=0x58;break;
    			  case 59 : time_buf[5]=0x59;break;
    
    			  
    			  default : time_buf[5]=0x01;
    		  }
    		  
    		  
    		  		  switch(w)//设置星期
    		  {
    			  case 1 : time_buf[6]=0x01;break;
    			  case 2 : time_buf[6]=0x02;break;
    			  case 3 : time_buf[6]=0x03;break;
    			  case 4 : time_buf[6]=0x04;break;
    			  case 5 : time_buf[6]=0x05;break;
    			  case 6 : time_buf[6]=0x06;break;
    			  case 7 : time_buf[6]=0x07;break;
    
    			  default : time_buf[6]=0x01;
    		  }
    										
    										 ds1302_write_time();           //修改时间,写入
    		                 
    			               OLED_Clear();                  //清屏
    			
    			               ds1032_read_realTime();        //读取此时时刻
    			
    			               Modify_RealTime_Display();           //修改后时间日期刷新一次显示
    
    		                 break;
    									
    										}
    										
    										
    										
    								}
    								
    								
    					 }
           }		
      }		
    	 
    //******************************修改闹钟时间和闹钟设定程序段*******************************//	
    	
    		if(!KEY_ALM)  	  
    	 {
    		  delay_ms(10);
    		  if(KEY_ALM==0)
    		  {
    		  while(!KEY_ALM);
    
    			OLED_Clear();               //清屏
    		
    			OLED_ShowChinese(32,0,27);  //闹钟设定
    		  OLED_ShowChinese(48,0,28);
    			OLED_ShowChinese(64,0,29);
    		  OLED_ShowChinese(80,0,30);
    				
    			OLED_ShowChar(60,3,':',16);
    				
    			Show_Modify_Alarm(num2);        //显示修改闹钟信息
    				
    				
    					while(1)
    					{
    						 
                 	OLED_ShowNum(44,3,Alarm_Hour,2,16);			
    						 
    	           	OLED_ShowNum(68,3,Alarm_Minute,2,16);	
    						
    						  if(Alarm_Clock)                            //闹钟开关显示
    							{
    						     OLED_ShowChinese(104,3,31);
    							}
    							else
    							{
    							   OLED_ShowChinese(104,3,32);
    							}
    						
    						if(Alarm_Minute<10)                                     //防止显示1位数,不整齐
    							{  
    									OLED_ShowChar(68,3,'0',16);                 //0位补偿
    							}
    						  	if(!KEY_ADJ)  	  
    							{
    								delay_ms(10);
    									if(KEY_ADJ==0)
    									{
    											while(!KEY_ADJ);		 
    													num2++;
    													if(num2>2)
    														num2= 0;
    													 Show_Modify_Alarm(num2);
    									}	
    									
    							}
    							
    							
    							if(!KEY_ADD)  	  
    							{
    								delay_ms(10);
    									if(KEY_ADD==0)
    									{
    											while(!KEY_ADD);		
    					  			 
    											switch(num2)
    											{
    												case 0 : Alarm_Hour++; break;
    												case 1 : Alarm_Minute++; break;
    												case 2 : Alarm_Clock++; break;
    											}
    											if(Alarm_Hour>23)
    											Alarm_Hour= 23;
    											if(Alarm_Minute>59)
    											Alarm_Minute=59;
    										  if(Alarm_Clock>=1)
    											Alarm_Clock=1;
    										
    										}
    			          }
    							
    					if(!KEY_DEC)  	  
    							{
    								delay_ms(10);
    									if(KEY_DEC==0)
    									{
    											while(!KEY_DEC);		
    											switch(num2)
    											{
    												case 0 : Alarm_Hour--; break;
    												case 1 : Alarm_Minute--; break;
    												case 2 : Alarm_Clock--; break;
    												
    											}
    												if(Alarm_Hour<=0)
    													Alarm_Hour=0;
    												if(Alarm_Minute<=0)
    													Alarm_Minute=0;
    												if(Alarm_Clock<=0)
    											    Alarm_Clock=0;
    						
    												
    			             }
    			         }
    								
    						
    							 
    							 if(!KEY_ALM)  	  
    									 {
    											delay_ms(10);
    											if(KEY_ALM==0)
    											{
    											while(!KEY_ALM);
    												
    											  OLED_Clear();
    			
    			                  ds1032_read_realTime();        //读取此时时刻
    			
    			                  Modify_RealTime_Display();    //修改后时间日期刷新一次显示
    
    		                    break;
    											}
                        }											
    							 
    							 
    						 
    					}
    					
    			
    			}
    		}
    	//****************************主程序运行指示灯程序段**************************************//
           
    
    	    if(Run_Indicate_num>=50)                           //闪烁则证明主程序在持续运行
    	    	{                                                                                                    
    			     RUN_Indicate_ENABLE; //指示灯亮		
            }
    		
    	  	else
    	    	{		
                RUN_Indicate_UNABLE;//指示灯灭	
            }
    
        }
    		
    		
    	}	
    		
    		
    
    

    六、实验效果 

    七、资料内容

    项目分享

    作者:辰哥单片机设计

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32项目分享:万年历

    发表回复