灵动MM32单片机移植NMEA协议库解算GGA数据格式通过串口dma硬件传输

今天使用一款常见的gps模块,goouuu果云GPS模块,这款产品可以说是便宜好用,但是这个原版本的例程我觉得不太行,解析库的时候太浪费资源,而且兼容性不好。所以我就用灵动mm32在果云GPS模块上移植野火的开发的GPS库文件

用到的硬件和库文件:
①MM32F3277G9P单片机 ②goouuu果云GPS模块模块 ③智能车逐飞MM32开源库 ④野火开源库

逐飞开源库链接: 逐飞科技MM32F327X_G9P开源库
野火GPS模块资料链接

  • 灵动MM32单片机移植NMEA协议库解算GGA数据格式通过串口dma硬件传输
    • 一、模块介绍
    • 二、模块引脚说明及模块资源
    • 三、NMEA-0183 协议
      • 3-1协议框架
      • 3-2 协议帧格式说明:
      • 3-3 GGA数据格式
    • 四、NMEA库移植过程
    • 五、MM32配置代码
      • 5-1 GPS接口初始化
        • GPS_USART_Config函数
        • GPS_DMA_Config 函数
        • DMA2_Channel3_IRQHandler中断函数
      • 5-2 解码测试函数nmea_decode_test()
      • 5-3 MM32堆栈空间设置
    • 六、主函数调用

一、模块介绍

ATGM336H-5N系列模块是小尺寸的高性能BDS/GNSS全星座定位导航模块系列的总称。

该系列模块产品都是基于中科微第四代低功耗GNSS SOC单芯片—AT6558
支持多种卫星导航系统,包括中国的BDS(北斗卫星导航系统),美国的GPS,俄罗斯的GLONASS,欧盟的GALILEO,日本的QZSS 以及卫星增强系统SBAS ( WAAS,EGNOS,GAGAN,MSAS )。

AT6558是一款真正意义的六合一多模卫星导航定位芯片,包含32个跟踪通道,可以同时接收六个卫星导航系统的GNSS信号,并且实现联合定位导航与授时。

二、模块引脚说明及模块资源

引脚说明:
VCC :电源线,正常电压范围为: 3.3~5V
GND:地线
TXD: 串口数据发送信号线,使用 TTL 电平
RXD: 串口数据接收信号线,使用 TTL 电平
PPS: 时间脉冲信号线,模块接收到 GPS 时间信息后,输出可调节的脉冲信号,默认为 1Hz,脉冲上升沿与 UTC 时间对齐

资源描述:
XH414 法拉电容:
参数为: 3.3V 0.07F。它的功能和锂电池一样,在主电源掉电的时候可以为定位模块的 RTC 部分供电,以使定位模块在下次启动时能快速搜索到卫星,一般可持续供电 1 小时。

有源天线 IPX接口: IPX 接口用于连接有源天线

时间脉冲指示灯:
模块上电后,时间脉冲指示灯即亮,在定位模块接收到时间信息后,时间脉冲信号指示灯会默认以 1Hz 的频率闪烁,该信号频率可以调节。

三、NMEA-0183 协议

NMEA-0183 是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的 ASCII 格式, 使用逗号隔开数据,数据流长度从 30-100 字符不等,通常以每秒间隔选择输出。

最常用的格式为"GGA",它包含了定位时间,纬度,经度,高度,定位所用的卫星数, DOP 值, 差分状态和校正时段等,其他的有速度,跟踪,日期等。 NMEA 实际上已成为所有的定位接收机中最通用的数据输出格式。

3-1协议框架


NMEA 语句的数据段为信息主体,不同类型的语句用于传输不同类型的定位信息, 其语句类型又分为两部分, 如 GNZDA 前面两个字符 GN 用于区分定位系统

其中 GN 标识符比较特殊,当发送器具有多模功能时(即同时支持一个以上的定位系统),系统会把各系统的信息整合、 处理后,再把这些综合信息采用 GN 作为标识符发送出来,如前面的时间日期信息, 使用 GNZDA 语句, 在这样的系统中, GP、 BD 等标识符仅用于表示对应系统的卫星信息,如 GPGSA 和 BDGSA 语句分别用于表示美国 GPS 系统和北斗系统的卫星信息。

NMEA-0183 协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有 GGA、RMC、 VTG、 GLL、 ZDA、 GSA、 GSV 等。下面给出这些常用 NMEA-0183 语句的字段定义解释

