Data transfer between stm32 and GPS module, and finally transfer the data back to the computer

Data transfer between stm32 and GPS module, and finally transfer the data back to the computer

Ready to work

  1. One stm32f103zet6 development board
  2. One gps module (model G28Z2FTTL)
  3. Serial debugging assistant
  4. Several Dupont lines

GPS (G28Z2FTTL) module introduction

The module uses Zhongke Micro AT6558R positioning chip, which is a type that can receive satellite signals with 99 channels and low power consumption; the high sensitivity and high G-MOUSE can be used in weak signal places such as cities, canyons, elevated highways, and any vehicle interior The location can be located quickly and accurately. The module can be widely used in products such as vehicle monitoring, bus station reporting, vehicle navigation, ship navigation, and notebook navigation.
Insert picture description here

It can be seen from the above figure that the GPS module transmits data through the serial port, so the connection with stm32f103zet6 is as follows

GPS stm32
VCC VCC (5V or 3.3V)
GND GND
TXD RXD (PA3 pin)
RXD TXD (PA2 pin)

Here GPS and stm32 are transmitted through USART2.

GPS data type and format

Common types of GPS

category description
GPGSV Visible satellite information
GPRMC Recommended minimum positioning information
GPVTG Ground speed information
GPGGA GPS positioning information
GPGSA Current satellite information

Data Format

$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<CR><LF> 
  <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:校验值
————————————————
版权声明:本文为CSDN博主「靑い空゛」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_17308321/article/details/80714560

Code part

Serial port initialization part

Because the serial port 1 is used for communication between the computer and stm32, the communication of GPS and stm32 selects serial port 2.
The following is the initialization of the serial port 2 code:

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);
}

The following is the serial port 2 interrupt code:

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 part of the code

Parse GPS data code:

#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("*****************\r\n");
		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");
					}
				}
			}
		}
}

Print GPS data code to the serial port debugging assistant:

void printfGpsBuffer(void){
    
    
	if(Save_Data.isParseData){
    
    
		Save_Data.isParseData = FALSE;
		printf("Save_Data.UTCTime = %s\r\n", Save_Data.UTCTime);//打印数据
		free(Save_Data.UTCTime);//释放空间
		
		if(Save_Data.isUsefull){
    
    
			Save_Data.isUsefull = FALSE;
			printf("Save_Data.latitude = %s\r\n", Save_Data.latitude);
			free(Save_Data.latitude);
			printf("Save_Data.N_S = %s\r\n", Save_Data.N_S);
			free(Save_Data.N_S);
			printf("Save_Data.longitude = %s\r\n", Save_Data.longitude);
			free(Save_Data.longitude);
			printf("Save_Data.E_W = %s\r\n", Save_Data.E_W);
			free(Save_Data.E_W);
		}
		else
		{
    
    
			printf("GPS DATA is not usefull!\r\n");
		}
	}
}

Data Display

Insert picture description here
The above picture is the GPRMC data extracted after analysis. Enter the latitude and longitude on the map to view the specific location.
This is a small program to directly view the location by entering the latitude and longitude ===> :ryeb

参考文献:
1、https://blog.csdn.net/weixin_42827999/article/details/93530544?utm_source=app&app_version=4.5.2
2、https://blog.csdn.net/qq_17308321/article/details/80714560

Guess you like

Origin blog.csdn.net/weixin_47888745/article/details/114983398