模块介绍
T302模块是泰斗微电子推出的一款支持BD2 B1/GPS L1频点的双模授时模块。模块内部集成了泰斗微电子自主研发的BD2 B1/GPS L1双模芯片,为电力系统、通信基站等授时终端产品提供了高精度、高灵敏度、低功耗、低成本的BD2 B1/GPS L1双模解决方案。
T302模块尺寸为22.4mmx 17mmx2.2mm,体积小巧。采用28pin邮票孔兼容通用封装,采用通用接口协议。板上可直接替换,大大节省授时定位终端产品设计时间。
T302支持模块软件升级等功能。
产品特性
28pin邮票孔封装,尺寸22.4mm x 17mm x2.2mm
支持BD2 B1和GPS L1频点
支持以下三种工作模式,并可通过命令相互无缝切换(无缝切换是指在模式切换的过程中,模块不重启,且1PPS信号稳定无跳变,授时服务不中断):
1)单BD2 B1工作模式
2)单GPS L1工作模式
3)BD2 B1/GPS L1双模工作模式
导航配置
配置和读取数据是一样的,都需要打开相应的串口设备,只不过配置过程是以特定指令格式往该串口写数据,厂家的指令集截取如下:
转化为代码就是下面这个样子了,注意换行符\n不能丢。
int bspCfgGpsMode(int mode, int isRestart)
{
int fd = 0;
char tx_buff [256];
fd = open("/dev/ttyS5", O_RDWR|O_NOCTTY|O_NDELAY);
if(fd < 0)
{
printf("Open /dev/ttyS5 failed!");
return -1;
}
memset(&tx_buff, 0, sizeof(tx_buff));
if(isRestart) /*冷启动*/
{
switch(mode)
{
case 1: /* 北斗 */
strcpy(tx_buff,"$CCSIR,1,1*48\n");
break;
case 2: /* GPS */
strcpy(tx_buff,"$CCSIR,2,1*4B\n");
break;
case 3: /* 混合 */
default:
strcpy(tx_buff,"$CCSIR,3,1*4A\n");
break;
}
}
else /*不重启*/
{
switch(mode)
{
case 1:
strcpy(tx_buff,"$CCSIR,1,0*49\n");
break;
case 2:
strcpy(tx_buff,"$CCSIR,2,0*4A\n");
break;
case 3:
default:
strcpy(tx_buff,"$CCSIR,3,0*4B\n");
break;
}
}
write(fd, tx_buff, sizeof(tx_buff));
close(fd);
return 0;
}
数据解析
导航系统切换后势必导致串口数据格式的差异
GPS数据
$GPZDA,030959.00,28,12,2022,00,00*6B
$GPRMC,030959.00,A,2234.84485,N,11355.31347,E,0.042,,281222,,,A,V*00
$GPGGA,030959.00,2234.84485,N,11355.31347,E,1,05,1.57,213.7,M,-2.5,M,,*42
$GPGSA,A,3,25,31,23,12,32,,,,,,,,3.27,1.57,2.86,1*10
$GPGSV,3,1,09,01,01,306,43,10,63,178,36,12,17,041,43,21,05,286,41,0*6B
$GPGSV,3,2,09,22,39,332,32,23,30,159,33,25,45,054,42,31,51,291,44,0*66
$GPGSV,3,3,09,32,55,016,38,0*51
$GPZDA,031000.00,28,12,2022,00,00*6F
$GPRMC,031000.00,A,2234.84523,N,11355.31294,E,0.041,,281222,,,A,V*05
$GPGGA,031000.00,2234.84523,N,11355.31294,E,1,05,1.57,212.1,M,-2.5,M,,*43
$GPGSA,A,3,25,31,23,12,32,,,,,,,,3.27,1.57,2.86,1*10
$GPGSV,3,1,09,01,01,306,42,10,63,178,36,12,17,041,43,21,05,286,39,0*65
$GPGSV,3,2,09,22,39,332,31,23,30,159,33,25,45,054,41,31,51,291,44,0*66
$GPGSV,3,3,09,32,55,016,36,0*5F
北斗的数据相对较慢
$BDZDA,024143.00,28,12,2022,00,00*7C
$BDRMC,024143.00,A,2234.73989,N,11355.32483,E,0.175,,281222,,,A,V*17
$BDGGA,024143.00,2234.73989,N,11355.32483,E,1,05,4.41,250.7,M,-2.5,M,,*55
$BDGSA,A,3,06,09,13,16,08,,,,,,,,22.3,4.41,21.9,4*01
$BDGSV,4,1,14,02,48,237,,03,63,189,,04,32,111,,05,25,257,,0*7C
$BDGSV,4,2,14,06,54,332,40,07,26,178,,08,50,204,19,09,50,312,33,0*74
$BDGSV,4,3,14,10,20,185,20,13,55,222,27,16,54,344,39,19,65,353,,0*7F
$BDGSV,4,4,14,20,52,112,,22,16,321,,0*71
$BDZDA,024144.00,28,12,2022,00,00*7B
$BDRMC,024144.00,A,2234.74003,N,11355.32485,E,0.176,,281222,,,A,V*19
$BDGGA,024144.00,2234.74003,N,11355.32485,E,1,05,4.41,250.6,M,-2.5,M,,*59
$BDGSA,A,3,06,09,13,16,08,,,,,,,,22.3,4.41,21.9,4*01
$BDGSV,4,1,14,02,48,237,,03,63,189,,04,32,111,,05,25,257,,0*7C
$BDGSV,4,2,14,06,54,332,40,07,26,178,,08,50,204,20,09,50,312,33,0*7E
$BDGSV,4,3,14,10,20,185,19,13,55,222,27,16,54,344,39,19,65,353,,0*75
$BDGSV,4,4,14,20,52,112,,22,16,321,,0*71
混合定位数据
$GNZDA,013516.00,28,12,2022,00,00*73
$GNRMC,013516.00,A,2234.67271,N,11355.36048,E,0.023,,281222,,,A,V*14
$GNGGA,013516.00,2234.67271,N,11355.36048,E,1,06,2.32,84.7,M,-2.5,M,,*6E
$GNGSA,A,3,10,12,22,32,24,,,,,,,,3.02,2.32,1.94,1*0A
$GNGSA,A,3,06,,,,,,,,,,,,3.02,2.32,1.94,4*0C
$GPGSV,2,1,08,10,66,340,39,12,37,083,33,22,19,293,41,23,,,22,0*5A
$GPGSV,2,2,08,24,21,040,40,25,,,30,31,,,33,32,38,321,42,0*62
$BDGSV,1,1,02,06,59,315,36,09,,,33,0*47
$GNZDA,013517.00,28,12,2022,00,00*72
$GNRMC,013517.00,A,2234.67264,N,11355.36054,E,0.024,,281222,,,A,V*1B
$GNGGA,013517.00,2234.67264,N,11355.36054,E,1,06,2.32,84.6,M,-2.5,M,,*67
$GNGSA,A,3,10,12,22,32,24,,,,,,,,3.02,2.32,1.94,1*0A
$GNGSA,A,3,06,,,,,,,,,,,,3.02,2.32,1.94,4*0C
$GPGSV,2,1,08,10,66,340,40,12,37,083,31,22,19,293,40,23,,,20,0*55
$GPGSV,2,2,08,24,21,040,40,25,,,30,31,,,33,32,38,321,42,0*62
$BDGSV,1,1,02,06,59,315,36,09,,,33,0*47
了解一下GPS数据格式后,我们就会明白后三个字母才是用来区分数据类型的,此处我们只需要解析RMC数据就行,下面我们就要以一种兼容的方式来解析这个数据了
static void parseRMC(char *pStr)
{
int tmp;
char* buf=pStr;
/*date time*/
gpsInfo.D.hour =(buf[4]-'0')*10+(buf[5]-'0');
gpsInfo.D.minute =(buf[6]-'0')*10+(buf[7]-'0');
gpsInfo.D.second =(buf[8]-'0')*10+(buf[9]-'0');
tmp = GetComma(9,buf); //得到第9个逗号的下一字符序号
gpsInfo.D.day =(buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');
gpsInfo.D.month =(buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');
gpsInfo.D.year =(buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;
/*other infomation*/
gpsInfo.status =buf[GetComma(2,buf)]; //状态
gpsInfo.latitude =getDoubleNumber(&buf[GetComma(3,buf)]) / 100; //纬度
gpsInfo.NS =buf[GetComma(4,buf)]; //南北纬
gpsInfo.longitude=getDoubleNumber(&buf[GetComma(5,buf)]) / 100; //经度
gpsInfo.EW =buf[GetComma(6,buf)]; //东西经
gpsInfo.speed =getDoubleNumber(&buf[GetComma(7,buf)]); //速度
UTC2BTC(&gpsInfo.D); //转北京时间
return;
}
int gpsAnalysize (char *gps_buff)
{
char *ptr = NULL;
if((strlen(gps_buff)) < 10)
{
printf ("gps_buff error\n");
}
if(NULL == (ptr = strstr(gps_buff, "RMC")))
{
printf ("cannot find \"RMC\".\n");
}
else
{
parseRMC(ptr);
}
return 0;
}