完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
stm32与GPS模块的数据传输,最后把数据传回到电脑上
准备工作
模组采用中科微AT6558R定位芯片,是一-款能够以99通道接收卫星信号低功耗;高灵敏度高的G-MOUSE能够在城市、峡谷、高架下面等弱信号的地方,以及汽车内部任何位置可以快速、准确的进行定位。使得模块可广泛用于车载监控、公交车报站、车载导航、船载导航、笔记本导航等产品上。 从上图可以从看出,GPS模块是通过串口传输数据的,因此与stm32f103zet6的接法如下 [tr]GPSstm32[/tr]
GPS数据类型及格式 GPS常见类型 [tr]类别描述[/tr]
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh <1> UTC 时间,hhmmss(时分秒)格式 <2> 定位状态,A=有效定位,V=无效定位 <3>纬度ddmm.mmmm(度分)格式(前面的0也将被传输) <4> 纬度半球N(北半球)或S(南半球) <5>经度dddmm.mmmm(度分)格式(前面的0也将被传输) <6> 经度半球E(东经)或W(西经) <7>地面速率(000.0~999.9节,前面的0也将被传输) <8>地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输) <9> UTC 日期,ddmmyy(日月年)格式 <10>磁偏角(000.0~180.0度,前面的0也将被传输) <11> 磁偏角方向,E(东)或W(西) <12>模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效) $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx <1> UTC 时间,格式为hhmmss.sss; <2> 纬度,格式为ddmm.mmmm(第一位是零也将传送); <3> 纬度半球,N 或S(北纬或南纬) <4> 经度,格式为dddmm.mmmm(第一位零也将传送); <5> 经度半球,E 或W(东经或西经) <6> 定位质量指示,0=定位无效,1=定位有效; <7>使用卫星数量,从00到12(第一个零也将传送) <8>水平精确度,0.5到99.9 <9>天线离海平面的高度,-9999.9到9999.9米M指单位米 <10>大地水准面高度,-9999.9到9999.9米M指单位米 <11>差分GPS数据期限(RTCMSC-104),最后设立RTCM传送的秒数量 <12>差分参考基站标号,从0000到1023(首位0也将传送)。 $GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh <1> 以正北为参考基准的地面航向(000~359度,前面的0也将被传输) <2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输) <3> 地面速率(000.0~999.9节,前面的0也将被传输) <4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输) <5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效 $GPGSV,(1),(2),(3),(4),(5),(6),(7),…(4),(5),(6),(7)*hh(CR)(LF) 各部分含义为: (1)总的GSV语句电文数;2; (2)当前GSV语句号:1; (3)可视卫星总数:08; (4)PRN码(伪随机噪声码) 也可以认为是卫星编号 (5)仰角(00~90度):33度; (6)方位角(000~359度):240度; (7)信噪比(00~99dB):45dB(后面依次为第10,16,17号卫星的信息); *总和校验域; hh 总和校验数:78; (CR)(LF)回车,换行。 注:每条语句最多包括四颗卫星的信息,每颗卫星的信息有四个数据项,即: (4)-卫星号,(5)-仰角,(6)-方位角,(7)-信噪比。 $GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A 字段1:定位模式,A=自动手动2D/3D,M=手动2D/3D 字段2:定位类型,1=未定位,2=2D定位,3=3D定位 字段3:PRN码(伪随机噪声码),第1信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段4:PRN码(伪随机噪声码),第2信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段5:PRN码(伪随机噪声码),第3信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段6:PRN码(伪随机噪声码),第4信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段7:PRN码(伪随机噪声码),第5信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段8:PRN码(伪随机噪声码),第6信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段9:PRN码(伪随机噪声码),第7信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段10:PRN码(伪随机噪声码),第8信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段11:PRN码(伪随机噪声码),第9信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段12:PRN码(伪随机噪声码),第10信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段13:PRN码(伪随机噪声码),第11信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段14:PRN码(伪随机噪声码),第12信道正在使用的卫星PRN码编号(00)(前导位数不足则补0) 字段15:PDOP综合位置精度因子(0.5 - 99.9) 字段16:HDOP水平精度因子(0.5 - 99.9) 字段17:VDOP垂直精度因子(0.5 - 99.9) 字段18:校验值 代码部分 串口初始化部分 因为串口1用来电脑和stm32通信,所以GPS和stm32的通信选择串口2。 下面是串口2代码的初始化: void My_USART2_Init(void){ GPIO_InitTypeDef GPIO_InitStrue; USART_InitTypeDef USART2_InitStrue; NVIC_InitTypeDef NVIC_InitStrue; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_InitStrue.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出 GPIO_InitStrue.GPIO_Pin = GPIO_Pin_2; GPIO_InitStrue.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStrue); GPIO_InitStrue.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_InitStrue.GPIO_Pin = GPIO_Pin_3; GPIO_InitStrue.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_InitStrue); USART2_InitStrue.USART_BaudRate = 9600; USART2_InitStrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART2_InitStrue.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART2_InitStrue.USART_Parity = USART_Parity_No;//奇偶校验位 USART2_InitStrue.USART_StopBits = USART_StopBits_1;//停止位 USART2_InitStrue.USART_WordLength = USART_WordLength_8b;//数据位 USART_Init(USART2, &USART2_InitStrue); USART_Cmd(USART2, ENABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//打开接收中断,当接收到数据时开启中断 NVIC_InitStrue.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStrue.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStrue.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStrue); } 下面是串口2中断代码: extern short int point1; extern const short int USART2_MAX_RECV_LEN; extern char USAR2_RX_BUF[200]; extern const short int GPS_Buffer_Length; short int point1; extern struct Data Save_Data; void USART2_IRQHandler(void){ u8 res; if(USART_GetITStatus(USART2, USART_IT_RXNE)){ res = USART_ReceiveData(USART2); if(res == '$'){ point1 = 0; } USAR2_RX_BUF[point1++] = res; if(USAR2_RX_BUF[0] == '$' && USAR2_RX_BUF[4] == 'M' && USAR2_RX_BUF[5] == 'C'){ if(res == 'n'){ memcpy(Save_Data.GPS_Buffer, USAR2_RX_BUF, point1); Save_Data.isGetData = TRUE; point1 = 0; memset(USAR2_RX_BUF, 0, USART2_MAX_RECV_LEN);//Çå¿ÕÊý×é parseGpsBuffer();//½âÎöÊý¾Ý printfGpsBuffer();//´òÓ¡Êý¾Ý } } if(point1 >= USART2_MAX_RECV_LEN) { point1 = USART2_MAX_RECV_LEN; } } } GPS部分代码 解析GPS数据代码: #ifndef _GPS_//预编译 #define _GPS_ #include "sys.h" typedef struct Data { char GPS_Buffer[200];//数据接收 BOOL isGetData;//接收数据是否完成 char *UTCTime;//时间戳 char *latitude;//纬度 char *N_S;//南北 char *longitude;//经度 char *E_W;//东西 BOOL isParseData;//是否解析完成 BOOL isUsefull;//是否为有效数据位 }Data; void parseGpsBuffer(void); void printfGpsBuffer(void); #endif const short int USART2_MAX_RECV_LEN = 200; char USAR2_RX_BUF[USART2_MAX_RECV_LEN]; const short int GPS_Buffer_Length = 200; struct Data Save_Data; void parseGpsBuffer(void){ char *subString; char *subStringNext; int i = 0; if(Save_Data.isGetData) { Save_Data.isGetData = FALSE; printf("*****************rn"); printf("%s",Save_Data.GPS_Buffer); for(i = 0; i <= 6; i++){ if(i == 0){ if((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL) printf("解析错误"); } else{ subString++;//到达解析数据中逗号的下一位 if((subStringNext = strstr(subString, ",")) != NULL) { char usefullBuffer[2]; switch(i){ case 1: //利用subStringNext和subString的首地址相减来确定指针开辟空间的大小,以防指针不合法。 Save_Data.UTCTime = (char *)malloc((subStringNext - subString)*sizeof(char)); memcpy(Save_Data.UTCTime, subString, subStringNext - subString); break; case 2: memcpy(usefullBuffer, subString, subStringNext - subString); break; case 3: Save_Data.latitude = (char *)malloc((subStringNext - subString)*sizeof(char)); memcpy(Save_Data.latitude, subString, subStringNext - subString); break; case 4: Save_Data.N_S = (char *)malloc((subStringNext - subString)*sizeof(char)); memcpy(Save_Data.N_S, subString, subStringNext - subString); break; case 5: Save_Data.longitude = (char *)malloc((subStringNext - subString)*sizeof(char)); memcpy(Save_Data.longitude, subString, subStringNext - subString); break; case 6: Save_Data.E_W = (char *)malloc((subStringNext - subString)*sizeof(char)); memcpy(Save_Data.E_W, subString, subStringNext - subString); break; default: break; } subString = subStringNext; Save_Data.isParseData = TRUE; if(usefullBuffer[0] == 'A') Save_Data.isUsefull = TRUE; else if(usefullBuffer[0] == 'V') Save_Data.isUsefull = FALSE; } else{ printf("解析错误2"); } } } } } 打印GPS数据代码到串口调试助手上: void printfGpsBuffer(void){ if(Save_Data.isParseData){ Save_Data.isParseData = FALSE; printf("Save_Data.UTCTime = %srn", Save_Data.UTCTime);//打印数据 free(Save_Data.UTCTime);//释放空间 if(Save_Data.isUsefull){ Save_Data.isUsefull = FALSE; printf("Save_Data.latitude = %srn", Save_Data.latitude); free(Save_Data.latitude); printf("Save_Data.N_S = %srn", Save_Data.N_S); free(Save_Data.N_S); printf("Save_Data.longitude = %srn", Save_Data.longitude); free(Save_Data.longitude); printf("Save_Data.E_W = %srn", Save_Data.E_W); free(Save_Data.E_W); } else { printf("GPS DATA is not usefull!rn"); } } } 数据展示 上图就是经过解析提取到的GPRMC数据,把经纬度输入到地图上就可以查看具体位置了。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1614 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1541 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
682 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1592 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 00:51 , Processed in 0.719915 second(s), Total 49, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号