将32位无符号整数表示的时间信号转化为习惯的形式 | 您所在的位置:网站首页 › 手表上的时间符号表示 › 将32位无符号整数表示的时间信号转化为习惯的形式 |
2019独角兽企业重金招聘Python工程师标准>>> STM32 的RTC模块中有需要将无符号的32位整形数字转化为包含年,月,日,时,分,秒的结构体或者其余表达形式的信号,在纠结了好久之后,勉强第一次实现了功能,现在贴上代码 PS: 因为KEIL调试不够方便,将代码移植到WINDOWS里面调试成功,目前还未移植到STM32中。 #include typedef unsigned char INT8U; typedef unsigned short int INT16U; typedef unsigned int INT32U; /* rtc.h */ #ifndef __RTC_H__ #define __RTC_H__ #define SECDAY 86400UL #define YEAR_START 1970 //系统第一天为1970年1月1日 #define FIRST_WEEK 6 //1970年1月1日为星期四 2000年1月1日为星期六 #define YEAR_TOTAL 130 //只支持100年的数据 //定义结构体记录从RTC模块读取出的数据 typedef struct rtc_time{ //没有加入溢出检查模块,请自行防止数字溢出 INT8U tm_sec; //0-59 INT8U tm_min; //0-59 INT8U tm_hour; //0-23 INT8U tm_day; //1-31 INT8U tm_week; //1-7 INT8U tm_mon; //1-12 INT8U tm_year; //0- YEARTOTAL-1 } RTC_S; void to_tm(INT32U tim,RTC_S* tm); //将32位数字转换为结构体 void from_tm(RTC_S* tm,INT32U* tim); //从tm中读取内容记录到tim中 void quick_init(void); //快速初始化,其实功能是加快后续运算,空间换时间 #endif /* rtc.c 事实时钟模块 */ //#include "includes.h" #define ISLEEP(YEAR) (((YEAR)%4 == 0)&&\ (((YEAR)%100!=0)||((YEAR)%400 == 0))) INT8U quick_leep[YEAR_TOTAL]; //该处理方式浪费了大量空间 INT16U year_sort[YEAR_TOTAL]; //用于判断具体哪年 INT16U month[12] = {31,59,90, 120,151,181, //判断月份 212,243,273, 304,334,365}; INT16U month_leep[12] = {31,60,91, 121,152,182, //判断闰年的月份 213,244,274, 305,335,366}; void quick_init(void) //快速初始化,其实功能是加快后续运算,空间换时间 { INT8U i; INT32U j; for(i = 0 ; i < YEAR_TOTAL ; i++) //建立闰年快速查询表 { j = i + YEAR_START; if(ISLEEP(j)) { quick_leep[i] = 1; } else { quick_leep[i] = 0; } } j = 0; for(i = 0;itm_hour = sec / 3600; tm->tm_min = (sec % 3600) / 60; tm->tm_sec = (sec % 3600) % 60; days = tim / SECDAY; //当前天总数 days += 2; //算上第一天 //得到星期 tm->tm_week = (days + 5 + FIRST_WEEK )%7 + 1; //初步得到年份 year_1 = days / 365; //最终得到year_1 即为当前所在的年份; while(1) { if((0 == year_1)&&(days year_sort[year_1]) { year_1 ++; continue; } else { year_1 --; } } tm->tm_year = year_1; year_3 = year_2 / 31; //初步决定是几月份 if(quick_leep[year_1]) //根据闰年与否选择不同的数组 { pmonth = month_leep; } else { pmonth = month; } while(1) //最终得到正确的月份 year_3 { if((0 == year_3)&&(year_3 pmonth[year_3 - 1])&&(year_2 pmonth[year_3]) { year_3 ++; continue; } else { year_3 --; } } tm->tm_mon = year_3 + 1; //没有0月 tm->tm_day = year_4 ; //没有0日 } void from_tm(RTC_S* tm,INT32U* tim) //从tm中读取内容记录到tim中 { INT8U leep_flag; //闰年标志位 INT16U day_temp = 0; //记录总共计时多少天 INT32U sec_temp = 0; //记录总共一天剩下的多少秒 leep_flag = quick_leep[tm->tm_year]; sec_temp = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; day_temp = tm->tm_day - 1; //没有0号 if( 0 == tm->tm_year) //累加年 级别的天数 { day_temp += 0; } else { day_temp += (year_sort[tm->tm_year - 1]); } if(1 == tm->tm_mon) //累加月 级别的天数 { day_temp += 0; } else if(leep_flag) { day_temp += month_leep[tm->tm_mon - 2]; } else { day_temp += month[tm->tm_mon - 2]; } day_temp--; //减去第一天 *tim = day_temp * SECDAY + sec_temp; //耦合到一个32位数字中去 } void tmprint(RTC_S* tm) //Windows编程环境拓展,用于检查 { printf("year: %d\n",tm->tm_year + YEAR_START); printf("mon: %d\n",tm->tm_mon); printf("day: %d\n",tm->tm_day); printf("week: %d\n",tm->tm_week); printf("hour: %d\n",tm->tm_hour); printf("min: %d\n",tm->tm_min); printf("sec: %d\n",tm->tm_sec); } int main() { RTC_S tm1,tm2; INT32U i,j,k; tm1.tm_sec = 30; tm1.tm_min = 30; tm1.tm_hour = 10; tm1.tm_day = 1; tm1.tm_week = 4; tm1.tm_mon = 2; tm1.tm_year = 2080-YEAR_START; quick_init(); tmprint(&tm1); from_tm(&tm1,&i); printf("%d\n",i); printf("\n"); to_tm(i,&tm2); tmprint(&tm2); from_tm(&tm2,&j); printf("%d\n",j); // system("pause"); return 0; } 程序运行后结果如下,运行一切正常
将代码进行了少量修改,经过测试,因为INT32U的影响,此次计数最多能够计数到130年左右。 |
CopyRight 2018-2019 实验室设备网 版权所有 |