基于DS3231实时时钟模块的stm32简易闹钟

stm32简易闹钟

设计、制作一个简易的闹钟。要求如下:
(1)作品需设有电源指示灯(绿),上电后,指示灯亮;
(2)该闹钟能够显示当前的日期和时间,显示界面如下:
Alarm Clock
Date:年-月-日 (日期)
Time:时:分:秒 (时间)
Alm: 时:分:秒 (报警时间)
(3)报警时间可调。设4个按键,分别为调时、调分、调秒、确定
(4)当报警时间到达时,采用蜂鸣器报警,蜂鸣器要求响5S钟。
系统系统基于DS3231实时时钟模块的stm32简易闹钟_第1张图片

时钟模块设计与论证

方案一:直接采用STM32单片机自身集成的RTC实时时钟,使用程序实现年、月、日、星期、时、分、秒计数。采用此种方案虽然减少芯片的使用,节约成本,但是单片机掉电会丢失数据,需要外部32.768KHz晶振和纽扣电池供电。 
方案二:采用DS1302为计时时钟芯片 
该芯片是串行电路,与单片机接口简单,但需另备电池和32.768kHz晶振,因焊接工艺和晶振质量等原因会导致精度降低。
方案三:采用DS3231实时时钟模块
该芯片与单片机通过IIC串行通信,传递速度比较快。自带有电池,不需要外部晶振,完整的时钟日历功能包括秒、分、时、星期、日期、月和年计时,并提供有效期到2100年的闰年补偿,两个日历闹钟。还有集成了温度传感器,成本低。
由于DS3231时钟芯片模块精度高,而且具有闰年补偿功能且价格经济实惠等优点,故采用方案三。

本设计采用模块

采用STM32F103C8T6作为控制器,采用独立按键输入,0.96寸OLED显示屏spi四线通信作为显示模块,DS3231M模块作为实时时钟模块,发声模块采用有源蜂鸣器模块。
原理图如下:
基于DS3231实时时钟模块的stm32简易闹钟_第2张图片
主程序:


#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "oled.h"
#include "picture.h"
#include "ds3231.h"
#include "key.h"

_calendar_part calendar;//声明时钟结构体

_Alarmclock_part Alarmclock;//声明闹钟结构体

typedef struct
{
	u8 sure_flag;
	u8 stop_flag;
}_Alarm_flag;	//标志结构体

_Alarm_flag flag;

void display(void);
void Key_Control(void);

int main()
{
	SysTick_Init(72);//系统时钟初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
	LED_Init();				//led初始化
	OLED_Init();			//OLED初始化
	DS3231_Init();		//DS3231初始化
	KEY_Init();				//按键初始化
	Alarmclock.hour = 8;//闹钟初始值
	Alarmclock.min = 50;
	Alarmclock.sec = 0;
	Alarmclock1_close();//初始先将闹钟关闭并清除闹钟标志位
	Alarmclock1_cmd(0);
	beep = 1;
	while(1)
	{
		get_time();
		display();	//oled显示
		Key_Control();	//按键控制
		if(flag.sure_flag)
		{
			Alarmclock1_cmd(1);	//闹钟使能
			SetAlarmclock(Alarmclock.hour,Alarmclock.min,Alarmclock.sec);//设置闹钟
			if(Alarmclock1state()==1&&!flag.stop_flag)//检测闹钟标志位
			{
				beep = 0;					//蜂鸣器打开
			Alarmclock1_cmd(0); //闹钟失能
			Alarmclock1_close();	//关闭闹钟并清理标志位
			flag.stop_flag = 1;	
			}
		}
		else
		{
			beep = 1;	//蜂鸣器关闭
		}
		if(flag.stop_flag)		//使闹钟5秒钟后停止
		{
			Alarmclock1_cmd(1);		
			SetAlarmclock(Alarmclock.hour,Alarmclock.min,Alarmclock.sec+5);	
			if(Alarmclock1state()==1)
			{
					beep = 1;
				Alarmclock1_cmd(0);
				Alarmclock1_close();
				flag.stop_flag = 0;
				flag.sure_flag = 0;
			}
		}
		
	}
}

void display(void)//OLED显示
{
	/*****日期显示****/
	OLED_ShowNum(0,0,2000+calendar.year,4,16);
	OLED_ShowFontHZ(16*2,0,0,16,1);  //年
	OLED_ShowNum(16*3,0,calendar.month,2,16);
	OLED_ShowFontHZ(16*4,0,1,16,1);  //月
	OLED_ShowNum(16*5,0,calendar.day,2,16);
	OLED_ShowFontHZ(16*6,0,2,16,1);  //日
	/*****时间显示*****/
	OLED_ShowChar(24*0,16,calendar.hour/10+'0',24,1);	//时
	OLED_ShowChar(12*1,16,calendar.hour%10+'0',24,1);	//时
	OLED_ShowChar(6*5,16,':',24,1);
	OLED_ShowChar(24*2,16,calendar.min/10+'0',24,1);	//分
	OLED_ShowChar(12*5,16,calendar.min%10+'0',24,1);	//分
	OLED_ShowChar(6*13,16,':',24,1);
	OLED_ShowChar(24*4,16,calendar.sec/10+'0',24,1);	//秒
	OLED_ShowChar(12*9,16,calendar.sec%10+'0',24,1);	//秒
	
	/******闹钟******/
	if(flag.sure_flag)OLED_ShowString(16*0,48,"A",16);
	else OLED_ShowString(16*0,48," ",16);
	OLED_ShowChar(16*1,48,Alarmclock.hour/10+'0',16,1);	//时
	OLED_ShowChar(8*3,48,Alarmclock.hour%10+'0',16,1);	//时
	OLED_ShowChar(4*9,48,':',16,1);
	OLED_ShowChar(16*3,48,Alarmclock.min/10+'0',16,1);	//分
	OLED_ShowChar(8*7,48,Alarmclock.min%10+'0',16,1);	//分
	OLED_ShowChar(4*17,48,':',16,1);
	OLED_ShowChar(16*5,48,Alarmclock.sec/10+'0',16,1);	//秒
	OLED_ShowChar(8*11,48,Alarmclock.sec%10+'0',16,1);	//秒
	
	OLED_Refresh_Gram();  //刷新GRAM数组

}

void Key_Control(void)//按键控制
{
	u8 temp = 0;
	temp =	KEY_Scan(0);
	switch(temp)
	{
		case 1:	Alarmclock.hour+=1;
						if(Alarmclock.hour>=24) Alarmclock.hour=0;
						break;
		case 2: Alarmclock.min+=1;
						if(Alarmclock.min>=60) Alarmclock.min=0;
						break;
		case 3: Alarmclock.sec+=1;
						if(Alarmclock.sec>=60) Alarmclock.sec=0;
						break;
		case 4: flag.sure_flag =~ flag.sure_flag;
						break;
	}

}


源程序这里https://download.csdn.net/download/qq_44702247/12581386

你可能感兴趣的:(stm32,单片机,嵌入式)