MTK基站定位

$GPGGA,hhmmss.ssss,ddmm.mmmm,a,dddmm.mmmm,a,x,xx,x.x,x.x,M,,M,x.x,xxxx*CS
$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F

0.$GPGGA 语句ID 表明该语句为Global Positioning System Fix Data(GGA)GPS定位信息
1.UTC时间,hhmmss.ssss,时分秒格式    092204.999
2.纬度 ddmm.mmmm,度分格式(前导位数不足则补0) 4250.5589
3.纬度 N 北纬  S 南纬                          S
4.经度 dddmm.mmmm,度分格式(前导位数不足则补0) 14718.5084
5.经度 经度 E 东经  W 西经                     E
6.GPS状态,0=未定位 1=非差分定位 2=差分定位 3=无效PPS 6=正在估算  1
7.正在使用的卫星数量(00--12)                          04
8.HDOP水平精度因子(0.5--99.9)                         24.4
  PDOP 图形强度因子
  HDOP 平面强度因子
  VDOP 高程强度因子
  HDOP是描述水平坐标精度的误差程度,值为纬度和经度误差平方和的开根号值,所以最准确的时候

HDOP近似于1,一般来说大于6,就表示误差比较大。
  PDOP是指位置精度强弱度(0.5--99.9);为纬度、经度和高程等误差平方和的开根号值,所以Pdop的

平方 =Hdop 的平方 +Vdop 的平方。具体含义:归因于卫星的几何分布,天空中卫星分布程度越好,定

位精度越高(数值越小精度越高)。
9.地球椭球面相对大地水准面的高度    19.7
10.海拔高度单位  M
11.WGS-84水准划分
12.WGS-84水准划分单位
13.差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
14.差分站ID号0000 - 1023(前导位数不足则补0,如果不是差分定位将为空)
15.校验位  *1F

$GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A

0.$GPGSA 语句ID,表明该语句为GPS DOP and Active Satellites(GSA)当前卫星信息
1.定位模式  A=自动2D/3D  M=手动2D/3D
2.定位类型  1=未定义  2=2D定位  3=3D定位
3.PRN码(伪随机噪声码) 第1信道正在使用的卫星PRN码编号(00)
   12条信道 
15.PDOP综合位置精度因子(0.5 - 99.9)
16.HDOP水平精度因子(0.5 - 99.9)
17.VDOP垂直精度因子(0.5 - 99.9)
18.校验值

$GPGSV,3,1,10,20,78,331,45,01,59,235,47,22,41,069,13,45*70

0.$GPGSV,语句ID,表明该语句为GPS Satellites in View(GSV)可见卫星信息
1.本次GSV语句的总数目(1--3)
2.本条GSV语句是本次GSV语句的第几条(1--3)
3.当前可见卫星总数(00--12)
4.PRN码(01-32)
5.卫星仰角(00--90)
6.卫星方位角(000--359)
7.信噪比(00--99)dbHz
8.PRN码(01-32)
9.卫星仰角(00--90)
10.卫星方位角(000--359)
11.信噪比(00--99)dbHz
12.PRN码(01-32)
13.卫星仰角(00--90)
14.卫星方位角(000--359)
15.信噪比(00--99)dbHz
16.校验值

$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50

0.$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定

位信息
1. hhmmss.sss
2. A=定义  V=未定义
3. 纬度 DDMM.MMMM
4. N 北  S 南
5. 经度 DDDMM.MMMM
6. E 东  W 西
7. 速度 节 Knots
8. 方位角 度
9. DDMMYY
10.磁偏角 (000 -- 180)
11.磁偏角方向 E=东 W=西

16.效验码

 
$GPVTG,89.68,T,,M,0.00,N,0.0,K*5F

0.$GPVTG,语句ID,表明该语句为Track Made Good and Ground Speed(VTG)地面速度信息
1.运动角度 000--359
2.T=正北参照系
3.运动角度 000-359
4.M = 磁北参照系
5.水平运动速度(0.00)
6.N =节
7.水平运动速度
8.K=公里/时
9.效验值


$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D
0.$GPGLL,语句ID,表明该语句为Geographic Position(GLL)地理定位信息
1.纬度ddmm.mmmm,度分格式(前导位数不足则补0) 
2.纬度N(北纬)或S(南纬)
3.经度dddmm.mmmm,度分格式(前导位数不足则补0)
4.经度E(东经)或W(西经)
5.UTC时间,hhmmss.sss格式
6.状态,A=定位,V=未定位
7.校验值

 typedef enum
{
 BS_INVAL = 0, ///无效状态
 BS_IDLE,  ///空闲状态
 BS_WRITE,  ///写状态
 BS_READ   ///读状态
}BUFFER_STATE;

