欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

基于 stm32 的 GPS 数据解析

最编程 2024-04-25 22:12:57
...

目录

1.GPS模块

2.GPS发送的数据格式

3.软件设计

3.1配置好串口

3.2然后写串口中断函数

效果


 

1.GPS模块

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aS56I-c5aW26buE5YyF,size_20,color_FFFFFF,t_70,g_se,x_16

2.GPS发送的数据格式

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
<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=数据无效          <CR><LF>表示回车和换行

3.软件设计

3.1配置好串口

void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
     //USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 
}

3.2然后写串口中断函数

当串口接收到数据后,我们用$符号记录每条信息的开始,用K记录逗号的位置,便于解析数据

这里解析的是gprmc中的经纬度速度和gpgga里的高度;

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	    u8 res; 
		res =USART_ReceiveData(USART1);	//读取接收到的数据
		if(res=='$'||USART_RX_BUF[0]=='$')
		{
			if(res=='$')
			i=0;
			USART_RX_BUF[i]=res;
			i++;
		}			
if(USART_RX_BUF[4]=='M'&&USART_RX_BUF[5]=='C')
			{	
			if(res==',')
    	k++;
		switch(k)
		{
			case 2:
				if(res=='A'&&res!=',')
					flag=1;
				else 
					flag=0;
			break;
			case 3:
				if(flag==1&&res!=','&&res!='.')
				{	longitude*=10;
				  longitude+=res-48;}
				break;
			case 5:
				if(flag==1&&res!=','&&res!='.')
				{latitude*=10;
				 latitude+=res-48;}
				break;
		  case 7:
				if(flag==1&&res!=','&&res!='.')
				{	speed*=10;
				  speed+=res-48;}
				  break;
		
		}
		}		
		if(USART_RX_BUF[4]=='G'&&USART_RX_BUF[5]=='A')
			{	
			if(res==',')
    	    p++;
		switch(p)
		{			
			case 9:
				if(res!=','&&res!='.')
				{
				 high*=10;
				 high+=res-48;
				 }
				 break;				
		}		
		
			
if(res==0x0A)
		{  
		  memset(USART_RX_BUF,0x00,200);
			i=0;
			k=0;			
			a=longitude/10000000;
			b=latitude/10000000;
			c=speed/10*0.5144;
	  	printf("longitude: %f\r\n",a);
		  printf("latitude: %f\r\n",b);
		  printf("speed: %f\r\n",c);
			 printf("high: %f\r\n",high/100);
			longitude=0;
			latitude=0;
			speed=0;
			
		}		
		}						

}

解析完数据化,打印数据;

效果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aS56I-c5aW26buE5YyF,size_20,color_FFFFFF,t_70,g_se,x_16