From 7ca189e68029d59662b258194afb4ab6a24b047f Mon Sep 17 00:00:00 2001 From: tpu Date: Mon, 19 May 2025 16:29:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=8A=82=E5=81=87=E6=97=A5?= =?UTF-8?q?=E7=9A=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/user_custs1_impl.c | 296 +++++++++++++++++++++++++++++++++++++++-- src/user_peripheral.c | 1 + src/user_peripheral.h | 3 + 3 files changed, 291 insertions(+), 9 deletions(-) diff --git a/src/user_custs1_impl.c b/src/user_custs1_impl.c index b1df124..e539d83 100644 --- a/src/user_custs1_impl.c +++ b/src/user_custs1_impl.c @@ -60,6 +60,9 @@ uint16_t indication_counter __SECTION_ZERO("retention_mem_area0"); //@RETENTION uint16_t non_db_val_counter __SECTION_ZERO("retention_mem_area0"); //@RETENTION MEMORY int adcval; + +static void get_holiday(void); + /* * FUNCTION DEFINITIONS **************************************************************************************** @@ -85,22 +88,141 @@ int adc1_update(void) /****************************************************************************************/ +static const uint16_t lunar_year_info[32] = +{ + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x0d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x0b255, 0x06d20, 0x0ada0, //2040-2049 + 0x04b63, 0x09370, //2050-2051 +}; +static const uint32_t lunar_year_info2 = 0x48010000; + + +// 每个节气相对于"小寒"的秒数 +static int jieqi_info[] = +{ + 0, 1272283, 2547462, 3828568, 5117483, 6416376, + 7726093, 9047327, 10379235, 11721860, 13072410, 14428379, + 15787551, 17145937, 18501082, 19850188, 21190911, 22520708, + 23839844, 25146961, 26443845, 27730671, 29010666, 30284551, +}; + +// 已知2020年"小寒"相对于1月1日的秒数 +#define xiaohan_2020 451804 + + int year=2025, month=0, date=0, wday=2; +int l_year=4, l_month=11, l_date=1; int hour=0, minute=0, second=0; -// 增加1天 -void date_inc(void) + +static int get_lunar_mdays(int mon, int *yinfo_out) +{ + int lflag = mon&0x80; + mon &= 0x7f; + + // 取得当年的信息 + int yinfo = lunar_year_info[l_year]; + if(lunar_year_info2&(1<>mon)) mdays += 1; + } + + if(yinfo_out) + *yinfo_out = yinfo; + return mdays; +} + + +// 农历增加一天 +void ldate_inc(void) +{ + int lflag = l_month&0x80; + int mon = l_month&0x7f; + int yinfo; + + int mdays = get_lunar_mdays(l_month, &yinfo); + + l_date += 1; + if(l_date==mdays){ + l_date = 0; + mon += 1; + if(lflag==0 && mon==(yinfo&0x0f)){ + lflag = 0x80; + mon -= 1; + }else{ + lflag = 0; + } + if(mon==12){ + mon = 0; + l_year += 1; + } + l_month = lflag|mon; + } +} + + +// 给出年月日,返回是否是节气日 +int jieqi(int year, int month, int date) { uint8_t d2m[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; int is_leap = (year%4)? 0 : (year%100)? 1: (year%400)? 0: 1; d2m[1] += is_leap; + // 计算当前日期是本年第几天 + int i, d=0; + for(i=0; i=7) wday = 0; date += 1; - if(date==d2m[month]){ + if(date==get_month_day(month)){ date = 0; month += 1; if(month>=12){ @@ -137,6 +259,8 @@ int clock_update(int inc) if(hour>=24){ hour = 0; date_inc(); + ldate_inc(); + get_holiday(); retv = 4; } } @@ -146,13 +270,18 @@ int clock_update(int inc) void clock_set(uint8_t *buf) { - year = buf[1] + buf[2]*256; + year = buf[1] + buf[2]*256; month = buf[3]; date = buf[4]-1; hour = buf[5]; minute = buf[6]; second = buf[7]; wday = buf[8]-1; + l_year = buf[9]; + l_month= buf[10]; + l_date = buf[11]-1; + + get_holiday(); } @@ -178,16 +307,150 @@ void clock_push(void) void clock_print(void) { - printk("\n%04d-%02d-%02d %02d:%02d:%02d\n", year, month+1, date+1, hour, minute, second); + printk("\n%04d-%02d-%02d %02d:%02d:%02d L: %d-%d\n", year, month+1, date+1, hour, minute, second, l_month+1, l_date+1); } /****************************************************************************************/ +static char *jieqi_name[] = { + "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", + "清明", "谷雨", "立夏", "小满", "芒种", "夏至", + "小暑", "大暑", "立秋", "处暑", "白露", "秋分", + "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", +}; static char *wday_str[] = {"一", "二", "三", "四", "五", "六", "日"}; +static char *lday_str_lo[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊", "正"}; +static char *lday_str_hi[] = {"初", "十", "廿", "二", "三"}; + static int epd_wait_state; static timer_hnd epd_wait_hnd; +typedef struct { + char *name; + uint8_t mon; + uint8_t day; +}HOLIDAY_INFO; + +HOLIDAY_INFO hday_info[] = { + {"除夕", 0xc0|12, 30}, + {"春节", 0x80| 1, 1}, + {"元宵节", 0x80| 1, 15}, + {"龙抬头", 0x80| 2, 2}, + {"端午节", 0x80| 5, 5}, + {"七夕节", 0x80| 7, 7}, + {"中秋节", 0x80| 8, 15}, + {"重阳节", 0x80| 9, 9}, + {"腊八节", 0x80|12, 8}, + + {"元旦节", 1, 1}, + {"情人节", 2, 14}, + {"妇女节", 3, 8}, + {"植树节", 3, 12}, + {"愚人节", 4, 1}, + {"劳动节", 5, 1}, + {"青年节", 5, 4}, + {"母亲节", 5, 0x97}, // 5月第二个周日 + {"儿童节", 6, 1}, + {"父亲节", 6, 0xa7}, // 6月第三个周日 + {"教师节", 9, 10}, + {"国庆节", 10, 1}, + {"程序员节", 10, 24}, + {"万圣节", 11, 1}, + {"光棍节", 11, 11}, + {"平安夜", 12, 24}, + {"圣诞节", 12, 25}, + {"", 0, 0}, +}; + +static char *jieqi_str = "小寒"; +static char *holiday_str = "元旦节"; + +static void ldate_str(char *buf) +{ + char *lflag = (l_month&0x80)? "闰" : ""; + int lm = l_month&0x7f; + if(lm==0){ + lm = 12; + } + + int hi = l_date/10; + int lo = l_date%10; + + if(lo==9){ + if(hi==1) + hi = 3; + else if(hi==2) + hi = 4; + } + + sprintf(buf, "%s%s月%s%s", lflag, lday_str_lo[lm], lday_str_hi[hi], lday_str_lo[lo]); +} + + +static void set_holiday(int index) +{ + if(holiday_str==NULL){ + holiday_str = hday_info[index].name; + }else if(jieqi_str==NULL){ + // 已经有一个农历节日了,将其转移到节气位置。 + jieqi_str = holiday_str; + holiday_str = hday_info[index].name; + }else{ + // printf("OOPS! 节日溢出!\n"); + } +} + +void get_holiday(void) +{ + int i; + + jieqi_str = NULL; + holiday_str = NULL; + + i = jieqi(year, month, date); + if(i>=0){ + jieqi_str = jieqi_name[i]; + } + + i = 0; + while(hday_info[i].mon){ + int mon = hday_info[i].mon; + int day = hday_info[i].day; + int mflag = mon&0xc0; + int dflag = day; + mon = (mon&0x0f)-1; + day = (day&0x1f)-1; + if(mflag&0x80){ + // 农历节日 + if(mflag&0x40){ + // 当月最后一天 + int mdays = get_lunar_mdays(l_month, NULL); + day = mdays-1; + } + if(l_month==mon && l_date==day){ + set_holiday(i); + } + }else{ + // 公历节日 + if(dflag&0x80){ + // 第几个周天 + int wc = date/7; + int hwc = (dflag>>4)&0x03; + day &= 0x07; + if(month==mon && wc==hwc && wday==day){ + set_holiday(i); + } + }else if(month==mon && date==day){ + set_holiday(i); + } + } + i += 1; + } + + return; +} + static uint8_t batt_cal(uint16_t adc_sample) { @@ -258,25 +521,40 @@ void clock_draw(int flags) memset(fb_bw, 0xff, scr_h*line_bytes); memset(fb_rr, 0x00, scr_h*line_bytes); + // 显示电池电量 draw_batt(190, 13); if(flags&DRAW_BT){ + // 显示蓝牙图标 draw_bt(180, 13); } - + + // 使用大字显示时间 select_font(1); sprintf(tbuf, "%02d:%02d", hour, minute); draw_text(12, 25, tbuf, BLACK); + // 显示公历日期 sprintf(tbuf, "%4d年%2d月%2d日 星期%s", year, month+1, date+1, wday_str[wday]); select_font(0); draw_text(15, 8, tbuf, BLACK); - - draw_text(12, 85, "十二月初二", BLACK); + // 显示农历日期(不显示年) + ldate_str(tbuf); + draw_text(12, 85, tbuf, BLACK); + // 显示节气与节假日 + if(jieqi_str) + draw_text( 98, 85, jieqi_str, BLACK); + if(flags&DRAW_BT){ + draw_text(152, 85, bt_id, BLACK); + }else if(holiday_str){ + draw_text(152, 85, holiday_str, BLACK); + } + + // 墨水屏更新显示 epd_init(); epd_screen_update(); epd_update(); - + // 更新时如果深度休眠,会花屏。 这里暂时关闭休眠。 arch_set_sleep_mode(ARCH_SLEEP_OFF); epd_wait_hnd = app_easy_timer(40, epd_wait_timer); } diff --git a/src/user_peripheral.c b/src/user_peripheral.c index 881c81d..76c5f31 100644 --- a/src/user_peripheral.c +++ b/src/user_peripheral.c @@ -74,6 +74,7 @@ static int adv_state; static int otp_btaddr[2]; static int otp_boot; static char adv_name[20]; +char *bt_id = adv_name+12; int clock_interval; diff --git a/src/user_peripheral.h b/src/user_peripheral.h index bbb8113..dec69d7 100644 --- a/src/user_peripheral.h +++ b/src/user_peripheral.h @@ -85,6 +85,9 @@ **************************************************************************************** */ +extern char *bt_id; + + /* * FUNCTION DECLARATIONS ****************************************************************************************