typedef struct
{
 BYTE *pBuff;
 DWORD dwLen; 
}BufferStruct;

typedef struct
{
 BYTE btHour;    //
 BYTE btMinute;     //
 BYTE btSecond;     //
 BYTE btDay;     //
 BYTE btMonth;    //
 WORD wYear;     //
 BYTE btDataValid;   // 1 = last valid, 2 = 2D valid, 3 = 3D valid, 4 = cellid2gps, 0 = navigation rx warning
 double dbLatitude;   // current latitude
 double dbLongitude;   // current longitude
 double dbAltitude;   // Altitude: mean-sea-level (geoid) meters
 double dbAccuracy;   // 水平精度
 double dbSpeed;    // speed over ground, knots
 double dbCourse;   // course over ground, degrees true
}CkGPSDataStruct;
/// 设置gps数据有效回调
typedef void (*cgps_set_gpsdata_cb)(const CkGPSDataStruct *p_gpsdata);
/// 设置原始GPS数据回调
typedef void (*cgps_set_raw_gps_cb)(const GPSDataStruct *p_rawgps);

typedef struct
{
   short sh_gps_count;                ///使用gps的功能的数量
   BOOL  bt_open;                     ///是否已经打开GPS
   BUFFER_STATE  ns_buffer_state;     ///串口数据缓存的状态
   BYTE  b_buffer_valid_cnt;          ///缓存连续无效的次数
   BufferStruct gpsdate;              ///GPS数据
   char *fp;                         ///存放gps数据的文件
   U32 u32_tick;                      ///gps有效的tick
   cgps_set_gpsdata_cb  set_gpsdata_cb[MAX_GPSM_MODULE_SIZE]; ///设置gps数据有效回调
   cgps_set_raw_gps_cb  set_raw_gps_cb[MAX_GPSM_MODULE_SIZE]; ///设置原始GPS数据回调
}GPSParseStruct;

static GPSParserStruct gGPSParser;

void cgps_init(void)
{
   CKGPSDataStruct *p_ckGPSData = &gGPSParser.gpsdata;
   static char szGPSDataFile[MAX_PATH] = {0};
   
   cfs_get_full_path(szGPSDataFile,"GData.dat");
   
   memset(&gGPSParser,0,sizeof(GPSParserStruct));
   
   gGPSParser.fp = szGPSDataFile;
#ifdef __CKING_WRITE_GPSDATA_CYCLICAL__
      cgps_read_gpsdata(p_ckGPSData);
   StopTimer(U16_GPS_WRITE_FILE_TIMER);
   StartTimer(U16_GPS_WRITE_FILE_TIMER, 
     CK_GPS_WRITE_FILE_INTERVAL, 
     cgps_write_gpsdata);
#endif
}

BOOL cgps_open(void)
{
   BOOL bRet = TRUE;
   
   if(gGPSParser.sh_gps_count <= 0)
   {
      bRet = GPS_Open();
   if(bRet)
   {
#ifndef __CKING_SYNCHRONIZATION_ANALYSIS__
     StopTimer(U16_GPS_DATA_RECV_TIMER);
     StartTimer(U16_GPS_DATA_RECV_TIMER, 
       CK_GPS_DATA_RECV_SHORT_INTERVAL, 
       cgps_parse_uart_buffer);
#endif
     gGPSParser.bt_open = TRUE;
     gGPSParser.sh_gps_count = 1;
   }
   }
   else
   {
   gGPSParser.sh_gps_count++;
   }
   return bRet;
}

void cgps_close(void)
{
   if(gGPSParser.sh_gps_count <= 1)
   {
      stopTimer(U16_GPS_DATA_RECV_TIMER);
   GPS_Close();
   gGPSParser.bt_open = FALSE;
   gGPSParser.sh_gps_count = 0; 
   }
   else
   {
      gGPSParser.sh_gps_count--;
   }
}