3-2 协议帧格式说明:

该协议采用 ASCII 码。 帧格式形如: $ aaccc,ddd,ddd,…,ddd * hh < C R >< LF>
<1> “$”——帧命令起始位
<2> aaccc——地址域,前两位为识别符,后三位为语句名
<3> ddd…ddd——数据
<4> “ * ”——校验和前缀
<5> hh——校验和(check sum), $与*之间所有字符 ASCII 码的校验和(各字节做异或运算,得到校验和后,再转换 16 进制格式的 ASCII 字符。)
<6> < CR>< LF>——CR(Carriage Return) + LF(Line Feed)帧结束,回车和换行

3-3 GGA数据格式

GPS 固定数据输出语句(Global positioning system fix data)。

格式:$GNGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>*<15>< CR>< LF >

$GNGGA,012842.000,2253.7220,N,11350.7025,E,1,11,1.5,44.8,M,0.0,M,*44

<1> UTC 时间,格式为 hhmmss.sss
<2> 纬度,格式为 ddmm.mmmm(前导位数不足则补 0)
<3> 纬度半球, N 或 S(北纬或南纬)
<4> 经度,格式为 dddmm.mmmm(前导位数不足则补 0)
<5> 经度半球, E 或 W(东经或西经)
<6> 定位质量指示, 0=定位无效, 1=标准定位, 2=差分定位, 6=估算
<7> 使用卫星数量,从 00 到 12(前导位数不足则补 0)
<8> 水平精确度, 0.5 到 99.9
<9> 天线离海平面的高度, -9999.9 到 9999.9 米
<10> 高度单位, M 表示单位米
<11> 大地椭球面相对海平面的高度(-999.9 到 9999.9)
<12> 高度单位, M 表示单位米
<13> 差分 GPS 数据期限(RTCM SC-104),最后设立 RTCM 传送的秒数量
<14> 差分参考基站标号,从 0000 到 1023(前导位数不足则补 0)
<15> 校验和。

其他数据格式这里就不再介绍

四、NMEA库移植过程

NMEA解码库使用纯 C 语言编写,支持解析 GPGGA,GPGSA ,GPGSV, GPRMC, GPVTG 这五种语句(这五种语句已经提供足够多的 GPS 信息),

解析得的 GPS 数据信息以结构体存储,附加了地理学相关功能,可支持导航等数据工作。

将nmea_decode文件夹复制到工程目录之下

并在keil的设置添加文件路径:


将库文件下的.c文件添加到工程中

五、MM32配置代码

GPS在传输数据的时候是串口接收的,因此大量的数据在串口传输时候,如果使用mcu来进行循环处理,这将大大降低CPU的效率

因此这里选择串口dma,硬件数据传输,但是网上关于灵动单片机的dma配置资源比较少,这里我将我的代码配置出来。

5-1 GPS接口初始化

主要包括串口初始化和串口dma配置

///**
//  * @brief  GPS_Config gps 初始化
//  * @param  无
//  * @retval 无
//  */
void GPS_Config(void)
{GPS_USART_Config();GPS_DMA_Config();
}

GPS_USART_Config函数

主要是对mm32 与定位模块连接的 USART 串口外设作了基本的初始化,除了要注意把波特率配置为 9600,其它跟普通串口配置无异。

/** 函数名:GPS_USART_Config* 描述  :USART GPIO 配置,工作模式配置* 输入  :无* 输出  : 无* 调用  :外部调用*/
static void GPS_USART_Config(void)
{   uart_init(GPS_UART, GPS_USART_BAUDRATE, GPS_USART_RX, GPS_USART_TX);uart_rx_irq(GPS_UART, 1);
}

GPS_DMA_Config 函数

MM32DMA相关的宏定义:这部分可以查阅芯片手册得到:

//DMA
#define GPS_USART_DMA_STREAM            DMA2_Channel3
#define GPS_DMA_IRQn                     DMA2_Channel3_IRQn         //GPS中断源
#define GPS_USART_DMA_CLK                RCC_AHBENR_DMA2
#define GPS_USART_DMA_CHANNEL            DMA_Channel_3/* 外设标志 */
#define GPS_DMA_IT_HT               DMA2_IT_HT3 //DMA_IT_HTIF5
#define GPS_DMA_IT_TC               DMA2_IT_TC3 //DMA_IT_TCIF5#define UART_DMAReq_Rx                      ((uint16_t)0x0040)
/* 中断函数 */
#define GPS_DMA_IRQHANDLER           DMA2_Channel3_IRQHandler   //GPS使用的DMA中断服务函数

