STM32F1基于标准库工程RTC秒钟断+定时闹钟功能示例
工程功能介绍
基于STM32F103,使用的是标准库,套用正点原子工程模板,使用STM32的RTC时钟系统中的秒中断和RTC 闹钟报警中断来执行相对应的代码。这里仅演示各中断功能响应执行的代码。可以参考此功能模块自行移植。
RTC秒中断和闹钟驱动
#include "rtc.h"
_calendar_obj calendar;
const u8 mon_table[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static void RTC_Alarm_EXIT(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line17);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void RTC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_ITConfig(RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask();
RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RTC_Alarm_EXIT();
}
u8 Is_Leap_Year(u16 pyear)
{
if(pyear % 4 == 0)
{
if(pyear % 100 == 0)
{
if(pyear % 400 == 0) return 1;
else return 0;
}
else
return 1;
}
else
return 0;
}
u8 RTC_Get(void)
{
static u16 dayCount = 0;
u32 secCount = 0;
volatile u32 tmp = 0;
u16 tmp1 = 0;
secCount = RTC_GetCounter();
tmp = secCount / 86400;
if(dayCount != tmp)
{
dayCount = tmp;
tmp1 = 1970;
while(tmp >= 365)
{
if(Is_Leap_Year(tmp1))
{
if(tmp >= 366)
tmp -= 366;
else
{
break;
}
}
else
tmp -= 365;
tmp1++;
}
calendar.w_year = tmp1;
tmp1 = 0;
while(tmp >= 28)
{
if(Is_Leap_Year(calendar.w_year) && tmp1 == 1)
{
if(tmp >= 29)
tmp -= 29;
else
break;
}
else
{
if(tmp >= mon_table[tmp1])
tmp -= mon_table[tmp1];
else
break;
}
tmp1++;
}
calendar.w_month = tmp1 + 1;
calendar.w_date = tmp + 1;
}
tmp = secCount % 86400;
calendar.hour = tmp / 3600;
calendar.min = (tmp % 3600) / 60;
calendar.sec = (tmp % 3600) % 60;
return 0;
}
u8 RTC_Set(u16 year, u8 mon, u8 day, u8 hour, u8 min, u8 sec)
{
u16 t;
u32 secCount = 0;
if(year < 1970 || year > 2099)
return 1;
for(t = 1970; t < year; t++)
{
if(Is_Leap_Year(t))
secCount += 31622400;
else
secCount += 31536000;
}
mon -= 1;
for(t = 0; t < mon; t++)
{
secCount += (u32)mon_table[t] * 86400;
if(Is_Leap_Year(year) && t == 1)
secCount += 86400;
}
secCount += (u32)(day - 1) * 86400;
secCount += (u32)hour * 3600;
secCount += (u32)min * 60;
secCount += sec;
RTC_SetCounter(secCount);
RTC_WaitForLastTask();
RTC_Get();
return 0;
}
#ifndef __RTC_H
#define __RTC_H
#include "stm32f10x.h"
typedef struct
{
vu8 hour;
vu8 min;
vu8 sec;
vu16 w_year;
vu8 w_month;
vu8 w_date;
vu8 week;
}_calendar_obj;
extern _calendar_obj calendar;
void RTC_Config(void);
void RTC_Init(void);
u8 RTC_Set(u16 year,u8 mon,u8 day,u8 hour,u8 min,u8 sec);
u8 RTC_Get(void);
#endif
main主程序
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "rtc.h"
#include
volatile unsigned char RTC_IT_SEC_flag = 0;
void LEDInit(void);
void LEDInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
int main(void)
{
volatile u8 t = 0;
delay_init();
RTC_Config();
RTC_Set(2023, 6, 14, 12, 27, 5);
RTC_EnterConfigMode();
RTC_SetAlarm(6 + RTC_GetCounter());
RTC_WaitForLastTask();
RTC_ExitConfigMode();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
LEDInit();
while(1)
{
if(t != calendar.sec)
{
t = calendar.sec;
printf("NowTime:%d 年 %d 月 %d 日 %d 时 %d 分 %d 秒 \r\n ", \
calendar.w_year, calendar.w_month, calendar.w_date, calendar.hour, calendar.min, calendar.sec);
}
}
}
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_SEC);
RTC_Get();
GPIOE->ODR ^= GPIO_Pin_5;
printf("RTC_IT_SEC!\r\n");
RTC_WaitForLastTask();
}
}
void RTCAlarm_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line17);
RTC_WaitForLastTask();
printf("Alarm clock!\r\n");
RTC_ClearITPendingBit(RTC_IT_ALR);
PWR_BackupAccessCmd(ENABLE);
RTC_EnterConfigMode();
RTC_SetAlarm(6 + RTC_GetCounter());
RTC_WaitForLastTask();
RTC_ExitConfigMode();
PWR_BackupAccessCmd(DISABLE);
}
RTC_ClearITPendingBit(RTC_IT_OW);
RTC_WaitForLastTask();
}
工程源码
链接:https:
提取码:2xk3