237 lines
10 KiB
C
237 lines
10 KiB
C
#include "ec20gnss.h"
|
||
#include <stdlib.h>
|
||
#include "syslib.h"
|
||
|
||
/********************************************************************************
|
||
* @file ec20gnss.c
|
||
* @author 晏诚科技 Mr.Wang
|
||
* @version V1.0.0
|
||
* @date 9-Jan-2021
|
||
* @brief Quectel模块EC20公 GNSS全球定位系统相关驱动
|
||
******************************************************************************
|
||
* @attention
|
||
* EC20模块支持多定位系统,本驱动默认使用GPS卫星进行定位
|
||
*******************************************************************************/
|
||
|
||
/*****************************************
|
||
*ec20 GNSS 驱动内部使用常变量
|
||
****************************************/
|
||
#define GNSS_CMDPACK_LEN 128 //EC20 GNSS相关命令字符串的最大长度
|
||
NMEARMC_s sRMCData ; //NMEARMC_s结构体全局 用于存放NMEA语句中RMC语句的数据
|
||
|
||
/********************************************************
|
||
ec20模块 GNSS 相关AT指令处理
|
||
*********************************************************/
|
||
enum eGnssCmdNum
|
||
{
|
||
OPENNMEA =0, SELFOPENGNSS = 1, OPENGNSS =2, QUERYRMC =3 , CLOSEGNSS =4
|
||
} ; //枚举ec20模块GNSS相关指令
|
||
|
||
volatile EC20_CMD_DATA_s sGnssCmd[11]=
|
||
{
|
||
// cmdNum cmdStr, timeout(100ms), trueStr, trueOffset falseStr revResult rtyNum
|
||
{OPENNMEA, "AT+QGPSCFG=\"nmeasrc\",1\r\n", 3, "OK" , -1, "ERROR", TIMEOUT, 2 }, //启用通过 AT+QGPSGNMEA 获取 NMEA 语句
|
||
{SELFOPENGNSS, "AT+QGPSCFG=\"autogps\",1\r\n", 3, "OK" , -1, "ERROR", TIMEOUT, 2 }, //开启GNSS自启动功能
|
||
{OPENGNSS, "AT+QGPS=1\r\n", 3, "OK" , -1, "ERROR", TIMEOUT, 2 }, //打开GNSS
|
||
{QUERYRMC, "AT+QGPSGNMEA=\"RMC\"\r\n", 3, "+QGPSGNMEA: $GPRMC" , -1, "ERROR", TIMEOUT, 2 }, //获取 NMEA 语句中的RMC
|
||
{CLOSEGNSS, "AT+QGPSEND\r\n", 3, "OK" , -1, "ERROR", TIMEOUT, 2 } //关闭GNSS
|
||
} ; //EC20模块NET相关指令的EC20_CMD_DATA_s结构体类型参数
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: static inline const char *GnssCmdNumToString(enum eGnssCmdNum result)
|
||
* 功能说明: 输出枚举成员名的字符串指针。
|
||
* 入口参数: eGnssCmdNum类型的枚举
|
||
* 出口参数: 为枚举的成员名字符串指针
|
||
**************************************************************************************************/
|
||
static inline const char *GnssCmdNumToString(enum eGnssCmdNum result)
|
||
{
|
||
switch (result)
|
||
{
|
||
ENUM_CHIP_TYPE_CASE(OPENNMEA)
|
||
ENUM_CHIP_TYPE_CASE(SELFOPENGNSS)
|
||
ENUM_CHIP_TYPE_CASE(OPENGNSS)
|
||
ENUM_CHIP_TYPE_CASE(QUERYRMC)
|
||
ENUM_CHIP_TYPE_CASE(CLOSEGNSS)
|
||
}
|
||
ErrorLogPrintf("EC20 无效eGnssCmdNum!") ;
|
||
return "无此命令";
|
||
}
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: RunResult EC20_SendGnssCmd( uint8_t cmdNum, char *format,... )
|
||
* 功能说明: MCU串口向EC20发送GNSS相关命令
|
||
* 入口参数:
|
||
* @param1 cmdNum EC20_CMD_DATA_s中cmdNum成员命令编号
|
||
* @param2 char *format,... 可变参变量
|
||
* 出口参数:
|
||
* @param1 status RunResult枚举类型变量,返回函数运行结果
|
||
**************************************************************************************************/
|
||
RunResult EC20_SendGnssCmd( uint8_t cmdNum, char *format,... )
|
||
{
|
||
uint8_t revTimes = 0 ;
|
||
RunResult status = TIMEOUT ;
|
||
uint8_t retryTimes = sGnssCmd[cmdNum].rtyNum ;
|
||
char *cmdPack = NULL ;
|
||
format = sGnssCmd[cmdNum].cmdStr ;
|
||
cmdPack = portMalloc(GNSS_CMDPACK_LEN*sizeof(uint8_t)) ;
|
||
va_list ap;
|
||
va_start (ap, format);
|
||
int outLen = vsnprintf(cmdPack, GNSS_CMDPACK_LEN, (const char*)format, ap); //vsprintf (temp, cmd, ap); //到此为止,所有的参数情况已经汇总到temp了
|
||
if((outLen<=0)||( outLen > GNSS_CMDPACK_LEN)) //vsprintf (temp, cmd, ap); //到此为止,所有的参数情况已经汇总到temp了
|
||
{
|
||
ErrorLogPrintf("%s,%d:cmdPack spillover!",__FILE__, __LINE__) ; //增加NET_CMDPACK_LEN数值
|
||
status = RUNERR ;
|
||
goto netCmdOut ;
|
||
}
|
||
while(retryTimes--)
|
||
{
|
||
Ec20AtBufReset() ;
|
||
revTimes = 0 ;
|
||
//UARTx_Printf(EC20_UART, (uint8_t *)"%s", (uint8_t *)cmdPack);
|
||
UARTx_SendData(EC20_UART, cmdPack, outLen) ; //DMA发送
|
||
while( revTimes++ < sGnssCmd[cmdNum].timeout )
|
||
{
|
||
Wait_For_Nms(100);
|
||
sGnssCmd[cmdNum].trueOffset = kmp(ec20AtBuf, sGnssCmd[cmdNum].trueStr) ;
|
||
if( sGnssCmd[cmdNum].trueOffset >= 0)
|
||
{
|
||
status = RUNOK ;
|
||
goto netCmdOut ;
|
||
}
|
||
else if( kmp(ec20AtBuf, sGnssCmd[cmdNum].falseStr) >= 0)
|
||
{
|
||
status = RUNERR ;
|
||
goto netCmdOut ;
|
||
}
|
||
}
|
||
Wait_For_Nms( 1000 ) ;
|
||
}
|
||
netCmdOut:portFree(cmdPack) ;
|
||
va_end (ap);
|
||
DebugLogPrintf("%s %s", GnssCmdNumToString((enum eGnssCmdNum)cmdNum), RunResultToString(status) ) ;
|
||
return (status) ;
|
||
}
|
||
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: RunResult EC20GnssConfig(void)
|
||
* 功能说明: EC20 GNSS功能配置 主要启用通过 AT+QGPSGNMEA 获取 NMEA 语句
|
||
* 出口参数:
|
||
* @param1 runResult RunResult枚举类型变量,返回函数运行结果
|
||
**************************************************************************************************/
|
||
RunResult EC20GnssConfig(void)
|
||
{
|
||
RunResult runResult = EC20_SendGnssCmd(OPENNMEA, NULL ) ;
|
||
return (runResult) ;
|
||
}
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: RunResult EC20SelfOpenGnss(void)
|
||
* 功能说明: EC20 开机自启动GNSS引擎
|
||
* 出口参数:
|
||
* @param1 runResult RunResult枚举类型变量,返回函数运行结果
|
||
**************************************************************************************************/
|
||
RunResult EC20SelfOpenGnss(void)
|
||
{
|
||
RunResult runResult = EC20_SendGnssCmd(SELFOPENGNSS, NULL ) ;
|
||
return (runResult) ;
|
||
}
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: RunResult EC20OpenGnss(void)
|
||
* 功能说明: EC20 开启EC20 GNSS引擎
|
||
* 出口参数:
|
||
* @param1 runResult RunResult枚举类型变量,返回函数运行结果
|
||
**************************************************************************************************/
|
||
RunResult EC20OpenGnss(void)
|
||
{
|
||
RunResult runResult = EC20_SendGnssCmd(OPENGNSS, NULL ) ;
|
||
return (runResult) ;
|
||
}
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: RunResult EC20CloseGnss(void)
|
||
* 功能说明: EC20 关闭EC20 GNSS引擎
|
||
* 出口参数:
|
||
* @param1 runResult RunResult枚举类型变量,返回函数运行结果
|
||
**************************************************************************************************/
|
||
RunResult EC20CloseGnss(void)
|
||
{
|
||
RunResult runResult = EC20_SendGnssCmd(CLOSEGNSS, NULL ) ;
|
||
return (runResult) ;
|
||
}
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: RunResult EC20GnssQueryRMC(void)
|
||
* 功能说明: 获取 NMEA 语句中的RMC
|
||
* 出口参数:
|
||
* @param1 runResult RunResult枚举类型变量,返回函数运行结果
|
||
**************************************************************************************************/
|
||
RunResult EC20GnssQueryRMC(NMEARMC_s *psNmeaRMC )
|
||
{
|
||
RunResult runResult = EC20_SendGnssCmd(QUERYRMC, NULL ) ;
|
||
memset(psNmeaRMC, 0, sizeof(NMEARMC_s)) ; //先清空NMEARMC_s类型变量
|
||
if( runResult == RUNOK )
|
||
{
|
||
strtok(&ec20AtBuf[sGnssCmd[QUERYRMC].trueOffset], ",") ;
|
||
strncpy(psNmeaRMC->utcTime, strtok(NULL, ","), sizeof(psNmeaRMC->utcTime) ) ; //填充UTC时间
|
||
strncpy((char*)&psNmeaRMC->eGnssStatus, strtok(NULL, ","), 1 ) ; //填充GNSS定位状态
|
||
if( psNmeaRMC->eGnssStatus == ALREADY ) //已经定位成功
|
||
{
|
||
strncpy(psNmeaRMC->latitude, strtok(NULL, ","), sizeof(psNmeaRMC->latitude) ) ; //填充GNSS定位纬度值
|
||
strncpy((char*)&psNmeaRMC->eLatitudeDirect, strtok(NULL, ","), 1 ) ; //填充GNSS定位纬度方向
|
||
strncpy(psNmeaRMC->longitude, strtok(NULL, ","), sizeof(psNmeaRMC->longitude) ) ; //填充GNSS定位经度值
|
||
strncpy((char*)&psNmeaRMC->eLongitudeDirect, strtok(NULL, ","), 1 ) ; //填充GNSS定位经度方向
|
||
strncpy(psNmeaRMC->speed, strtok(NULL, ","), sizeof(psNmeaRMC->speed) ) ; //填充GNSS定位物体速度 单位:节
|
||
strncpy(psNmeaRMC->angDirect, strtok(NULL, ","), sizeof(psNmeaRMC->angDirect) ) ; //填充GNSS定位角方向
|
||
strncpy(psNmeaRMC->utcDate, strtok(NULL, ","), sizeof(psNmeaRMC->utcDate) ) ; //填充GNSS定位UTC日期
|
||
}
|
||
else //还在定位中,表示GPS信号弱
|
||
{
|
||
runResult = TIMEOUT ;
|
||
}
|
||
}
|
||
return (runResult) ;
|
||
}
|
||
|
||
/**************************************************************************************************
|
||
* 名 称: void RMCUtcToBJT(Calendar_u *puSetRTC, NMEARMC_s *psRMCData )
|
||
* 功能说明: 将GNSS返回的RMC语句中的日期和时间转化为 Calendar_u共用体数据格式
|
||
* 出口参数:
|
||
* @param1 puSetRTC Calendar_u共用体指针
|
||
* @param2 psRMCData NMEARMC_s结构体指针
|
||
**************************************************************************************************/
|
||
void RMCUtcToBJT(Calendar_u *puSetRTC, NMEARMC_s *psRMCData )
|
||
{
|
||
strncpy((char*)&puSetRTC->sCalendar.w_year[0], "20", 2 ) ;
|
||
strncpy((char*)&puSetRTC->sCalendar.w_year[2], &psRMCData->utcDate[4], 2 ) ; //填充年
|
||
strncpy((char*)puSetRTC->sCalendar.w_month , &psRMCData->utcDate[2], 2 ) ; //填充月
|
||
strncpy((char*)puSetRTC->sCalendar.w_date , &psRMCData->utcDate[0], 2 ) ; //填充日
|
||
|
||
strncpy((char*)&puSetRTC->sCalendar.hour , &psRMCData->utcTime[0], 2 ) ; //填充时
|
||
int hour = atoi((const char*)puSetRTC->sCalendar.hour) +8 ;
|
||
puSetRTC->sCalendar.hour[0] = hour/10 + 0x30 ;
|
||
puSetRTC->sCalendar.hour[1] = hour%10 + 0x30 ;
|
||
|
||
strncpy((char*)&puSetRTC->sCalendar.min , &psRMCData->utcTime[2], 2 ) ; //填充分
|
||
strncpy((char*)&puSetRTC->sCalendar.sec , &psRMCData->utcTime[4], 2 ) ; //填充秒
|
||
|
||
puSetRTC->sCalendar.colon1 = puSetRTC->sCalendar.colon2 = '.' ;
|
||
puSetRTC->sCalendar.dash1 = puSetRTC->sCalendar.dash2 = '-' ;
|
||
puSetRTC->sCalendar.spacing = ' ' ;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|