串口接收缓冲区地址宏定义

#define GPS_DATA_ADDR             (u32)&UART4->RDR //GPS_DR_Base        //GPS使用的串口的数据寄存器地址
#define GPS_RBUFF_SIZE            512                   //串口接收缓冲区大小
#define HALF_GPS_RBUFF_SIZE       (GPS_RBUFF_SIZE/2)    //串口接收缓冲区一半

重点在串口 DMA 的配置,代码如下

/*** @brief  GPS_Interrupt_Config 配置GPS使用的DMA中断 * @param  None.* @retval None.*/
static void GPS_Interrupt_Config(void)
{exNVIC_Init_TypeDef  NVIC_InitStruct;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStruct.NVIC_IRQChannel = GPS_DMA_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;exNVIC_Init(&NVIC_InitStruct);
}
/*** @brief  GPS_DMA_Config gps dma接收配置* @param  无* @retval 无*/
static void GPS_DMA_Config(void)
{DMA_InitTypeDef DMA_InitStructure;/*开启DMA时钟*/ RCC_AHBPeriphClockCmd(GPS_USART_DMA_CLK, ENABLE); /* 复位初始化DMA数据流 */ DMA_DeInit(GPS_USART_DMA_STREAM);DMA_StructInit(&DMA_InitStructure); /*设置DMA源:串口数据寄存器地址*/DMA_InitStructure.DMA_PeripheralBaseAddr = GPS_DATA_ADDR;    /*内存地址(要传输的变量的指针)*/DMA_InitStructure.DMA_MemoryBaseAddr = (u32)gps_rbuff;/*方向:从外设到内存*/     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/   DMA_InitStructure.DMA_BufferSize = GPS_RBUFF_SIZE;/*外设地址不增*/       DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*内存地址自增*/DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    /*外设数据单位*/  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;/*内存数据单位 8bit*/DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /*DMA模式:不断循环*/DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    /*优先级:中*/   DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;    //M2M mode is disabledDMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                               // 非内存到内存模式DMA_InitStructure.DMA_Auto_reload = DMA_Auto_Reload_Enable;/*配置DMA2的数据流3*/         DMA_Init(GPS_USART_DMA_STREAM, &DMA_InitStructure); // Enable UARTy_DMA1_Channel Transfer complete interruptDMA_ITConfig(GPS_USART_DMA_STREAM, DMA_IT_HT|DMA_IT_TC, ENABLE);/* 配置串口 向 DMA发出请求 */UART_DMACmd(UART4, UART_DMAReq_EN, ENABLE); /*使能DMA*/DMA_Cmd(GPS_USART_DMA_STREAM, ENABLE);/*配置中断优先级*/GPS_Interrupt_Config();
}

GPS_DMA_Config 函数主要工作如下: 设置了外设地址为 USART 的数据寄存器,并把数据传输方向设置为从USART 数据寄存器传输到内存变量 gps_rbuff 中,该缓冲区数组大小为 512 字节。

DMA2_Channel3_IRQHandler中断函数

最关键的位置它设置了 DMA 半传输结束中断及全传输结束中断,

//配置 DMA 发送完成后产生中断
DMA_ITConfig(GPS_USART_DMA_STREAM,DMA_IT_HT|DMA_IT_TC,ENABLE);

所以它实际把缓冲区分为成了大小相等的 A/B 两部分,每次 DMA 接收了半个缓冲区大小的数据时(本程序为256 字节),就会引起中断得益于这个机制。

可以设计程序当 DMA 使用缓冲区 A 存储数据时,控制 CPU 使用 B中的数据进行 GPS 解码,当 DMA 使用 B 存储时,控制 CPU 使用 A 进行解码,只要缓冲区的大小设置合适,即可避免前面说到的数据丢失问题,这种处理方式也称“乒乓缓冲”,得名于它像打乒乓球一样,你来我往。

当 DMA 的 半 传 输 中 断 或 全 传 输 中 断 产 生 时 , 进 入 的 中 断 服 务 函 数 调 用 了DMA2_Channel3_IRQHandler函数

