实时时钟+闹钟

在江科大实时时钟的基础上添加闹钟的配置,参考http://t.csdn.cn/YDlYy

实现功能 :每隔time秒蜂鸣器响一次、设置闹钟的年月日时分秒,到时间蜂鸣器响。

前三个函数没有变,添加 

  • void RTC_AlarmInit(void)  闹钟的中断配置
  • void RTC_AlarmSet(uint16_t time) 闹钟的时间设置,实际是RTC_ALR的值
  • void RTC_IRQHandler(void)  中断函数配置,当RTC_CNT = RTC_ALR时产生中断标志位

#include "stm32f10x.h"                  // Device header
#include <time.h>
#include "MYRTC.h"

uint16_t RTC_Time[6]={2023,1,1,23,59,55};
uint8_t Flag=0;
void MyRTC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	PWR_BackupAccessCmd(ENABLE);
	
	if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)//借助BKP的特性,置一个数当作标志位实现复位断电不重置时间
	{
		RCC_LSEConfig(RCC_LSE_ON);     //32.768KHz
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)//调用函数等RCC有个标志位LSERDY置1时时钟启动完成

		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
		RCC_RTCCLKCmd(ENABLE);
		
		RTC_WaitForSynchro();
		RTC_WaitForLastTask();
		
		//注意事项第三点。函数本身调用了进入配置模式函数,所以不用再每次调用。
		RTC_SetPrescaler(32768 - 1);	//时钟频率1hz
		RTC_WaitForLastTask();			//对RTC寄存器的写操作要等待写操作结束
		
		RTC_SetTime();			
				
		BKP_WriteBackupRegister(BKP_DR1,0XA5A5);
	}
	else     	//继续计时
	{
		RTC_WaitForSynchro();
		RTC_WaitForLastTask();
	}
	
}

void RTC_SetTime(void)		//设置时间就是对RTC_CNT进行设置
{
	time_t time_cnt;
	struct tm time_date;
	
	time_date.tm_year=RTC_Time[0] - 1900;
	time_date.tm_mon=RTC_Time[1] - 1;
	time_date.tm_mday=RTC_Time[2];
	time_date.tm_hour=RTC_Time[3];
	time_date.tm_min=RTC_Time[4];
	time_date.tm_sec=RTC_Time[5];
	
	time_cnt = mktime(&time_date) - 8*60*60;
	
	RTC_SetCounter(time_cnt);
	RTC_WaitForLastTask();
}

void RTC_ReadTime(void)
{
	time_t time_cnt;
	struct tm time_date;
	
	time_cnt=RTC_GetCounter() + 8*60*60;
	time_date = *localtime(&time_cnt);
	
	RTC_Time[0] = time_date.tm_year + 1900;
	RTC_Time[1] = time_date.tm_mon + 1;
	RTC_Time[2] = time_date.tm_mday;
	RTC_Time[3] = time_date.tm_hour;
	RTC_Time[4] = time_date.tm_min;
	RTC_Time[5] = time_date.tm_sec;
	
}	
void RTC_AlarmInit(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
//	RTC->CRH |= 0X02;				//一定要加 允许闹钟中断
	RTC_ITConfig(RTC_IT_ALR,ENABLE);

}
void RTC_AlarmSet(uint16_t time)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	PWR_BackupAccessCmd(ENABLE);
	
	RTC_SetAlarm(RTC_GetCounter()+time);
	RTC_WaitForLastTask();
}
void RTC_IRQHandler(void)
{
	if(RTC_GetITStatus(RTC_IT_ALR) == SET)
	{
		Flag=1;
		RTC_AlarmSet(5);
		RTC_ClearITPendingBit(RTC_IT_ALR);
		RTC_WaitForLastTask();
	}
	
}
uint8_t RTC_GetFlag(void)
{
	uint8_t tempFlag = Flag;
    Flag = 0;
    return tempFlag;
}

主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.H"
#include "Key.h"
#include "OLED.H"
#include "MYRTC.h"

int main(void)
{
	OLED_Init();
	MyRTC_Init();
	RTC_AlarmInit();
	RTC_AlarmSet(5);
	OLED_ShowString(1,1,"Date:XXXX-XX-XX");
	OLED_ShowString(2,1,"Time:XX-XX-XX");
	OLED_ShowString(3,1,"CNT:");
	OLED_ShowString(4,1,"DIV:");

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
	
	while(1)
	{
		RTC_ReadTime();
		
		OLED_ShowNum(1,6,RTC_Time[0],4);
		OLED_ShowNum(1,11,RTC_Time[1],2);
		OLED_ShowNum(1,14,RTC_Time[2],2);
		OLED_ShowNum(2,6,RTC_Time[3],2);
		OLED_ShowNum(2,9,RTC_Time[4],2);
		OLED_ShowNum(2,12,RTC_Time[5],2);
		OLED_ShowNum(3,6,RTC_GetCounter(),10);
		
		//DIV每自减一轮,cnt+1;自减范围32767~0
		OLED_ShowNum(4,6,RTC_GetDivider(),10); 
		
		if(RTC_GetFlag() == 1)
		{
			GPIO_ResetBits(GPIOA,GPIO_Pin_1);
			Delay_ms(100);
			GPIO_SetBits(GPIOA,GPIO_Pin_1);
		}
	}
}

或者定义一个闹钟的数组,在设置时间里和RTC一样对闹钟的RTC_ALR进行配置。

    time_t time_cnt;
    struct tm time_date;
    time_date.tm_year=Alarm_Time[0] - 1900;
    time_date.tm_mon=Alarm_Time[1] - 1;
    time_date.tm_mday=Alarm_Time[2];
    time_date.tm_hour=Alarm_Time[3];
    time_date.tm_min=Alarm_Time[4];
    time_date.tm_sec=Alarm_Time[5];
    time_cnt = mktime(&time_date) - 8*60*60;
    RTC_SetAlarm(time_cnt);

猜你喜欢

转载自blog.csdn.net/m0_70732442/article/details/132249913