///解析串口数据
static void cgps_parse_uart_buffer(void)
{
   GPSDataStruct *pGpsData = NULL;
   ///判断缓存是否为写状态,如果是就等待
   if(gGPSParser.ns_buffer_state == BS_WRITE)
   {
        StopTimer(U16_GPS_DATA_RECV_TIMER);
  StartTimer(U16_GPS_DATA_RECV_TIMER, 
       CK_GPS_DATA_RECV_SHORT_INTERVAL, 
       cgps_parse_uart_buffer);
  return;
   }
   
   if(gGPSParser.ns_buffer_state == BS_INVAL)
   {
        gGPSParser.b_buffer_valid_cnt ++;
  if(gGPSParser.b_buffer_valid_cnt >= MAX_UART_BUFFER_INVAL_TIMES)
  {
      gGPSParser.b_buffer_valid_cnt = 0;
   nmea_parser_init();
  }
  
  StopTimer(U16_GPS_DATA_RECV_TIMER);
  StartTimer(U16_GPS_DATA_RECV_TIMER, 
       CK_GPS_DATA_RECV_SHORT_INTERVAL, 
       cgps_parse_uart_buffer);
  return;
   }
   gGPSParser.ns_buffer_state = BS_READ;
   
   pGpsData = nmea_parse_buffer(gGPSParser.data.pBuff,gGPSParser.data.dwLen);
   
   gGPSParser.ns_buffer_state = BS_INVAL;
   
   StopTimer(U16_GPS_DATA_RECV_TIMER);
   StartTimer(U16_GPS_DATA_RECV_TIMER, 
     CK_GPS_DATA_RECV_SHORT_INTERVAL, 
     cgps_parse_uart_buffer);
   if(pGpsData != NULL)
   {
       cgps_excute_raw_gps_cb(pGpsData);
    cgps_parse_gpsdata(pGpsData);
   }
      
       
}



、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 







要获得cell id,可以通过发送 MSG_ID_MMI_EM_UPDATE_REQ来获得

网络回来的消息为MSE_ID_MMI_EM_UPDATE_RSP,MSG_ID_MMI_EM_STATUS_ID.
可以自行实现这两个消息的处理函数
处理的函数 mmi_em_update_rsp_hdlr 处理请求是否成功。如果不影响原来的工程模式处理可以使用EnginerrModeStartRes
           mmi_em_status_ind 处理返回来的所有信息。
要想停止 MSG_ID_MMI_EM_STATUS_IND消息,可以在次发送MSG_ID_MMI_EM_UPDATE_REQ,并将update_req->info_request全部置为EM_OFF.

基站定位:
cell_id                    unique identifier of the cell (cid for gsm ,bid for cdma)
location_area_code         location area code (lac for gsm ,nid for cdma) 位置区号
mobile_country_code        mobile country code (mcc for gsm and cdma) 移动国家码
mobile_network_code        mobile network code (mnc for gsm,sid for cdma) 移动网络码
age                        the number of milliseconds since this cell was primary,if age is 0,the cell_id represents a current measurement
signal_strength            radio signal strength mearsured in dbm
timing_advance             represents the distance from the cell tower.each unit is roughly 550 meters
///其他需要调用基站定位数据地方,可以通过注册一个回调函数来得到相应的基站信息
例如:

1.cagps_reg_valid_cb(cagps_greg_send_agps);
  cagps_open();
2.cagps_unreg_valid_cb(cagps_gred_send_agps);
  cagps_close();
 
typedef struct
{
   WORD cell_id;
   WORD location_area_code;
   WORD mobile_country_code;
   WORD mobile_network_code;
   WORD age;
   S16  signal_strength;
   WORD timing_advance;
}AGPSDataStruct;
typedef enum
{
   AI_NULL = 0x00;
   AI_LAI  = 0x01;
   AI_MR   = 0x02;
   AI_ALL  = 0x03
}AGPS_ITEM;
///基站定位数据回调
typedef void (*cagps_set_agpsdata_cb)(const AGPSDataStruct *p_agpsdata);
typedef struct
{
  BOOL bt_open;
  AGPSDataStruct agpsdata;
  AGPS_ITEM ai_item;
  cagps_set_agpsdata_cb set_agpsdata_cb[MAX_GPSM_MODULE_SIZE]; 
}AGPSParserStruct;
static AGPSParserStruct gAGPSParser;

