Chinaunix首页 | 论坛 | 博客
  • 博客访问: 320897
  • 博文数量: 86
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 185
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-25 17:14
个人简介

代码才是最叼的

文章分类

全部博文(86)

文章存档

2019年(1)

2018年(1)

2017年(9)

2016年(19)

2015年(55)

2014年(1)

分类: 嵌入式

2017-01-05 20:59:50

工作中使用ublox模块获取时间,由于对时间卡的比较严格,出现了gps模块跳秒的情况,故作一番详细的研究;
过程中有三个时间GPSTime、BDTime、UTCTime,这三个时间的关系大家可以去百度,我就不详细的介绍了;主要我们经常使用的是UTC时间,UTC时间+时区时间就是localTime,在实用的过程中发现一上电过一会时间会晚1s或者2秒的情况,之前一直没找到原因,因为这个问题也费了不少周折,起初就没有王GPS模块上去考虑,最后实在是没有别的方向了,只能怀疑模块给的时间就有问题;通过查看手册和技术支持沟通,最终确定模块在冷启动的时候会发生跳秒的情况,也就是时间会变,在使用UTC时间时有个跳秒的有效判断位,但是由于我们一上电就要获取时间值,故不能等待那么长时间,通过沟通测试,终于有了方案:使用GPSTime和BDTime这两个时间不会跳变,GPSTime-闰秒时间就是UTC时间,北斗也同理。
     GPSTime和BDTime能读到一个星期数和这周的一个描述,然后通过儒略日方法计算就能换算为当地的年月日时分秒。
     
1.儒略日换算代码如下:
typedef struct
{
    u16 GpsWeeks;
    sl32 GpsMs;
    sl32 GpsSecned;    
    u8  GpsLeaps;
}T_GpsTimeDate;
T_GpsTimeDate gUbloxGpsTime;
这段代码是大家可以共用的,获取的星期数和秒数来转化年月日时分秒
/************************************************************************************/
typedef struct
{
    time_t time;
    double sec;
}gtime_t;

double gpst0[] = {1980, 1, 6, 0, 0, 0};
gtime_t epoch2time(const double * ep)
{
    const int doy[]={1,32,60,91,121,152,182,213,244,274,305,335};
    gtime_t time={0};
    int days, sec, year=(int)ep[0],mon=(int)ep[1],day=(int)ep[2];

    if (year < 1970 || 2099 < year || mon < 1 || 12 < mon)
    return time;
    /*leap year if year % 4 == 0 in 1901-2099*/
    days = (year - 1970) * 365 + (year - 1969)/4 + doy[mon-1] + day-2+(year%4==0&&mon>=3?1:0);
    sec = (int) floor(ep[5]);
    time.time = (time_t)days*86400+(int)ep[3]*3600+(int)ep[4]*60+sec;
    time.sec = ep[5]-sec;
    return time;
}


gtime_t gpst2time(int week, double sec)
{
    gtime_t t=epoch2time(gpst0);

    if (sec < -1E9||1E9 < sec)
    sec = 0.0;
    t.time+= 86400*7*week+(int)sec;
    t.sec=sec-(int)sec;

    return t;
}
/*************************************************************************************/
s32 gps_NAV_TimeGPS(s32 gps_gmt_offset,u32 leap_second)
{
    char data[] = {0xB5, 0x62, 0x01, 0x20, 0x00, 0x00, 0x21, 0x64};
    char dataRsp[BSP_DATARSP_BUF_LEN]={0};
    struct tm result;
    struct tm mytime;
    struct tm *pmytime;
    time_t  t_tick;
    s32 gpsOffset;
    s32 status;
    gtime_t GPSTime;
    gtime_t UTCTime;
    struct tm * gpstimeinfo;
    if((gps_gmt_offset > 720)||(gps_gmt_offset<-720))
    {
            printf("Input par is error! gps_gmt_offset = %d",gps_gmt_offset);
            return -1;
    }
    gpsOffset = gps_gmt_offset;
    memset(dataRsp,0,BSP_DATARSP_BUF_LEN);
    status = gpsExecCommand_UBlox(data, 8, dataRsp, 20+6);


    if(status==OK)
    {        
        //解析时间,加时区
        char *pchar = &dataRsp[6];//数据区
        //printf("pchar[11] = %d\n", pchar[11]);
        if((pchar[11]&0x03) == 0x03)//GPSTime valid
        {
            gUbloxGpsTime.GpsMs    = pchar[3]*0x1000000 + pchar[2]*0x10000 + pchar[1]*0x100 + pchar[0];
            gUbloxGpsTime.GpsWeeks = pchar[9]*0x100 + pchar[8]; //小端模式
            gUbloxGpsTime.GpsLeaps  = pchar[11];
            gUbloxGpsTime.GpsSecned = gUbloxGpsTime.GpsMs / 1000 - leap_second; 
            GPSTime = gpst2time(gUbloxGpsTime.GpsWeeks,gUbloxGpsTime.GpsSecned);
            gpstimeinfo = localtime(&GPSTime.time);
        }
        return status;   
}

s32 bd_NAV_TimeBD(s32 gps_gmt_offset,u32 leap_second)
{
    char data[] = {0xB5, 0x62, 0x01, 0x24, 0x00, 0x00, 0x21, 0x64};
    char dataRsp[BSP_DATARSP_BUF_LEN]={0};
    struct tm result;
    struct tm mytime;
    struct tm *pmytime;
    time_t  t_tick;
    s32 gpsOffset;
    s32 status;
    gtime_t GPSTime;
    gtime_t UTCTime;
    struct tm * gpstimeinfo;
    if((gps_gmt_offset > 720)||(gps_gmt_offset<-720))
    {
            printf("Input par is error! gps_gmt_offset = %d",gps_gmt_offset);
            return -1;
    }
    gpsOffset = gps_gmt_offset;    
    memset(dataRsp,0,BSP_DATARSP_BUF_LEN);
    status = gpsExecCommand_UBlox(data, 8, dataRsp, 20+6);


    if(status==OK)
    {            
        //解析时间,加时区
        char *pchar = &dataRsp[6];//数据区
        //printf("pchar[11] = %d\n", pchar[11]);
        if((pchar[15]&0x03) == 0x03)//GPSTime valid
        {
            gUbloxGpsTime.GpsMs    = pchar[3]*0x1000000 + pchar[2]*0x10000 + pchar[1]*0x100 + pchar[0];
            gUbloxGpsTime.GpsWeeks = pchar[13]*0x100 + pchar[12] + 1356; //小端模式     1356是和UTC差的星期数
            gUbloxGpsTime.GpsLeaps  = pchar[14];
            gUbloxGpsTime.GpsSecned = gUbloxGpsTime.GpsMs / 1000 - leap_second; 
            GPSTime = gpst2time(gUbloxGpsTime.GpsWeeks,gUbloxGpsTime.GpsSecned);
            gpstimeinfo = localtime(&GPSTime.time);
        }
            return status;   
}



阅读(7433) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~