/****************************************************************************** 版权所有: 文件名称: gprs.c 文件版本: 01.01 创建作者: 创建日期: 2012-8-17 功能说明: GRS模块 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include "head.h" #include "gps_uart.h" #include "my_rtc.h" #include "gps.h" #include "bspconfig.h" #if defined(ADD_ATGM366_GPS_FUN) || defined(DEV_GPS_ATGM366) || defined(DEV_GPS_ATGM332D) #define BYTE2LONG(p) ((long)(((p)[0] << 24) + ((p)[1] << 16) + ((p)[2] << 8) + (p)[3])) /*------------------------------ 全局变量 ------------------------------------- */ GpsNmeaRmcDataType GpsNmeaRmcData; u8 SendBuf[GPS_LINE_LEN / 2]; const GpsNmeaDataType GpsNmeaDataTbl[] = { {FALSE, "GGA"}, {FALSE, "GLL"}, {FALSE, "GSA"}, {FALSE, "GSV"}, {TRUE, "RMC"}, {FALSE, "VTG"}, {FALSE, "ZDA"}, {FALSE, "TXT"}, {FALSE, "ANT"}, {FALSE, "DHV"}, {FALSE, "GST"}, }; const char GpsNmeaCmdData[][50] = { {"$PCAS01,0*1C\r\n"}, {"$PCAS01,1*1D\r\n"}, {"$PCAS01,2*1E\r\n"}, {"$PCAS01,3*1F\r\n"}, {"$PCAS01,4*18\r\n"}, // 57600 {"$PCAS01,5*19\r\n"}, // {"$PCAS03,0,0,0,0,1,0,0,0,0,0,,,0,0*03\r\n"}, //配置只上发RMC指令 {"$PCAS03,0,0,0,4,1,0,0,0*07\r\n"}, // 配置发RMC、GSV指令 {"$PCAS04,3*1A\r\n"}, // 配置选择北斗和GPS导航系统 {"$PCAS02,1000*2E\r\n"}, // 更新频率为1HZ {"$PCAS10,3*1F\r\n"}, // 恢复出厂设置 {"$PCAS04,2*1B\r\n"}, // 单独选择北斗 {"$PCAS04,1*18\r\n"}, // 单独选择GPS }; const int GpsCommBuadrateTbl[] = { 4800, 9600, 19200, 38400, 57600, 115200}; /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ extern int rtc_to_timespec(struct rtc_time_t *p_rtc, struct timespec *p_ts); GPS_SYNC_DELAY gps_sync; extern unsigned int g_keep_alive_gps; /****************************************************************************** 函数名称: 函数版本: 01.01 创建作者: 创建日期: 函数说明: 参数说明: 返回值: 0: 成功 其它: 失败 修改记录: */ extern struct timespec g_sys_time; char gps_crc(const char *p, u8 length) { char crc = p[0]; u8 i; for (i = 1; i < length; i++) { crc ^= p[i]; } return crc; } void GPSCommInit(GPS_COMM *p, u8 chnl) // 初始化 { memset(p, 0, sizeof(GPS_COMM)); p->type = IEC_MODBUS_M; p->chnl = chnl; p->bData = false; // p->arrSendBuf=&g_tRsComm[chnl].sendbuf[0]; ResetUartGPSLink(p); // rt_printf("gps com init\r\n"); //TODO ygl - } void ResetUartGPSLink(GPS_COMM *p) // 重置 { p->cTypeCounter = GPS_FRAME_HEAD; p->cRecvCnt = 0; } void GPS_Recv(GPS_COMM *p, BYTE byRevData) { static unsigned char RecvCounter; if (p->bData) { p->cTypeCounter = GPS_FRAME_HEAD; return; } p->arrRecvBuf[p->cRecvCnt++] = byRevData; // 接收数据 switch (p->cTypeCounter) { case GPS_FRAME_HEAD: // if (byRevData == '$') // 开始符号 { // rt_printf("GPS_FRAME_HEAD\r\n"); p->cTypeCounter++; } else { ResetUartGPSLink(p); } break; case GPS_FRAME_DATA: if (byRevData == '*') // 数据结束段 { // rt_printf("GPS_FRAME_DATA\r\n"); RecvCounter = 0; p->cTypeCounter = GPS_FRAME_TAIL; // p->nTypeCounter=GPS_FRAME_TAIL; } else if (p->cRecvCnt > GPS_UART_MAX_LEN) // 数据异常保护后续需要修改 // else if(p->nRecvCnt>GPS_UART_MAX_LEN) //数据异常保护后续需要修改 { ResetUartGPSLink(p); } break; case GPS_FRAME_TAIL: if (byRevData == '\n') // 回车符 { p->cTypeCounter = GPS_FRAME_HEAD; // p->nTypeCounter=GPS_FRAME_HEAD; p->bData = true; // rt_printf("GPS_FRAME_TAIL\r\n"); // rt_printf("data: %s\r\n", p->arrRecvBuf); } else if (++RecvCounter >= 4) { ResetUartGPSLink(p); } break; default: ResetUartGPSLink(p); break; } } void GPS_Timer(void) { u8 i; // TODO 待处理秒脉冲 by ewen // if(g_clock_mode != CLOCK_MODE_GPS_SECOND) // { // if(soe_check(EV_GPS_ADJUST_TIME)==true) // { // soe_record_ev(EV_GPS_ADJUST_TIME,0, 0,0,0 ); // } return; // } if (ustimer_delay_origin2(&GpsNmeaRmcData.data_vaild_time, 60 * tRunPara.GPS_switch_delay * USTIMER_SEC)) { GpsNmeaRmcData.data_vaild = 0; // TODO by ewen // if(soe_check(EV_GPS_ADJUST_TIME)==true) // { // soe_record_ev(EV_GPS_ADJUST_TIME,0, 0,0,0 ); // } } if (ustimer_delay_origin2(&GpsNmeaRmcData.gsv_time, 30 * USTIMER_SEC)) { GpsNmeaRmcData.bd_sv_num = 0; GpsNmeaRmcData.gp_sv_num = 0; } for (i = 0; i < GPS_NUM_MAX; i++) { if (ustimer_delay_origin2(&GpsNmeaRmcData.bd_online_time[i], 180 * USTIMER_SEC)) { GpsNmeaRmcData.bd_gsv[i].valid = 0; } if (ustimer_delay_origin2(&GpsNmeaRmcData.gp_online_time[i], 180 * USTIMER_SEC)) { GpsNmeaRmcData.gp_gsv[i].valid = 0; } } if (GpsNmeaRmcData.data_vaild == 0) { #ifdef GPS_ALIVE_SOE if (soe_check(EV_GPS_ALIVE) == true) { soe_record_ev(EV_GPS_ALIVE, 0, 0, 0, 0); } #endif GpsNmeaRmcData.bd_sv_num = 0; GpsNmeaRmcData.gp_sv_num = 0; } #ifdef GPS_NUM_SHOW g_sw_pub.ac_in[PUB_AC_IN_GPS_NUM] = (qs16)((GpsNmeaRmcData.bd_sv_num + GpsNmeaRmcData.gp_sv_num) * Q16_BASE); #elif defined BD_GPS_NUM g_sw_pub.ac_in[PUB_AC_IN_BD_NUM] = (qs16)(GpsNmeaRmcData.bd_sv_num * Q16_BASE); g_sw_pub.ac_in[PUB_AC_IN_GPS_NUM] = (qs16)(GpsNmeaRmcData.gp_sv_num * Q16_BASE); #endif } void GPS_Comm_App(GPS_COMM *p) { #ifdef ADD_PLUSE_OUTPUT GenerateSecdPluse(); #endif GPS_Timer(); // if(!g_clock_mode_gps) // return; GpsModuleFunInit(p); if (GpsNmeaRmcData.DataValidFlag == 'S') // soeê??t { struct rtc_time_t rtc; // TODO by ewen // 此处写RTC,但是在设置系统时间时已交由系统写入此处不用再写 // soe_record_opt(EV_GPS_ADJUST_TIME,GpsNmeaRmcData.MsOffset); // if(soe_check(EV_GPS_ADJUST_TIME)==false) // { // soe_record_ev(EV_GPS_ADJUST_TIME,1, 0,0,0 ); // } GpsNmeaRmcData.gps_soe_time = ustimer_get_origin(); #if (0) timespec_to_rtc(GpsNmeaRmcData.ts, &rtc, 1); if (rtc_time_write(&rtc) != 0) // { rt_printf("gps_fun:rtc_time_write err.\r\n"); return; } #endif GpsNmeaRmcData.DataValidFlag = '0'; // rt_printf_time("gps adjust,time=%d\r\n",GpsNmeaRmcData.MsOffset); } if (p->bData) // TODO: add vaild data control { GpsRecvDataFrameHandler(p); p->bData = false; p->cRecvCnt = 0; } } int _pow10(unsigned char num) { int val = 1; while (num--) val *= 10; return val; } unsigned char *GetParamDataValue(unsigned char *pos, float *data) //, , { unsigned char count, IntNum = 0, DecNum = 0, len, num; unsigned char *p = pos, *p1; int value; p++; // jump the first signed // len=(unsigned char*)strstr(p,",")-p; len = (unsigned char *)strchr(p, ',') - p; if ((len <= 0) || len > 15) { *data = 0; // valid data return pos + len + 1; } p1 = p; for (count = 0; count < len; count++, p1++) { if (*p1 == '.') // 取到小数点位置 { DecNum = len - IntNum - 1; break; } IntNum++; } // rt_printf("len=%d,InterNum=%d,DecNum=%d,x=%d\r\n",len,IntNum,DecNum,pow10(IntNum)); value = 0; while (IntNum) // get the part of Int { num = *p++ - 0x30; // 必须为0x30-0x39 value += num * _pow10(IntNum - 1); IntNum--; }; *data = (float)value; if (DecNum) { p++; // point count = DecNum; value = 0; while (count) // get the part of dec { num = *p++ - 0x30; // 必须为0x30-0x39 value += num * _pow10(count - 1); count--; }; *data += (float)value / _pow10(DecNum); } return pos + len + 1; } // 取字符 unsigned char *GetParamDataChar(unsigned char *pos, unsigned char *data, int max_len) { unsigned char len; unsigned char *p = pos; // int value; p++; // jump the first signed // len=(unsigned char*)strstr(p,",")-p; len = (unsigned char *)strchr(p, ',') - p; // rt_printf("len=%d\r\n",len); if ((len <= 0) || len > max_len) { *data = 0; // valid data return pos + len + 1; } memcpy(data, p, len); return pos + len + 1; } char *gps_char_data_get(char *pos, char end, int *data) { unsigned char len; len = strchr(pos, end) - pos; if ((len <= 0) || len > 15) { *data = -1; // valid data return pos + len + 1; } *data = atoi(pos); return pos + len + 1; } int CheckDataFrameVaild(unsigned char *pos) { unsigned char *p = pos, tmp; volatile unsigned char AddValue = 0; // if(strstr(p,"*")==NULL) if (strchr(p, '*') == NULL) return -1; if (*p++ != '$') return -1; while (*p != '*') AddValue ^= *p++; p++; //* tmp = (*p++ - 0x30) << 4; tmp |= (*p - 0x30) << 0; rt_printf("tmp=0x%02X,AddValue=0x%02X\r\n", tmp, AddValue); if (tmp != AddValue) { rt_printf("tmp=%s\r\n", pos); return 0; } return 1; } void UtcTimeToSysTime(struct rtc_time_t *rtc, GpsNmeaRmcDataType *utc, u8 opt) { char *p = &utc->Date[0]; rtc->day = (*p - 0x30) * 10 + *(p + 1) - 0x30; p += 2; rtc->month = (*p - 0x30) * 10 + *(p + 1) - 0x30; p += 2; rtc->year = (*p - 0x30) * 10 + *(p + 1) - 0x30; p += 2; p = &utc->UtcTime[0]; rtc->hour = (*p - 0x30) * 10 + *(p + 1) - 0x30; p += 2; rtc->min = (*p - 0x30) * 10 + *(p + 1) - 0x30; p += 2; if (opt == 1) rtc->ms = ((*p - 0x30) * 10 + *(p + 1) - 0x30) * 1000 + (*(p + 3) - 0x30) * 100 + (*(p + 4) - 0x30) * 10 + *(p + 5) - 0x30; else // 取S rtc->ms = ((*p - 0x30) * 10 + *(p + 1) - 0x30) * 1000; // rt_printf("year=%d,month=%d,day=%d,hour=%d,min=%d,ms=%d\r\n",rtc->year,rtc->month,rtc->day,rtc->hour,rtc->min,rtc->ms); } void gps_pluse_clear(void) { GpsNmeaRmcData.pluse_count = 0; } int GpsAdjustTimeFun(struct rtc_time_t *psrtc) // 本函数只能被捕获中断服务函数调用 { // static u8 counter=0; struct timespec ts; int res = FALSE; u64 MsOffset; static u8 power_on = 1; #ifdef CN_AREA_GUOWANG_FBC GpsNmeaRmcData.data_vaild_time = ustimer_get_origin(); GpsNmeaRmcData.data_vaild = 1; if (GpsNmeaRmcData.slave_vaild == 0) return res; #endif if (++GpsNmeaRmcData.pluse_count <= tRunPara.GPS_sync_time) // 根据对时间隔判断修正 { // GpsNmeaRmcData.DataValidFlag='0'; return res; } GpsNmeaRmcData.wait_sync = 0; // counter=0; #ifdef CN_AREA_GUOWANG_FBC GpsNmeaRmcData.slave_vaild = 0; #else if (GpsNmeaRmcData.DataValidFlag != 'Y' || !tRunPara.bGPS_sync_enable) return res; #endif GpsNmeaRmcData.DataValidFlag = '0'; // rtc_to_timespec(psrtc,&ts); #ifdef CN_AREA_GUOWANG_FBC GpsNmeaRmcData.ts.tv_sec += tRunPara.GPS_sync_time + 1; GpsNmeaRmcData.ts.tv_nsec = 20 * 1000 + 1000 * 1000; // 补偿20us + 1ms #else GpsNmeaRmcData.ts.tv_sec += 1; // tRunPara.GPS_sync_time + 1; //TODO EWEN GpsNmeaRmcData.ts.tv_nsec = 20 * 1000; // 补偿20us #ifdef KP_GPS_TEST GpsNmeaRmcData.ts.tv_sec += 4; #endif #endif gps_get_time(&ts); // 当前系统的精准时间带ms的 if (GpsNmeaRmcData.ts.tv_sec <= ts.tv_sec) // 系统时间超前 MsOffset = (ts.tv_sec - GpsNmeaRmcData.ts.tv_sec) * 1000 + ts.tv_nsec / 1000000; else // 系统时间滞后 MsOffset = (GpsNmeaRmcData.ts.tv_sec - ts.tv_sec) * 1000 - ts.tv_nsec / 1000000; if (MsOffset >= 5 || power_on) // 5ms { timespec_to_rtc(GpsNmeaRmcData.ts, psrtc, 1); // D£ê± sys_time_set(psrtc); if (MsOffset >= 1000 || power_on) // 1Sò?é??ó2?????SOE { power_on = 0; GpsNmeaRmcData.DataValidFlag = 'S'; // SOE±ê?? GpsNmeaRmcData.MsOffset = MsOffset; } else GpsNmeaRmcData.DataValidFlag = '0'; // rt_printf("set time=%d\r\n",MsOffset); //校准 res = TRUE; } else GpsNmeaRmcData.DataValidFlag = '0'; return res; } float gps_angle_calc(float value) { float tmp_d, tmp_m, tmp_dot; u32 tmp; tmp = (u32)value; tmp_d = value; tmp_m = (float)(tmp_d - tmp); tmp_dot = tmp_m * 100.0f / 60.0f; tmp = value; return (float)(tmp + tmp_dot); } void gps_dms_calc(float value, u32 *d, u32 *m, float *s) { u32 tmp1, tmp2; tmp1 = (u32)value; tmp2 = (u32)value / 100; *d = tmp2; *m = (u32)((value / 100.0f - tmp2) * 100.0f); *s = (float)(value - tmp1) * 60.0f; } // GPS接收数据解析 int GpsRecvDataFrameHandler(GPS_COMM *data) { static unsigned char LocalUtcTime[11]; unsigned char *p = &data->arrRecvBuf[0]; unsigned char *p1 = &data->arrRecvBuf[0]; u8 msg_no, valid_flag; if ((ustimer_delay_origin2(&data->recv_wait_time, 3 * USTIMER_SEC) <= 0) && !data->recv_handle) { return FALSE; } data->recv_handle = 1; if (data->GpsModuleRunStep == GPS_MODULE_INIT_STEP) //??????????????????????????? data->GpsModuleRunStep = GPS_MODULE_NORMAL_RUN_STEP; else if (data->GpsModuleRunStep == GPS_MODULE_BAUD_CHECK_STEP) // 查找到合适的波特率 data->GpsModuleRunStep = GPS_MODULE_BAUD_SET_STEP; // if(!CheckDataFrameVaild(p)) // return; // $GNRMC,051033.000,A,2222.12622,N,11329.24936,E,0.00,0.00,050825,,,A*79 if (strstr(p1, "RMC") != NULL) { p = strstr(p1, "RMC"); memcpy(&GpsNmeaRmcData.SingleType, p1 + 1, 2); // 记录是BD还是GN,即北斗还是GPS GpsNmeaRmcData.SingleType[p - p1] = 0; p += 3; p = GetParamDataChar(p, &GpsNmeaRmcData.UtcTime[0], sizeof(GpsNmeaRmcData.UtcTime)); p = GetParamDataChar(p, &valid_flag, sizeof(valid_flag)); // 数据有效标志 if (valid_flag != 'A') { GpsNmeaRmcData.bd_sv_num = 0; GpsNmeaRmcData.gp_sv_num = 0; g_sw_pub.ac_in[PUB_AC_GPS_NUM_SV] = 0; #ifdef GPS_NUM_SHOW g_sw_pub.ac_in[PUB_AC_IN_GPS_NUM] = (qs16)((GpsNmeaRmcData.bd_sv_num + GpsNmeaRmcData.gp_sv_num) * Q16_BASE); #elif defined BD_GPS_NUM g_sw_pub.ac_in[PUB_AC_IN_BD_NUM] = (qs16)(GpsNmeaRmcData.bd_sv_num * Q16_BASE); g_sw_pub.ac_in[PUB_AC_IN_GPS_NUM] = (qs16)(GpsNmeaRmcData.gp_sv_num * Q16_BASE); #endif return FALSE; } GpsNmeaRmcData.data_vaild_time = ustimer_get_origin(); GpsNmeaRmcData.data_vaild = 1; #ifdef GPS_ALIVE_SOE if (soe_check(EV_GPS_ALIVE) == false) { soe_record_ev(EV_GPS_ALIVE, 1, 0, 0, 0); } #endif if (GpsNmeaRmcData.wait_sync) { // return FALSE;//临时屏蔽 by ewen } GpsNmeaRmcData.DataValidFlag = valid_flag; p = GetParamDataValue(p, &GpsNmeaRmcData.Latitude); // 纬度 p = GetParamDataChar(p, &GpsNmeaRmcData.LatitudeDir, sizeof(GpsNmeaRmcData.LatitudeDir)); // 纬度方位 p = GetParamDataValue(p, &GpsNmeaRmcData.Longtitude); // 经度 p = GetParamDataChar(p, &GpsNmeaRmcData.LongtitudeDir, sizeof(GpsNmeaRmcData.LongtitudeDir)); // 经度方位 p = GetParamDataValue(p, &GpsNmeaRmcData.Spd); // 对地速度 p = GetParamDataValue(p, &GpsNmeaRmcData.cog); // 对地真航向 p = GetParamDataChar(p, &GpsNmeaRmcData.Date[0], sizeof(GpsNmeaRmcData.Date)); // 日期 gps_pluse_clear(); GpsNmeaRmcData.wait_sync = 1; memset(&GpsNmeaRmcData.UtcTime[8], '0', 3); // 去除毫秒 GPS模块机制 // if(memcmp(GpsNmeaRmcData.UtcTime,LocalUtcTime,sizeof(GpsNmeaRmcData.UtcTime))) //若gps第一次获取到时间或者1s内第一次获取到时间则有效或者是GPS断线后第一次获取的时间 { struct rtc_time_t rtc; UtcTimeToSysTime(&rtc, &GpsNmeaRmcData, 0); // 先将BD的UTC时间转为RTC rtc_to_timespec(&rtc, &GpsNmeaRmcData.ts); // 再将RTC转为timespec时间(主要用timespec) GpsNmeaRmcData.ts.tv_sec += 8 * 60 * 60; // UTC->BEIJING GpsNmeaRmcData.DataValidFlag = 'Y'; // zhl add if (gps_time_valid == 0) { // printf("GpsNmeaRmcData.ts.tv_sec:%lld\n", GpsNmeaRmcData.ts.tv_sec); shared_gps_time = GpsNmeaRmcData.ts.tv_sec; gps_time_valid = 1; } // rt_printf("gene_flag=%d\r\n",GpsNmeaRmcData.DataValidFlag); memcpy(GpsNmeaRmcData.UtcTime, LocalUtcTime, sizeof(GpsNmeaRmcData.UtcTime)); // rt_printf("recv gps uart data!"); } gps_dms_calc(GpsNmeaRmcData.Longtitude, &GpsNmeaRmcData.Longtitude_dd, &GpsNmeaRmcData.Longtitude_mm, &GpsNmeaRmcData.Longtitude_ss); gps_dms_calc(GpsNmeaRmcData.Latitude, &GpsNmeaRmcData.Latitude_dd, &GpsNmeaRmcData.Latitude_mm, &GpsNmeaRmcData.Latitude_ss); #ifndef GPS_JWD_SPLIT g_sw_pub.ac_in[PUB_AC_GPS_LONGITUDE] = (qs16)(gps_angle_calc(GpsNmeaRmcData.Longtitude / 100.0f) * Q16_BASE); g_sw_pub.ac_in[PUB_AC_GPS_LATITUDE] = (qs16)(gps_angle_calc(GpsNmeaRmcData.Latitude / 100.0f) * Q16_BASE); #else g_sw_pub.ac_in[PUB_AC_GPS_LONGITUDE_D] = GpsNmeaRmcData.Longtitude_dd * Q16_BASE; g_sw_pub.ac_in[PUB_AC_GPS_LONGITUDE_M] = GpsNmeaRmcData.Longtitude_mm * Q16_BASE; g_sw_pub.ac_in[PUB_AC_GPS_LONGITUDE_S] = GpsNmeaRmcData.Longtitude_ss * Q16_BASE; g_sw_pub.ac_in[PUB_AC_GPS_LATITUDE_D] = GpsNmeaRmcData.Latitude_dd * Q16_BASE; g_sw_pub.ac_in[PUB_AC_GPS_LATITUDE_M] = GpsNmeaRmcData.Latitude_mm * Q16_BASE; g_sw_pub.ac_in[PUB_AC_GPS_LATITUDE_S] = GpsNmeaRmcData.Latitude_ss * Q16_BASE; #endif } else if (strstr(p1, "GSV") != NULL) { if (strstr(p1, "BD") != NULL) { u8 i; p = p1 + 7; p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_msg_num); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_msg_no); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_sv_num); if (strstr(GpsNmeaRmcData.SingleType, "BD") != NULL) { g_sw_pub.ac_in[PUB_AC_GPS_NUM_SV] = (qs16)(GpsNmeaRmcData.bd_sv_num * Q16_BASE); } if (GpsNmeaRmcData.bd_sv_num > GPS_NUM_MAX) return FALSE; GpsNmeaRmcData.gsv_time = ustimer_get_origin(); msg_no = GpsNmeaRmcData.bd_msg_no - 1; if (GpsNmeaRmcData.bd_msg_no * 4 < GPS_NUM_MAX) { for (i = 0; i < 4; i++) { p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_gsv[msg_no * 4 + i].id); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_gsv[msg_no * 4 + i].ele); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_gsv[msg_no * 4 + i].az); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.bd_gsv[msg_no * 4 + i].cn0); GpsNmeaRmcData.bd_gsv[msg_no * 4 + i].valid = 1; GpsNmeaRmcData.bd_online_time[msg_no * 4 + i] = ustimer_get_origin(); } } } else if (strstr(p1, "GP") != NULL) { u8 i; p = p1 + 7; p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_msg_num); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_msg_no); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_sv_num); // rt_printf("GPS卫星:%d台\r\n", GpsNmeaRmcData.gp_sv_num); if (GpsNmeaRmcData.gp_sv_num > GPS_NUM_MAX) return FALSE; if (strstr(GpsNmeaRmcData.SingleType, "GN") != NULL) { g_sw_pub.ac_in[PUB_AC_GPS_NUM_SV] = (qs16)(GpsNmeaRmcData.gp_sv_num * Q16_BASE); } GpsNmeaRmcData.gsv_time = ustimer_get_origin(); msg_no = GpsNmeaRmcData.gp_msg_no - 1; if (GpsNmeaRmcData.gp_msg_no * 4 < GPS_NUM_MAX) { for (i = 0; i < 4; i++) { p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_gsv[msg_no * 4 + i].id); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_gsv[msg_no * 4 + i].ele); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_gsv[msg_no * 4 + i].az); p = gps_char_data_get(p, ',', &GpsNmeaRmcData.gp_gsv[msg_no * 4 + i].cn0); GpsNmeaRmcData.gp_gsv[msg_no * 4 + i].valid = 1; GpsNmeaRmcData.gp_online_time[msg_no * 4 + i] = ustimer_get_origin(); } } } } else { #if 0 if((data->GpsModuleRunStep==GPS_MODULE_NORMAL_RUN_STEP)&&(strstr(p,"TXT")==NULL)) //正常运行后若发现收到其他数据则下发配置指令 #else if ((data->GpsModuleRunStep == GPS_MODULE_NORMAL_RUN_STEP) && (strstr(p, "GSV") == NULL)) #endif { data->GpsModuleRunStep = GPS_MODULE_NEMA_SEL_STEP; // 若配置不成功可循环配置 } } return TRUE; } void GpsSwitchBaudrateFun(GPS_COMM *data, GpsCtrlCmdEnumType GpsCtrlCmd) { int ret; u8 chnl = data->chnl; GpsModuleRunStepEnum LocalGpsModuleRunStep = data->GpsModuleRunStep; memset(&g_tRsComm[chnl], 0, sizeof(g_tRsComm[chnl])); g_tRsComm[chnl].ptBuf = (BYTE *)&g_tRsIEC[chnl]; GPSCommInit((GPS_COMM *)g_tRsComm[chnl].ptBuf, chnl); // uart_open(UART_CHANNEL[chnl],tRunPara.tUartPara[i].wBaud,tRunPara.tUartPara[i].wParity); #if defined(BSP_DTU4) uart_open(UART_CHANNEL[chnl], GpsCommBuadrateTbl[GpsCtrlCmd], PARITY_NONE1); #else ret = uart_open(UART_CHANNEL[chnl], GpsCommBuadrateTbl[GpsCtrlCmd], PARITY_NONE_1); if (ret < 0) { printf("%s: outside uart %d open failed!\n", __FUNCTION__, UART_CHANNEL[chnl]); } #endif RS_Ena_Init(chnl); RS_Recv_Enable(chnl); data->GpsModuleRunStep = LocalGpsModuleRunStep; // 串口初始化 存储的数据都被清0 // rt_printf("Set baud:%d\r\n",GpsCommBuadrateTbl[GpsCtrlCmd]); } void GpsModuleFunInit(GPS_COMM *data) { static GpsCtrlCmdEnumType GpsSwitchBaudrate; static uint32_t us0 = 0; u8 count, chnl = data->chnl, i; int ret; if (us0 == 0) us0 = ustimer_get_origin(); if (ustimer_delay_origin2(&us0, USTIMER_SEC * 2) > 0) { // rt_printf("Step:%d\r\n",data->GpsModuleRunStep); switch (data->GpsModuleRunStep) { case GPS_MODULE_INIT_STEP: data->GpsModuleRunStep++; GpsSwitchBaudrate = GPS_SET_BUADRATE1_CMD; break; case GPS_MODULE_BAUD_CHECK_STEP: GpsSwitchBaudrateFun(data, GpsSwitchBaudrate); if (++GpsSwitchBaudrate > GPS_SET_BUADRATE5_CMD) GpsSwitchBaudrate = GPS_SET_BUADRATE0_CMD; // data->GpsModuleRunStep=GPS_MODULE_BAUD_SET_STEP; break; case GPS_MODULE_BAUD_SET_STEP: for (count = 0; count < sizeof(GpsCommBuadrateTbl) / 4; count++) { if (tRunPara.tUartPara[data->chnl].dBaud == GpsCommBuadrateTbl[count]) break; } if (count == sizeof(GpsCommBuadrateTbl) / 4) ; // ERROR else { GPS_Comm_Send(data, (char *)GpsNmeaCmdData[count], sizeof(GpsNmeaCmdData[count])); // 根据定值配置模块的波特率 } data->GpsModuleRunStep++; break; case GPS_MODULE_BAUD_FINISH_STEP: // 找到合适的波特率 #if 1 memset(&g_tRsComm[chnl], 0, sizeof(g_tRsComm[chnl])); g_tRsComm[chnl].ptBuf = (BYTE *)&g_tRsIEC[chnl]; GPSCommInit((GPS_COMM *)g_tRsComm[chnl].ptBuf, chnl); // 运行步骤恢复初始状态 ret = uart_open(UART_CHANNEL[chnl], tRunPara.tUartPara[chnl].dBaud, tRunPara.tUartPara[chnl].wParity); if (ret < 0) { printf("%s: outside uart %d open failed!\n", __FUNCTION__, UART_CHANNEL[chnl]); } RS_Ena_Init(chnl); RS_Recv_Enable(chnl); #endif GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_UPLOAD_RMC_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_UPLOAD_RMC_CMD])); // rt_printf("GPS_MODULE_BAUD_FINISH_STEP.\r\n"); data->GpsModuleRunStep = GPS_MODULE_UPDATE_FREQ_STEP; // GPS_MODULE_NORMAL_RUN_STEP; break; case GPS_MODULE_NEMA_SEL_STEP: // rt_printf("GPS_MODULE_NEMA_SEL_STEP = %d.\r\n", sizeof(GpsNmeaCmdData[GPS_SEL_UPLOAD_RMC_CMD])); GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_UPLOAD_RMC_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_UPLOAD_RMC_CMD])); data->GpsModuleRunStep++; break; case GPS_MODULE_NAVI_SYS_STEP: // rt_printf("GPS_MODULE_NAVI_SYS_STEP.\r\n"); GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_NAVI_SYS_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_NAVI_SYS_CMD])); data->GpsModuleRunStep = GPS_MODULE_NORMAL_RUN_STEP; break; case GPS_MODULE_UPDATE_FREQ_STEP: // rt_printf("GPS_MODULE_UPDATE_FREQ_STEP.\r\n"); GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_UPDATE_FREQ_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_UPDATE_FREQ_CMD])); data->GpsModuleRunStep++; break; case GPS_MODULE_SYS_STEP: if (tRunPara.GPS_Mode == 1) // 北斗 { rt_printf("选择北斗系统.\r\n"); GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_BD_SYS_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_BD_SYS_CMD])); } else if (tRunPara.GPS_Mode == 2) // GPS { rt_printf("选择GPS系统.\r\n"); GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_GPS_SYS_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_GPS_SYS_CMD])); } else { rt_printf("选择北斗/GPS系统.\r\n"); GPS_Comm_Send(data, (char *)GpsNmeaCmdData[GPS_SEL_NAVI_SYS_CMD], sizeof(GpsNmeaCmdData[GPS_SEL_NAVI_SYS_CMD])); } data->GpsModuleRunStep++; GpsNmeaRmcData.bd_sv_num = 0; GpsNmeaRmcData.gp_sv_num = 0; for (i = 0; i < GPS_NUM_MAX; i++) { GpsNmeaRmcData.bd_gsv[i].valid = 0; GpsNmeaRmcData.gp_gsv[i].valid = 0; } data->recv_wait_time = ustimer_get_origin(); data->recv_handle = 0; break; case GPS_MODULE_NORMAL_RUN_STEP: default: break; } } } void GpsSendBaudrateCmd(GPS_COMM *p) { u8 i = 0; char *ptr = &SendBuf[0]; // memset(ptr,'A',20); // ptr+=20; //*ptr++='\r'; //*ptr++='\n'; ptr[i++] = '$'; #if 0 // xxxxxx 20220920 add 此函数没有用上,消除警告 GPS_Comm_Send(p,ptr-22,22); #endif } void GPS_Comm_Send(GPS_COMM *p, char *data, unsigned char datalen) // 发送命令 { unsigned char *ptr = &g_tRsComm[p->chnl].sendbuf[0]; *ptr++ = datalen; // rt_printf("TX:%s\r\n",data); memcpy(ptr, data, datalen); g_tRsComm[p->chnl].nSendCnt = 1; // 第一个字节为长度 g_tRsComm[p->chnl].bSend = TRUE; } #if 0 void GenerateSecdPluse(void) { static uint32_t us0=0; static u8 state=0; if(us0==0) us0=ustimer_get_origin(); switch(state) { case 0: if(ustimer_delay_origin2(&us0,USTIMER_MS*600)>0) { GPIO_KOUT0_OFF(); GPIO_KOUT1_OFF(); state=1; rt_printf("high=%d\r\n",ustimer_get_origin()); } break; case 1: if(ustimer_delay_origin2(&us0,USTIMER_MS*50)>0) { GPIO_KOUT0_ON(); GPIO_KOUT1_ON(); state=0; rt_printf("low=%d\r\n",ustimer_get_origin()); } break; default: break; } } #endif char gps_data_valid_get(void) { return GpsNmeaRmcData.data_vaild; } void gps_info_printf(void) { struct rtc_time_t rtc; u16 i; rt_printf("GPS串口数据:"); if (gps_data_valid_get() == 'A' || gps_data_valid_get() == 1) { rt_printf("\r\n"); rt_printf(" 系统:%s\r\n", GpsNmeaRmcData.SingleType); timespec_to_rtc(GpsNmeaRmcData.ts, &rtc, 1); rt_printf(" 时间:%04d-%02d-%02d,%02d:%02d:%02d.%03d\r\n", 2000 + rtc.year, rtc.month, rtc.day, rtc.hour, rtc.min, rtc.ms / 1000, rtc.ms % 1000); rt_printf(" 经度:%f°(%d°%d′%f″)\r\n", gps_angle_calc(GpsNmeaRmcData.Longtitude / 100.0f), GpsNmeaRmcData.Longtitude_dd, GpsNmeaRmcData.Longtitude_mm, GpsNmeaRmcData.Longtitude_ss); rt_printf(" 纬度:%f°(%d°%d′%f″)\r\n", gps_angle_calc(GpsNmeaRmcData.Latitude / 100.0f), GpsNmeaRmcData.Latitude_dd, GpsNmeaRmcData.Latitude_mm, GpsNmeaRmcData.Latitude_ss); rt_printf("==============================================\r\n"); if (GpsNmeaRmcData.bd_sv_num > 0) { rt_printf("北斗卫星:%d台\r\n", GpsNmeaRmcData.bd_sv_num); for (i = 0; i < GPS_NUM_MAX; i++) { if ((GpsNmeaRmcData.bd_gsv[i].valid == 1) && (GpsNmeaRmcData.bd_gsv[i].id > 0)) { if (GpsNmeaRmcData.bd_gsv[i].id > 0) rt_printf(" [卫星编号:%d ", GpsNmeaRmcData.bd_gsv[i].id); else rt_printf(" [卫星编号:- "); if (GpsNmeaRmcData.bd_gsv[i].ele > 0) rt_printf("仰角: %d ", GpsNmeaRmcData.bd_gsv[i].ele); else rt_printf("仰角: - "); if (GpsNmeaRmcData.bd_gsv[i].az > 0) rt_printf("方位角: %d ", GpsNmeaRmcData.bd_gsv[i].az); else rt_printf("方位角: - "); if (GpsNmeaRmcData.bd_gsv[i].cn0 > 0) rt_printf("载噪比: %d]\r\n", GpsNmeaRmcData.bd_gsv[i].cn0); else rt_printf("载噪比: -]\r\n"); } } } else { rt_printf("北斗卫星:-\r\n"); } rt_printf("==============================================\r\n"); if (GpsNmeaRmcData.gp_sv_num > 0) { rt_printf("GPS卫星:%d台\r\n", GpsNmeaRmcData.gp_sv_num); for (i = 0; i < GPS_NUM_MAX; i++) { if ((GpsNmeaRmcData.gp_gsv[i].valid == 1) && (GpsNmeaRmcData.gp_gsv[i].id > 0)) { if (GpsNmeaRmcData.gp_gsv[i].id > 0) rt_printf(" [卫星编号:%d ", GpsNmeaRmcData.gp_gsv[i].id); else rt_printf(" [卫星编号:- "); if (GpsNmeaRmcData.gp_gsv[i].ele > 0) rt_printf("仰角: %d ", GpsNmeaRmcData.gp_gsv[i].ele); else rt_printf("仰角: - "); if (GpsNmeaRmcData.gp_gsv[i].az > 0) rt_printf("方位角: %d ", GpsNmeaRmcData.gp_gsv[i].az); else rt_printf("方位角: - "); if (GpsNmeaRmcData.gp_gsv[i].cn0 > 0) rt_printf("载噪比: %d]\r\n", GpsNmeaRmcData.gp_gsv[i].cn0); else rt_printf("载噪比: -]\r\n"); } } } else { rt_printf("GPS卫星:-\r\n"); } } else if (gps_data_valid_get() == 'V') { rt_printf("\r\n"); rt_printf(" 系统:无效\r\n"); rt_printf(" 时间:无效\r\n"); rt_printf(" 经度:无效\r\n"); rt_printf(" 纬度:无效\r\n"); } else { rt_printf("无\r\n"); } } int is_gps_alive(void) { return 0; // tRunPara.GPS_sync_enable && GpsNmeaRmcData.data_vaild;//TODO EWEN } // 从机时间同步 int gps_slave_sync(struct timespec *ts) { if (tRunPara.bGPS && GpsNmeaRmcData.data_vaild) // 打开秒脉冲对时 { gps_pluse_clear(); GpsNmeaRmcData.ts = *ts; GpsNmeaRmcData.slave_vaild = 1; return 1; } return 0; } void gps_init_step_set(u8 step) { u8 i; for (i = 0; i < CFG_UART_NUM_MAX; i++) { // ???????,?? if (UART_CHANNEL[i] < 0) { continue; } if (tRunPara.tUartPara[i].wProtocol == PROTOCOL_GPS) { ((GPS_COMM *)g_tRsComm[i].ptBuf)->GpsModuleRunStep = step; } } } #endif