///启动基站定位的时候需要对其初始化
///1.初始化参数的值,都设置为0.
///2.设置ai_item的参数为AI_NULL表示为接收到基站的信息 AI_LAI AI_MR 表示接收到了LAI MR参数
///3.设置消息映射函数。
void cagps_init(void)
{
   meset(&gAGPSParser,0,sizeof(AGPRSParserStruct));
   gAGPSParser.ai_item = AI_NULL;
   cagps_setevent_handler();
}
///设置消息映射函数,当请求基站定位的时候会参数两个消息MSG_ID_MMI_EM_UPDATE_RSP和MSG_ID_MMI_EM_STATUS_IND
///MSG_ID_MMI_EM_UPDATE_RSP 看是否请求成功。
///MSG_ID_MMI_EM_STATUS_IND 对得到的数据进行处理。
///[注]此处用的是mmi_frm_set_protocol_event_handler();
void cagps_setevent_handler();
{
    //SetProtocolEventHandler();
 mmi_frm_set_protocol_event_handler(cagps_update_rsp_hdlr,MSG_ID_MMI_EM_UPDATE_RSP,MMI_TRUE);
 mmi_frm_set_protocol_event_handler(cagps_status_ind_hdlr,MSG_ID_MMI_EM_STATUS_IND,MMI_TRUE);
}
///对MSG_ID_MMI_EM_UPDATE_RSP的处理
static void cagps_update_rsp_hdlr(void *inMsg)
{
    /*mmi_em_update_rsp_struct *rsp_p = (mmi_em_update_rsp_struct *)inMsg;
 if(rsp_p == NULL)
 {
   
 }
 if(rsp_p->result)
 {
 }
 else
 {
 }*/
}
///对MSG_ID_MMI_EM_STATUS_IND的处理
/*typedef struct
{
   LOCAL_PARA_HDR
   kal_uint8 mod_id;
   kal_uint32 em_info;
   peer_buff_struct* info;
} mmi_em_status_ind_struct;
typedef struct
{   
 kal_uint8 mcc[3]; //MCC
 kal_uint8 mnc[3]; //MNC
 kal_uint8 lac[2]; //LAC
 kal_uint16 cell_id;  //cell ID
 kal_uint8 nc_info_index; // index in rlc array to acquire the corresponding arfcn, bsic, rxlevel...
} rr_em_lai_info_struct;
*/
static void cagps_status_ind_hdlr(void *info)
{
   mmi_em_status_ind_struct *msg = (mmi_em_status_ind_struct *)info;
  
   if(msg == NULL)
   {
   }
   /// 处理lai
   if(msg->em_info == RR_EM_LAI_INFO)
   {
     rr_em_lai_info_struct *data_ptr;
  U16 mm_pdu_len;
  data_ptr = (rr_em_lai_info_struct *)get_pdu_ptr(msg->info,&mm_pdu_len);
  cagps_parse_lai_info(data_ptr);
   }
   ///处理 MR
   if(msg->em_info == RR_EM_MEASUREMENT_REPORT_INFO)
   {
     rr_em_measurement_report_info_struct *data_ptr;
  U16 mm_pdu_len;
  data_ptr = (rr_em_measurement_report_info_struct *)get_pdu_ptr(msg->info,&mm_pud_len);
  cagps_parse_mr_info(data_ptr);
   }
   free_peer_buff(msg->info);
}
///解析得到的LAI数据
static void cagps_parse_lai_info(const rr_em_lai_info_struct *data_ptr)
{
  AGPSDataStruct *p_ckAGPSData = &gAGPSParser.agpsdata;
 
  p_ckAGPSData->cell_id = data_ptr->cell_id;
  if(data_ptr->cell_id == 0)
  {
     return;
  }
  ///lac
  memcpy(&p_ckAGPSData->location_area_code,data_ptr->lac,sizeof(WORD));
  p_ckAGPSData->location_area_code = cmo_short_reverse((short)p_ckAGPSData->location_area_code);
 
  ///mcc
  p_ckAGPSData->mobile_country_code = data_ptr->mcc[0]*100 + data_ptr->mcc[1]*10 + data_ptr->mcc[2];
 
  ///mnc
  if(data_ptr->mnc[2] != 0x0f)
  {
     p_ckAGPSData->mobile_network_code = data_ptr->mnc[0]*100 + data_ptr->mnc[1]*10 + data_ptr->mnc[2];
  }
  else
  {
    p_ckAGPSData->mobile_network_code = data_ptr->mnc[0]*10 + data_ptr->mnc[1];
  }
 
  gAGPSParser.ai_item | = AI_LAI;
 
  if(gAGPSParser.ai_item == AI_ALL)
  {
     cagps_excute_valid_cb(&gAGPSParser.agpsdata);
  cagps_reset();
  }
}
///解析MR数据
static void cagps_parse_mr_info(const rr_em_measurement_report_info_struct *data_ptr)
{
   AGPSDataStruct *p_ckAGPSData = &gAGPSParser.agpsdata;
   ///ta
   if(data_ptr->timing_advance != 0xff)
   {
      p_ckAGPSData->timing_advance = data_ptr->timing_advance * 550;
   }
   ///RSSI
   p_ckAGPSData->signal_strength = data_ptr->serv_rla_in_quarter_dbm * 4;
  
   gAGPSParser.ai_item | = AI_MR;
  
   if(gAGPSParser.ai_item == AI_ALL)
   {
       cagps_excute_valid_cb(&gAGPSParser.agpsdat);
    agps_reset();
   }
}
///重置基站定位
static void cagps_reset(void)
{
  gAGPSParser.ai_item = AI_NULL;
}
///short类型转换
short cmo_short_reverse(short sh)
{
   char *p0 = (char *)&sh;
   short ret = 0;
   char *p1 = (char *)&ret;
  
   p1[0] = p0[0];
   p1[1] = p0[1];
  
   return ret;
}
///注册回调函数
REG_TYPE cagps_reg_valid_cb(cagps_set_agpsdata_cb fun_ptr)
{
    U8 i = 0;
 cagps_set_agpsdata_cb *parser_data_cb_list = gAGPSParer.set_agpsdata_cb;
 
 ASSERT(fun_ptr != NULL);
 while(parser_data_cb_list[i] != fun_ptr)
 {
    if(parser_data_cb_list[i] == fun_ptr)
    {
       return RT_HAS_DONE;
    }
    i++;
    if(i >= 6)
    {
      return RT_FAILED;
    }
 }
 
 parser_data_cb_list[i] = fun_ptr;
 
 return RT_SUCCESSED;
}
///取消注册回调函数
BOOL cagps_unreg_valid(cagps_set_agpsdata_cb fun_ptr)
{
   U8 i = 0;
   cagps_set_agpsdata_cb *parser_data_cb_list = gAGPSParser.set_agpsdata_cb;
   ASSERT(fun_ptr != NULL);
  
   while(i < 6)
   {
       if(parser_data_cb_list[i] == fun_ptr)
    {
        parser_data_cb_list[i] = NULL;
     return TRUE;
    }
    i++;
   }
   return FALSE;
}
///执行回调函数
static void cagps_excute_valid(const AGPSDataStruct *p_agpsdata)
{
   U8 i = 0;
   cagps_set_agpsdata_cb *parser_data_cb_list = gAGPSParser.set_agpsdata_cb;
   while(i < 6)
   {
       if(parser_data_cb_list[i] != NULL)
    {
       (*parser_data_cb_list[i])(p_agpsdata);
    }
    i++;
   }
}
///打开基站定位。发送消息MSG_ID_MMI_EM_UPDATE_REQ
BOOL cagps_open(void)
{
   if(!gAGPSParser.bt_open)
   {
      gAGPSParser.bt_open = TRUE;
   share_SendEMUpdateReq(TRUE);
   }
   return gAGPSParser.bt_open;
}
///关闭基站定位
void cagps_close(void)
{
   if(gAGPSParser.bt_open)
   {
      share_SendEMUpdateReq(FALSE);
      gAGPSParser.bt_open = FALSE;
   cagps_restet();
   }
}
///向系统发送MSG_ID_MMI_EM_UPDATE_REQ的消息处理
/*
typedef struct
{
 LOCAL_PARA_HDR
 kal_uint8 info_request[EM_INFO_REQ_NUM];
} mmi_em_update_req_struct;
*/
void share_SendEMUpdataReq(BOOL bState)
{
   S32 i;
   MYQUEUE Message;
   mmi_em_update_req_struct *update_req;
  
   Message.oslMsgId = MSG_ID_MMI_EM_UPDATE_REQ;
   update_req = OslConstructDataPtr(sizeof(mmi_em_update_req_struct));
   for(i = 0; i < EM_INFO_REQ_NUM; i++)
   {
      update_req->info_requsest[i] = EM_OFF;
   }
   if(bState)
   {
      update_req->info_request[RR_EM_LAI_INFO] = EM_ON;
   update_req->info_request[RR_EM_MESUREMENT_REPORT_INFO] = EM_ON;
   }
  
   Message.oslDataPtr = (oslParaType *)updata_req;
   Message.oslPeerBuffPtr = NULL;
   Message.oslSrcID = MOD_MMI;
   Message.oslDestId = MOD_L4C;
}

///外部得到基站信息
AGPSDataStruct *cagps_get_data(void)
{
    WORD wCID = gAGPSParser.agpsdata.cell_id;
 
 if(wCID == 0)
 {
 }
 return &gAGPSParser.agpsdata;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值