完善节假日的显示

This commit is contained in:
tpu
2025-05-19 16:29:31 +08:00
parent c7fb41ff2c
commit 7ca189e680
3 changed files with 291 additions and 9 deletions

View File

@@ -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<<l_year))
yinfo |= 0x10000;
// 取得当月的天数
int mdays = 29;
if(lflag){
if(yinfo&0x10000) mdays += 1;
}else{
if(yinfo&(0x8000>>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<month; i++){
d += d2m[i];
}
d += date;
// 计算闰年的天数。因为只考虑2020-2052年这里做了简化。
int Y = year-2020;
int L = (Y)? (Y-1)/4+1 : 0;
// 计算当年小寒的秒数
int xiaohan_sec = xiaohan_2020 + 20950*Y - L*86400;
// 20926是一个回归年(365.2422)不足一天的秒数(.2422*86400).
// 直接用有明显的误差。这里稍微增大了一点(20926+24)。
for(i=0; i<24; i++){
int sec = xiaohan_sec + jieqi_info[i];
int day = sec/86400;
if(day==d)
return i;
}
return -1;
}
/****************************************************************************************/
static int get_month_day(int mon)
{
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;
return d2m[month];
}
// 增加1天
void date_inc(void)
{
wday += 1;
if(wday>=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);
}

View File

@@ -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;

View File

@@ -85,6 +85,9 @@
****************************************************************************************
*/
extern char *bt_id;
/*
* FUNCTION DECLARATIONS
****************************************************************************************