diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 99af1a5f..8f08b7a0 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -9,6 +9,7 @@ list(APPEND ADD_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/partition" "${CMAKE_CURRENT_SOURCE_DIR}/bl_math" "${CMAKE_CURRENT_SOURCE_DIR}/pid" +"${CMAKE_CURRENT_SOURCE_DIR}/timestamp" ) ####################################################### @@ -27,6 +28,7 @@ file(GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/partition/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/bl_math/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/pid/*.c" +"${CMAKE_CURRENT_SOURCE_DIR}/timestamp/*.c" ) #aux_source_directory(. sources) diff --git a/common/timestamp/timestamp.c b/common/timestamp/timestamp.c new file mode 100644 index 00000000..606bafd1 --- /dev/null +++ b/common/timestamp/timestamp.c @@ -0,0 +1,137 @@ +/** + * @file timestamp.c + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ + +#include "timestamp.h" +#include "misc.h" + +#define FOUR_YEAR_DAY ((365 << 2) + 1) //The total number of days in a 4-year cycle +#define TIMEZONE (8) //Beijing time Zone adjustment + +#define SEC_NUM_PER_DAY (24 * 60 * 60) +#define SEC_NUM_PER_HOUR (60 * 60) +#define SEC_NUM_PER_MINUTE (60) + +static uint8_t month_day[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //平年 +static uint8_t Leap_month_day[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //闰年 + +/** +* @bref judge if it is a leap year +* @para year to be judge +* @return 1:leap year 0: nonleap year +*/ +bool check_leap_year(uint16_t year) +{ + if (year % 4) { + return false; + } else { + if ((year % 100 == 0) && (year % 400 != 0)) { + return false; + } else { + return true; + } + } +} + +void cal_weekday(rtc_time *beijing_time) +{ + uint32_t y,m,d,w; + + y=beijing_time->year; + m=beijing_time->month; + d=beijing_time->day; + + if((m==1)||(m==2)) + { + m+=12; + y--; + } + /* + 把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。 + 以公元元年为参考,公元元年1月1日为星期一
程序如下: + 利用基姆拉尔森计算日期公式 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) + */ + w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7; + + beijing_time->week=(uint8_t)w; +} + +void unixtime2bejingtime(uint32_t unixtime, rtc_time *beijing_time) +{ + uint32_t totle_day_num; + uint32_t current_sec_num; + + uint16_t remain_day; + + uint16_t temp_year; + + uint8_t *p = NULL; + + totle_day_num = unixtime / SEC_NUM_PER_DAY; //The total number of days + current_sec_num = unixtime % SEC_NUM_PER_DAY; //The number of seconds this day + + /* use the number of seconds this day, To calculate hour\minute\second */ + beijing_time->hour = current_sec_num / SEC_NUM_PER_HOUR; + beijing_time->minute = (current_sec_num % SEC_NUM_PER_HOUR) / SEC_NUM_PER_MINUTE; + beijing_time->second = (current_sec_num % SEC_NUM_PER_HOUR) % SEC_NUM_PER_MINUTE; + + /* Adjust the time zone and check whether the date is +1 */ + beijing_time->hour += 8; + if (beijing_time->hour > 23) { + beijing_time->hour -= 24; + totle_day_num++; + } + + + /* calculate year */ + beijing_time->year = 1970 + (totle_day_num / FOUR_YEAR_DAY) * 4; // 4-year as a cycle + remain_day = totle_day_num % FOUR_YEAR_DAY; //remaining day nym( < 4 year ) + + /* calculate year & day */ + temp_year = check_leap_year(beijing_time->year) ? 366 : 365; + while (remain_day >= temp_year) { + beijing_time->year++; + remain_day -= temp_year; + temp_year = check_leap_year(beijing_time->year) ? 366 : 365; + } + + /* Calculate specific dates(month\day)*/ + p = check_leap_year(beijing_time->year) ? Leap_month_day : month_day; + remain_day++; //The actual day starts at 1 + beijing_time->month = 0; + while (remain_day > *(p + beijing_time->month)) { + remain_day -= *(p + beijing_time->month); + beijing_time->month++; + } + + beijing_time->month++; //The actual month starts at 1 + beijing_time->day = remain_day; + + + + /*利用基姆拉尔森计算日期公式 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)*/ + + beijing_time->week = beijing_time->day + 2*beijing_time->month + 3*(beijing_time->month+1)/5 + \ + beijing_time->year + beijing_time->year/4 - beijing_time->year/100 +beijing_time->year/400 ; + + cal_weekday(beijing_time); +} diff --git a/common/timestamp/timestamp.h b/common/timestamp/timestamp.h new file mode 100644 index 00000000..2522d0f3 --- /dev/null +++ b/common/timestamp/timestamp.h @@ -0,0 +1,43 @@ +/** + * @file timestamp.h + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _TIMESTAMP_ +#define _TIMESTAMP_ + +#include "stdint.h" +#include "stdbool.h" + +typedef struct _rtc_time_t +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t week; + uint8_t hour; + uint8_t minute; + uint8_t second; +}rtc_time; +void unixtime2bejingtime(uint32_t unixtime,rtc_time* beijing_time); + +#endif + + diff --git a/examples/rtc/rtc_calendar/CMakeLists.txt b/examples/rtc/rtc_calendar/CMakeLists.txt new file mode 100644 index 00000000..64fc817d --- /dev/null +++ b/examples/rtc/rtc_calendar/CMakeLists.txt @@ -0,0 +1,2 @@ +set(mains main.c) +generate_bin() \ No newline at end of file diff --git a/examples/rtc/rtc_calendar/main.c b/examples/rtc/rtc_calendar/main.c new file mode 100644 index 00000000..d32051ed --- /dev/null +++ b/examples/rtc/rtc_calendar/main.c @@ -0,0 +1,41 @@ +/** + * @file main.c + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ + +#include "hal_rtc.h" +#include "timestamp.h" + +int main(void) +{ + rtc_time beijing_time; + + bflb_platform_init(0); + rtc_init(0); //set 0 means comparing none + rtc_set_timestamp(1628074512); //1628074512 :2021-8-4 18:55:12 + while (1) { + bflb_platform_delay_ms(1000); + unixtime2bejingtime((uint32_t)rtc_get_timestamp(), &beijing_time); + MSG("%d/%02d/%02d-%02d:%02d:%02d convert is: %u\r\n", + beijing_time.year, beijing_time.month, beijing_time.day, + beijing_time.hour, beijing_time.minute, beijing_time.second, (uint32_t)rtc_get_timestamp()); + } +}