我碰到的問題,GPS上UTC時(shí)間轉(zhuǎn)北京時(shí)間和STM32上UNIX時(shí)間戳轉(zhuǎn)北京時(shí)間。
這部分之前講RTC和GPS的時(shí)候有涉及到一部分。
具體的RTC如何得到UNIX時(shí)間戳,和GNRMC如何解析得到UTC時(shí)間可以參看一下。
參看:STM32開發(fā) – RTC詳解
參看:STM32開發(fā) – GPS模塊開發(fā)詳解
擴(kuò)展:C語言再學(xué)習(xí) – 時(shí)間函數(shù)
這里主要看三者轉(zhuǎn)換方法:
一、UTC時(shí)間轉(zhuǎn)換為北京時(shí)間
參看:UTC時(shí)間轉(zhuǎn)換為北京時(shí)間
時(shí)間類型結(jié)構(gòu)體
//UTC時(shí)間信息
__packed typedef struct
{
uint16_t year; //年份
uint8_t month; //月份
uint8_t date; //日期
uint8_t hour; //小時(shí)
uint8_t min; //分鐘
uint8_t sec; //秒鐘
}nmea_time;
UTC時(shí)間轉(zhuǎn)任意時(shí)區(qū)時(shí)間
其中,北京時(shí)間 = UTC time + 8 hours
void UTC_to_BJtime(nmea_time* utc_time, int8_t timezone)
{
int year,month,day,hour;
int lastday = 0; //last day of this month
int lastlastday = 0; //last day of last month
year = utc_time->year; //utc time
month = utc_time->month;
day = utc_time->date;
hour = utc_time->hour + timezone;
if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12){
lastday = 31;
if(month == 3){
if((year%400 == 0)||(year%4 == 0 && year%100 != 0)) //if this is lunar year
lastlastday = 29;
else
lastlastday = 28;
}
if(month == 8)
lastlastday = 31;
}
else if(month == 4 || month == 6 || month == 9 || month == 11){
lastday = 30;
lastlastday = 31;
}
else{
lastlastday = 31;
if((year%400 == 0)||(year%4 == 0 && year%100 != 0))
lastday = 29;
else
lastday = 28;
}
if(hour >= 24){ // if >24, day+1
hour -= 24;
day += 1;
if(day > lastday){ // next month, day-lastday of this month
day -= lastday;
month += 1;
if(month > 12){ // next year , month-12
month -= 12;
year += 1;
}
}
}
if(hour < 0){ // if <0, day-1
hour += 24;
day -= 1;
if(day < 1){ // month-1, day=last day of last month
day = lastlastday;
month -= 1;
if(month < 1){ // last year , month=12
month = 12;
year -= 1;
}
}
}
// transfer value to NMEA_result.local_time
NMEA_result.local_time.year = year;
NMEA_result.local_time.month = month;
NMEA_result.local_time.date = day;
NMEA_result.local_time.hour = hour;
NMEA_result.local_time.min = utc_time->min;
NMEA_result.local_time.sec = utc_time->sec;
}
二、UNIX Time 時(shí)間戳 與 北京時(shí)間 相互轉(zhuǎn)換
參看:UNIX Time 時(shí)間戳 與 北京時(shí)間 相互轉(zhuǎn)換
typedef struct t_xtime {
int year; int month; int day;
int hour; int minute; int second;
} _xtime ;
#define xMINUTE (60 ) //1分的秒數(shù)
#define xHOUR (60*xMINUTE) //1小時(shí)的秒數(shù)
#define xDAY (24*xHOUR ) //1天的秒數(shù)
#define xYEAR (365*xDAY ) //1年的秒數(shù)
1、將localtime(UTC+8北京時(shí)間)轉(zhuǎn)為UNIX TIME,以1970年1月1日為起點(diǎn)
unsigned int xDate2Seconds(_xtime *time)
{
static unsigned int month[12]={
/*01月*/xDAY*(0),
/*02月*/xDAY*(31),
/*03月*/xDAY*(31+28),
/*04月*/xDAY*(31+28+31),
/*05月*/xDAY*(31+28+31+30),
/*06月*/xDAY*(31+28+31+30+31),
/*07月*/xDAY*(31+28+31+30+31+30),
/*08月*/xDAY*(31+28+31+30+31+30+31),
/*09月*/xDAY*(31+28+31+30+31+30+31+31),
/*10月*/xDAY*(31+28+31+30+31+30+31+31+30),
/*11月*/xDAY*(31+28+31+30+31+30+31+31+30+31),
/*12月*/xDAY*(31+28+31+30+31+30+31+31+30+31+30)
};
unsigned int seconds = 0;
unsigned int year = 0;
year = time->year-1970; //不考慮2100年千年蟲問題
seconds = xYEAR*year + xDAY*((year+1)/4); //前幾年過去的秒數(shù)
seconds += month[time->month-1]; //加上今年本月過去的秒數(shù)
if( (time->month > 2) && (((year+2)%4)==0) )//2008年為閏年
seconds += xDAY; //閏年加1天秒數(shù)
seconds += xDAY*(time->day-1); //加上本天過去的秒數(shù)
seconds += xHOUR*time->hour; //加上本小時(shí)過去的秒數(shù)
seconds += xMINUTE*time->minute; //加上本分鐘過去的秒數(shù)
seconds += time->second; //加上當(dāng)前秒數(shù)
seconds -= 8 * xHOUR;
return seconds;
}
2、將UNIX時(shí)間轉(zhuǎn)為UTC+8 即北京時(shí)間
//UNIX轉(zhuǎn)為UTC 已進(jìn)行時(shí)區(qū)轉(zhuǎn)換 北京時(shí)間UTC+8
void xSeconds2Date(unsigned long seconds,_xtime *time )
{
static unsigned int month[12]={
/*01月*/31,
/*02月*/28,
/*03月*/31,
/*04月*/30,
/*05月*/31,
/*06月*/30,
/*07月*/31,
/*08月*/31,
/*09月*/30,
/*10月*/31,
/*11月*/30,
/*12月*/31
};
unsigned int days;
unsigned short leap_y_count;
time->second = seconds % 60;//獲得秒
seconds /= 60;
time->minute = seconds % 60;//獲得分
seconds += 8 * 60 ; //時(shí)區(qū)矯正 轉(zhuǎn)為UTC+8 bylzs
seconds /= 60;
time->hour = seconds % 24;//獲得時(shí)
days = seconds / 24;//獲得總天數(shù)
leap_y_count = (days + 365) / 1461;//過去了多少個(gè)閏年(4年一閏)
if( ((days + 366) % 1461) == 0)
{//閏年的最后1天
time->year = 1970 + (days / 366);//獲得年
time->month = 12; //調(diào)整月
time->day = 31;
return;
}
days -= leap_y_count;
time->year = 1970 + (days / 365); //獲得年
days %= 365; //今年的第幾天
days = 01 + days; //1日開始
if( (time->year % 4) == 0 )
{
if(days > 60)--days; //閏年調(diào)整
else
{
if(days == 60)
{
time->month = 2;
time->day = 29;
return;
}
}
}
for(time->month = 0;month[time->month] < days;time->month++)
{
days -= month[time->month];
}
++time->month; //調(diào)整月
time->day = days; //獲得日
}
3、UTC(字符串)轉(zhuǎn)UNIX時(shí)間
/*******************************************************************************
* Function Name : ConvertTimeToSecond
* Description : Convert GPS Date to Log buffer.
* Input : @date: format 'DDMMYY,HHMMSS.SSS'
* Output : None
* Return : Sencod
*******************************************************************************/
static u32 ConvertDateToSecond(const u8 *date)
{
u32 sencods = 0;
u16 temp = 1970;
u16 days = 0;
if(NULL == date) {
return 0;
}
//year
temp = (date[4] - 0x30) * 10 + (date[5] - 0x30) + 2000;
if(0 == (temp % 4)) {
days += 1;
}
temp -= 1;
//UTC time start 1970
for(; temp >= 1970; temp--) {
if(temp % 4) {
days += 365;
} else {
//leap year
days += 366;
上一篇:STM32開發(fā) -- 看門狗詳解
下一篇:STM32開發(fā) -- 外部中斷詳解
推薦閱讀最新更新時(shí)間:2025-05-23 04:16
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- 人形機(jī)器人馬拉松背后的思考,兆易創(chuàng)新如何賦能機(jī)器人產(chǎn)業(yè)
- 一種基于STM32的智能柜控制器設(shè)計(jì)
- 小型傾轉(zhuǎn)旋翼機(jī)的無刷直流電機(jī)驅(qū)動(dòng)器設(shè)計(jì)
- 超高速攝影機(jī)電控系統(tǒng)設(shè)計(jì)
- 基于GPS自動(dòng)授時(shí)的無線智能控制器的設(shè)計(jì)
- 基于PTR2000的無線氣象信息采集系統(tǒng)設(shè)計(jì)
- Microchip推出MEC175xB系列器件,為嵌入式控制器引入硬件 抗量子攻擊能力
- 無人飛行器機(jī)載穩(wěn)定云臺(tái)控制系統(tǒng)的設(shè)計(jì)
- 匠芯創(chuàng)推出面向具身智能高性能實(shí)時(shí)處理器M7000
- 使用 Analog Devices 的 LT3571 的參考設(shè)計(jì)
- MC32PF3000A1EP PMIC 解決方案電源管理的典型應(yīng)用
- REF198GRUZ-REEL 精密微功率、低壓差電壓基準(zhǔn)的典型應(yīng)用
- 用于評(píng)估SRK1001自適應(yīng)同步整流控制器、帶SR MOSFET的反激式轉(zhuǎn)換器演示板
- TS1935B 1.9A / 1.2MHz Boost DC-DC轉(zhuǎn)換器的典型應(yīng)用
- 900MHz全雙工無線發(fā)射器參考設(shè)計(jì)
- 口香糖電池充電
- 【訓(xùn)練營】無限鏡氛圍燈-807012A
- CN0140
- L99H02XP直流電機(jī)控制IC評(píng)估板
- 磁翻板液位計(jì)為什么會(huì)顯示虛假液位
- 50-基于51單片機(jī)的智能臺(tái)燈設(shè)計(jì)
- Arm進(jìn)軍汽車領(lǐng)域,初代開源云端框架已開啟下載
- 歐盟對(duì)大型科技企業(yè)監(jiān)管陷入僵局:內(nèi)部分歧大、規(guī)則模糊
- 蘋果與谷歌對(duì)智能手機(jī)市場(chǎng)控制力太強(qiáng)
- AVR單片機(jī)中斷實(shí)現(xiàn) ATmega16 INT ISR(INT0_vect)
- ARM微處理器的指令集概述(一)——ARM應(yīng)用系統(tǒng)開發(fā)詳解筆記
- 英特爾攜手智在一方打造智能制造工廠
- 移植內(nèi)核到s3c2440
- 天然氣流量計(jì)有幾種_天然氣流量計(jì)算方法
- 開啟軟件定義汽車全新未來征程,紅帽車用操作系統(tǒng)即將全面上市
- 車廠&零部件廠大咖說:48V先進(jìn)電源系統(tǒng)創(chuàng)新技術(shù)及產(chǎn)業(yè)化突破
- ROHM開發(fā)出適用于AI服務(wù)器48V電源熱插拔電路的100V功率MOSFET
- 納芯微高壓半橋驅(qū)動(dòng)NSD2622N:為E-mode GaN量身打造高可靠性、高集成度方案
- 3核A7+單核M0多核異構(gòu),米爾全新低功耗RK3506核心板發(fā)布
- 自動(dòng)化控制中智能技術(shù)的應(yīng)用研究
- OEM機(jī)器制造商利用仿真軟件提高效率
- 基于機(jī)器視覺的帶鋼焊縫定位
- 米爾RK3576核心板適配多種系統(tǒng),解鎖多樣化應(yīng)用
- 實(shí)時(shí)控制和通信領(lǐng)域的IT/OT融合如何推動(dòng)工業(yè)自動(dòng)化
- 美大學(xué)研發(fā)超高壓晶體管 可提高電動(dòng)車的續(xù)航能力和效率
- Syntiant:疫情擋不住AI芯片的熱潮
- 收獲菲律賓40億訂單,比亞迪從產(chǎn)品到戰(zhàn)略的轉(zhuǎn)型之路
- Covid-19讓熱成像探測(cè)器“紅”遍全球
- 英特爾與清華大學(xué)、中科院強(qiáng)強(qiáng)聯(lián)手,開啟5年自動(dòng)駕駛計(jì)劃
- 四個(gè)按鍵控制led位移
- 單片機(jī)蜂鳴器生日快樂歌
- 單片機(jī)10秒秒表
- 按鍵狀態(tài)led顯示
- 【12.7-12.13】一周大事件 | 東杰智能與啟征新能源簽訂2億元訂單;貴州茅臺(tái)斥資78.33億元加碼物流、包裝項(xiàng)目