stm32软件闹钟

其实不是stm32啦,因为stm32流量高,这是一个通用的软件闹钟(软件实现的当然通用哈)。

实现10个闹钟,需要mcu提供时间获取函数,1分钟定时检查调用,以及flash读写函数(用来掉电不丢失闹钟信息)。

rtc_alarm.c

#include "rtc_alarm.h"
#include "debug.h"
#include <string.h>
#include "system/includes.h"


#define DBG(format,...)     printf("[SOFT_ALARM]:"format, ##__VA_ARGS__) //LOG

// 记录全部闹钟
static RTC_ALARM_T soft_alarm_table[RTC_ALARM_MAX];

//打印soft_alarm_table
static void soft_alarm_printf(void)
{
    for(int i = 0; i < RTC_ALARM_MAX; i++)
    {
        DBG("index = %d sw = %d mode = %d %d-%d-%d,%d:%d:%d\n",
        soft_alarm_table[i].index, soft_alarm_table[i].sw, soft_alarm_table[i].mode,
        soft_alarm_table[i].time.year, soft_alarm_table[i].time.month, soft_alarm_table[i].time.day,
        soft_alarm_table[i].time.hour, soft_alarm_table[i].time.min, soft_alarm_table[i].time.sec);
    }
}

//调试调用檫除
static void soft_alarm_erase(void)
{
	//clear
	memset(&soft_alarm_table[0].index, 0x00, sizeof(soft_alarm_table));
    //write flash
    syscfg_write(CFG_USER_SOFT_ALARM, &soft_alarm_table[0].index, sizeof(soft_alarm_table));
}


//更新闹钟时调用
static void soft_alarm_save(void)
{
    //write flash
    syscfg_write(CFG_USER_SOFT_ALARM, &soft_alarm_table[0].index, sizeof(soft_alarm_table));

	//LOG
	//soft_alarm_printf();
}

// 上电调用
void soft_alarm_init(void)
{
    //read flash
    syscfg_read(CFG_USER_SOFT_ALARM, &soft_alarm_table[0].index, sizeof(soft_alarm_table));

	//LOG
	soft_alarm_printf();
}

//获取时间
static void get_now_time(RTC_TIME_T *p)
{
    //get time
	get_sys_time(p);

	//DBG("now time: %d-%d-%d,%d:%d:%d\n", p->year, p->month, p->day, p->hour, p->min, p->sec);
}

// 设置软件闹钟时间
static void soft_alarm_set(RTC_ALARM_T_P p)
{
	p->time.sec = 0;//闹钟不定时秒,到分钟就可以
    memcpy(&soft_alarm_table[p->index].index, &p->index, sizeof(RTC_ALARM_T));

	soft_alarm_save();
}


//日期转换为星期
//蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26x(m+1)/10]+d-1
//返回周1-7
static uint8_t rtc_calculate_week_val(RTC_TIME_T *data_time)
{
    RTC_TIME_T t_time;
    uint32_t century, val, year;

    memcpy(&t_time, data_time, sizeof(struct sys_time));
    if (t_time.month < 3) {
        t_time.month = t_time.month + 12;
        t_time.year--;
    }
    year = t_time.year % 100;
    century = t_time.year / 100;
    val = year + (year / 4) + (century / 4) + (26 * (t_time.month + 1) / 10) + t_time.day;
    val = val - century * 2 - 1;

    return (uint8_t)(val % 7) == 0 ? 7 : (val % 7);
}

static void beep(uint8_t number)
{
	DBG(">>>>ALARM ALARM %d\n", number);
	DBG(">>>>ALARM ALARM %d\n", number);
	DBG(">>>>ALARM ALARM %d\n", number);
	soft_alarm_printf();//DBG
}

//1分钟 执行一次检查闹钟是否需要执行
void soft_alarm_check(void)
{
    DBG("%s\n", __func__);

    int i;
	uint8_t week;
	RTC_TIME_T nowtime;
    get_now_time(&nowtime);

	week = 1 << rtc_calculate_week_val(&nowtime);

    for(i = 0; i < RTC_ALARM_MAX; i++)
    {
        if(soft_alarm_table[i].sw != TRUE) continue;

		if(memcmp(&soft_alarm_table[i].time.hour, &nowtime.hour, 3) != 0) continue;

		if(soft_alarm_table[i].mode == E_ALARM_MODE_ONCE)
		{
			soft_alarm_table[i].sw = FALSE;
			soft_alarm_save();
			goto ret;
		}
		else if(soft_alarm_table[i].mode == E_ALARM_MODE_EVERY_DAY)
		{
			goto ret;
		}
		else if((soft_alarm_table[i].mode & week ) > 0)
		{
			goto ret;
		}
    }

	return;
	ret:
	beep(i);
}

void rtc_alarm_test(void)
{
    DBG("%s\n", __func__);

	//soft_alarm_init();
	//soft_alarm_erase();
    //soft_alarm_printf();

	/*设置当前时间+1分钟的闹钟*/
    RTC_ALARM_T t;
    get_now_time(&t.time);

 	if(t.time.min < 59) t.time.min++;//暂时不考虑60分钟的情况
    t.index = 1;//测试使用第一个闹钟
    t.mode = E_ALARM_MODE_ONCE;//一次
    t.sw = TRUE;//打开

	t.time.year = 2024;
	t.time.month = 1;
	t.time.day = 3;

	DBG("week = %d\n", rtc_calculate_week_val(&t.time));

    soft_alarm_set(&t);

	//打印观察
    soft_alarm_printf();
}

rtc_alarm.h

#ifndef RTC_ALARM_H
#define RTC_ALARM_H

#include "typedef.h"

typedef struct rtc_time {
    u16 year;
    u8 month;
    u8 day;
    u8 hour;
    u8 min;
    u8 sec;
}RTC_TIME_T;

enum {
    E_ALARM_MODE_ONCE            = 0x00,
    E_ALARM_MODE_EVERY_DAY       = 0x01,
    E_ALARM_MODE_EVERY_MONDAY    = 0x02,
    E_ALARM_MODE_EVERY_TUESDAY   = 0x04,
    E_ALARM_MODE_EVERY_WEDNESDAY = 0x08,
    E_ALARM_MODE_EVERY_THURSDAY  = 0x10,
    E_ALARM_MODE_EVERY_FRIDAY    = 0x20,
    E_ALARM_MODE_EVERY_SATURDAY  = 0x40,
    E_ALARM_MODE_EVERY_SUNDAY    = 0x80,
};

typedef struct __ALARM__ {
    u8 index;   //索引
    bool sw;    //开关
    u8 mode;    //模式
    RTC_TIME_T time;//时间
} RTC_ALARM_T, *RTC_ALARM_T_P;

#define RTC_ALARM_MAX (10) //当前10个闹钟

void rtc_alarm_test(void);
extern void soft_alarm_init(void);
extern void soft_alarm_check(void);

#endif

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值