void DMA2_Channel3_IRQHandler(void)
{if(DMA_GetITStatus(GPS_DMA_IT_HT) )         /* DMA 半传输完成 */{GPS_HalfTransferEnd = 1;                //设置半传输完成标志位DMA_ClearITPendingBit (GPS_DMA_IT_HT); }else if(DMA_GetITStatus(GPS_DMA_IT_TC))     /* DMA 传输完成 */{GPS_TransferEnd = 1;                    //设置传输完成标志位DMA_ClearITPendingBit(GPS_DMA_IT_TC);}
}

在 这 个 函 数 处 理 中 , 主 要 是 在 半 传 输 和 全 传 输 结 束 引 起 中 断 时 , 对GPS_HalfTransferEnd 和 GPS_TransferEnd 标志位进行标记, 在解码流程中根据这两个标志使用不同的缓冲区进行处理。

5-2 解码测试函数nmea_decode_test()

解码函数主要是调用函数库中的函数,并加标志位进行处理。

/*** @brief  nmea_decode_test 解码GPS模块信息* @param  无* @retval 无*/
int nmea_decode_test(void)
{double deg_lat;//转换成[degree].[degree]格式的纬度double deg_lon;//转换成[degree].[degree]格式的经度nmeaINFO info;          //GPS解码后得到的信息nmeaPARSER parser;      //解码时使用的数据结构  uint8_t new_parse=0;    //是否有新的解码数据标志nmeaTIME beiJingTime;    //北京时间 uint8 str_buff[50];/* 设置用于输出调试信息的函数 */nmea_property()->trace_func = &trace;nmea_property()->error_func = &error;nmea_property()->info_func = &gps_info;/* 初始化GPS数据结构 */nmea_zero_INFO(&info);nmea_parser_init(&parser);while(1){//    for(int t = 0;t<256;t++){uart_putchar(DEBUG_UART,gps_rbuff[t]);}if(GPS_HalfTransferEnd)     /* 接收到GPS_RBUFF_SIZE一半的数据 */{/* 进行nmea格式解码 */nmea_parse(&parser, (const char*)&gps_rbuff[0], HALF_GPS_RBUFF_SIZE, &info);GPS_HalfTransferEnd = 0;   //清空标志位new_parse = 1;             //设置解码消息标志 }else if(GPS_TransferEnd)    /* 接收到另一半数据 */{nmea_parse(&parser, (const char*)&gps_rbuff[HALF_GPS_RBUFF_SIZE], HALF_GPS_RBUFF_SIZE, &info);GPS_TransferEnd = 0;new_parse =1;}if(new_parse)                //有新的解码消息   {    /* 对解码后的时间进行转换,转换成北京时间 */GMTconvert(&info.utc,&beiJingTime,8,1);/* 输出解码得到的信息 */// printf("\r\n时间%d-%02d-%02d,%d:%d:%d\r\n", beiJingTime.year+1900, beiJingTime.mon,beiJingTime.day,beiJingTime.hour,beiJingTime.min,beiJingTime.sec);//info.lat lon中的格式为[degree][min].[sec/60],使用以下函数转换成[degree].[degree]格式deg_lat = nmea_ndeg2degree(info.lat);deg_lon = nmea_ndeg2degree(info.lon);//       printf("\r\n纬度:%f,经度%f\r\n",deg_lat,deg_lon);
//      printf("\r\n海拔高度:%f 米 ", info.elv);
//      printf("\r\n速度:%f km/h ", info.speed);
//      printf("\r\n航向:%f 度", info.direction);
//      printf("\r\n正在使用的GPS卫星:%d,可见GPS卫星:%d",info.satinfo.inuse,info.satinfo.inview);
//      printf("\r\n正在使用的北斗卫星:%d,可见北斗卫星:%d",info.BDsatinfo.inuse,info.BDsatinfo.inview);
//      printf("\r\nPDOP:%f,HDOP:%f,VDOP:%f",info.PDOP,info.HDOP,info.VDOP);/* 显示时间日期 */sprintf(str_buff," Date:%4d/%02d/%02d ", beiJingTime.year+1900, beiJingTime.mon,beiJingTime.day);LCD_ShowString(0,2,str_buff,BLACK);sprintf(str_buff," Time:%02d:%02d:%02d", beiJingTime.hour,beiJingTime.min,beiJingTime.sec);LCD_ShowString(0,20,str_buff,BLACK);/* 正在使用的卫星 可见的卫星*/sprintf(str_buff," GPS:%2d ", info.satinfo.inuse);LCD_ShowString(150,0,str_buff,BLACK);/* 正在使用的卫星 可见的卫星*/sprintf(str_buff," BDS:%2d ", info.BDsatinfo.inuse);LCD_ShowString(150,20,str_buff,BLACK);/* 纬度 经度*/sprintf(str_buff," lat:%.6f ", deg_lat);LCD_ShowString(0,40,str_buff,BLUE);sprintf(str_buff," lon:%.6f",deg_lon);LCD_ShowString(115,40,str_buff,BLUE);/* 速度 */sprintf(str_buff," speed:%4.2f km/h", info.speed);LCD_ShowString(0,60,str_buff,RED);/* 航向 */sprintf(str_buff," Angle:%3.2f deg", info.direction);LCD_ShowString(0,80,str_buff,MAGENTA);new_parse = 0;}}
}

根据串口的内容,紧接着调用 NMEA库函数 nmea_parse 进行解码,解码的结果存放在数据结构变量 info 中,由于解码结果得到的时间信息是格林威治时间,所以在输出解码结果前,调用了 GMTconvert 函数把它转化成北京时间。

使用了 nmea_ndeg2degree 函数把 info.lat 及 info.lon 参数转化到了 deg_lat 和 deg_lon 变量中。

info.lat 及 info.lon 存储的就是纬度、 经度信息,但它们的单位是[degree][min].[sec/60]格式,即 NMEA 语句解码后的原始 ddmm.mmmm 表示的数据,通常在地图上使用的格式都是[degree].[degree], 所以一定要经过这样转换后再使用。

5-3 MM32堆栈空间设置

由于 NMEA 解码库在进行解码时需要动态分配较大的空间,所以我们需要在 MM32的启动文件 startup_mm32f327x_keil.s 文件中对堆栈空间进行修改,本工程中设置的栈空间大小设置为 0x00002000, 堆空间大小设置为 0x0000 0800。

Stack_Size      EQU     0x00002000
;这时候为8kb栈空间 实测最大调用为3264bAREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size       EQU     0x00000800AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limitPRESERVE8THUMB

关于如何查看工程中调用的最大栈空间,可以查看我之前写的博客链接:
Keil STM32查看堆栈使用量及调用链.htm文件

六、主函数调用

#include "headfile.h"
// **************************** 代码区域 ****************************int main(void)
{board_init(true);                                  //初始化 UART1 DEBUG输出串口GPS_Config();                                      //初始化 GPS   DMA加大容量栈空间Lcd_Init();   LCD_ShowString(0,0,"GPS_TEST",MAGENTA);   //初始化 IPS   ST7789屏幕    nmea_decode_test();                                 //GPS解码测试while(1){}}

在全部模块初始化结束之后,就可以在屏幕上边参数信息了,包括经纬度和时间等等。

另外:确认天线处在卫星信号良好的位置中, 天线需要正面朝上,并置于室外无遮挡物处。 若把天线置于室内,是无法定位的,卫星信号在室内基本无信号

最后工程文件我将放置在百度网盘链接: https://pan.baidu.com/s/1QRNr87n38MjN-yKf30Uiww提取码:jr2t

不足之处多多指教,工程的我是根据野火的NMEA库移植而来。dma配置部分花费的时间比较多,后来看了灵动官网的一些配置,参考而来。参数手册很重要,一些dma的通道都是从中看来的。

【灵动MM32-DMA传输-GPS解算】 移植NMEA协议库解析GGA数据格式相关推荐

  1. GPS卫星定位接收器的NMEA协议解析

    原文地址:GPS卫星定位接收器的NMEA协议解析作者:蟹蟹 GPS接收机只要处于工作状态就会源源不断地把接收并计算出的GPS导航定位信息通过串口传送到计算机中.前面的代码只负责从串口接收数据并将其放置 ...

  2. NtripShare GNSS变形监测软件、实时RTK解算、基线解算源码、GPS静态数据处理源码(七)

    动态解算完成之后,原计划增加天线和坐标系统模块,考虑到当前系统中用到的一些第三方库缠身的效率问题,思前想后,心一横把用到的所有库重写,这酸爽,就是掉坑里出不来了.... 需要吐槽一下某些第三方的库,写 ...

  3. STM32F4时钟触发ADC双通道采样DMA传输进行FFT+测频率+采样频率可变+显示波形(详细解读)...

    此文转载自:https://blog.csdn.net/qq_45620831/article/details/110819495 写在前面的婆婆妈妈的话 本人大三,参加过数次电赛,来CSDN好久, ...

  4. STM32F4时钟触发ADC双通道采样DMA传输进行FFT+测频率+采样频率可变+显示波形(详细解读)

    写在前面的婆婆妈妈的话(代码链接在最下方) 本人大三,参加过数次电赛,来CSDN好久, 每次都是在绝望中从这里找到了希望,每次都仿佛一个即将被怪兽打翻的小船突然被危险流浪者救起来.是众多前辈的智慧,让 ...

  5. 【灵动MM32-姿态角解算】移植MPU6050-DMP库实现姿态角PRY解算

    MM32使用DMP库处理MPU6050数据.姿态解算 实现途径: ①MM32F3277G9P单片机 ②MPU6050模块 ③智能车逐飞MM32开源库 ④正点原子dmp开源库 开源库链接: 逐飞科技MM ...

  6. STM32从零到一,从标准库移植到HAL库,UART串口1以DMA模式收发不定长数据代码详解+常见问题 一文解析

    前言 本文的参考资料 感谢提供标准库版本的CSDN同学:这两篇文章至少是我看过的最详细的标准库配置DMA版本.而且代码实测稳定能用. STM32 | DMA配置和使用如此简单(超详细)_...| .. ...

  7. 北斗信号服务器解算,GPS/北斗定位解算算法的研究

    摘要: 卫星导航是一种通过全球卫星导航系统(Global Navigation Satellite System,GNSS)精确的测定地球上任何一点的位置和时间的方法.目前,卫星导航接收机可提供个人定 ...

  8. MATLAB接收机位置解算,GPS-receiver GPS软件接收机代码 完整的捕获 解算定位 (可 8个通道) matlab 240万源代码下载- www.pudn.com...

    文件名称: GPS-receiver下载  收藏√  [ 5  4  3  2  1 ] 开发工具: matlab 文件大小: 148 KB 上传时间: 2015-07-02 下载次数: 0 提 供 ...

  9. GPS接收机-从射频信号到定位解算

    GNSS接收机-从特高频信号到定位解算 GPS信号历险记 天线 极化方式 抗干扰处理 射频前端 基带处理 信号搜索和捕获 跟踪 载波环 锁相环 锁频环 码环(延迟锁定环路DLL) 位同步 帧同步 定位 ...

最新文章

  1. 【ARM】ARM接口技术
  2. “重金求来”Alibaba技术官并发编程笔记,附Java面经
  3. 用python画猫咪怎么画-如何用Python实现可视化地图
  4. ABAP SUBMIT 程序时带屏幕默认值
  5. Eclipse配置注释模板的方法
  6. gitlab 构建tag_GitLab常用命令 分支 Tag 配置 操作
  7. 20分钟完成Mac上的 LNMP 环境部署,优雅·高效开发(Docker方式)
  8. 软件测试工程师核心竞争力(转)
  9. (43)System Verilog 类中变量随机化
  10. 【学生党福利】AD 学生免费许可申请
  11. 如何修改Solaris的时区信息
  12. Sum All Odd Fibonacci Numbers-freecodecamp算法题目
  13. 数字图像处理 matlab图像的几何运算 实验三 旋转 缩放 裁剪 镜像变换 平移
  14. 秃如其来第一步之安装JDK
  15. 特种浓缩分离:无机陶瓷膜设备性能描述
  16. 电脑数据信息安全常识
  17. NLP - 文本向量化
  18. Linux 学习笔记3 -- 常用 Linux 命令的基本使用
  19. 【步兵 cocos2dx】自动化测试
  20. 无法安装战网,提示007D

热门文章

  1. 安全电子签章密码技术规范_首个国家标准历时3年诞生,电子签章越来越安全...
  2. 欧姆龙温控器参数笔记(二)(初始设定菜单)
  3. Windows也有聚焦搜索了?
  4. Python 判断字符串是否包含中文汉字
  5. js正则表达式 验证手机号,email地址和邮政编码
  6. python制作萝莉御姐语音包
  7. 设置MySQL复制时,replicate-ignore-db模式下如何正常工作
  8. 静态代理和依赖注入方式获取网店管家查询仓库信息接口
  9. MES系统会采集哪些数据?数据采集方式有哪些?
  10. 结构化方法、面向对象方法的区别