stm32_ota/ABM开发板(DTU透传APP源码)/YcOS版本/APPV4.0/HARDWARE/LTE/EC20/ec20gnss.c
2024-12-17 20:03:43 +08:00

237 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 = ' ' ;
}