提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

  • 目录

    前言:

    一、使用HAL库生成代码

             1、HAL库设置

    二、程序编写

    1.串口

    2.gps.c

           GPS.h

    3、串口1开启接收

    4、main.c

    总结


  • 前言:

    使用stm3f103c8t6, GPS是NEO-6M

    一、使用HAL库生成代码

             1、HAL库设置

                        选择使用的芯片

                            

                         基础配置及打开串口

                            

     

     

     

     

     

    二、程序编写

    1.串口

       串口1用来和电脑通讯,串口2用来和GPS模块通讯,波特率设置为9600

        printf重定向

       在usart.c中添加这个函数

    #include "stdio.h"
    #include "string.h"
    
    int fputc(int ch, FILE *f)
    {
        HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
        return ch;
    }
    
    /**
      * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
      * 输入参数: 无
      * 返 回 值: 无
      * 说    明:无
      */
    int fgetc(FILE * f)
    {
        uint8_t ch = 0;
        while(HAL_UART_Receive(&huart1,&ch, 1, 0xffff)!=HAL_OK);
        return ch;
    }
    串口2波特率为9600
    void MX_USART2_UART_Init(void)
    {
    
      huart2.Instance = USART2;
      huart2.Init.BaudRate = 9600;  //这里程序中默认为115200 
      huart2.Init.WordLength = UART_WORDLENGTH_8B;
      huart2.Init.StopBits = UART_STOPBITS_1;
      huart2.Init.Parity = UART_PARITY_NONE;
      huart2.Init.Mode = UART_MODE_TX_RX;
      huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart2.Init.OverSampling = UART_OVERSAMPLING_16;
      if (HAL_UART_Init(&huart2) != HAL_OK)
      {
        Error_Handler();
      }
    
    }
    

    2.gps.c

    代码如下(示例):

    #include "gps.h"
    #include "stdio.h"     
    #include "stdarg.h"     
    #include "string.h"     
    #include "math.h"
    
    
        
    //m^n函数
    //返回值:m^n次方.
    uint32_t NMEA_Pow(uint8_t m,uint8_t n)
    {
        uint32_t result=1;     
        while(n--)result*=m;    
        return result;
    }
    
    void Andly_GPS(Mgps_msg *Mgps,uint8_t *buf)//解析定位信息
    {
        uint16_t i=0,j=0,k=0;
        uint8_t *p1,dx;
        uint32_t temp;
        float rs;
        p1 = strstr((const char *)buf,"RMC");
    //    char *json_buff;
        if(buf[0]==0) buf[0]=1;//防止有时候首字节为0 出现解析失败
        buf=strstr((const char *)buf,"RMC");
            if(strstr((const char *)buf,"RMC")!=NULL)
            {
                buf=strstr((const char *)buf,",A");    
                
                i=NMEA_Comma_Pos(buf,2);//第N个逗号所在位置
                j=i;k=i;
                for(i;i<i+10;i++)
                {
                    if(buf[i]==',') break;
                    Mgps->latitude[i-j]=buf[i];//维度
                    if(buf[i]!='.')Mgps->lat[i-k]=buf[i];//维度
                    else k=k+1;
                }
                
                i=NMEA_Comma_Pos(buf,1);//第N个逗号所在位置
                j=i;k=i;
                for(i;i<i+20;i++)
                {
                    if(buf[i]==',') break;
                    Mgps->Location[i-j]=buf[i];//定位A V
                    if(buf[i]!='.')Mgps->lat[i-k]=buf[i];//维度
                    else k=k+1;
                }
                
                i=NMEA_Comma_Pos(buf,4);//第N个逗号所在位置
                j=i;k=i;
                for(i;i<i+11;i++)
                {
                    if(buf[i]==',') break;
                    Mgps->longitude[i-j]=buf[i];//经度
                    if(buf[i]!='.')Mgps->lon[i-k]=buf[i];//经度
                    else k=k+1;
                }
                
            }
        
    }
    uint8_t NMEA_Comma_Pos(uint8_t *buf,uint8_t cx)
    {                 
        uint8_t *p=buf;
        while(cx)
        {         
            if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//遇到'*'或者非法字符,则不存在第cx个逗号
            if(*buf==',')cx--;
            buf++;
        }
        return buf-p;     
    }
    
    //str转换为数字,以','或者'*'结束
    //buf:数字存储区
    //dx:小数点位数,返回给调用函数
    //返回值:转换后的数值
    int NMEA_Str2num(uint8_t *buf,uint8_t*dx)
    {
        uint8_t *p=buf;
        uint32_t ires=0,fres=0;
        uint8_t ilen=0,flen=0,i;
        uint8_t mask=0;
        int res;
        while(1) //得到整数和小数的长度
        {
            if(*p=='-'){mask|=0X02;p++;}//是负数
            if(*p==','||(*p=='*'))break;//遇到结束了
            if(*p=='.'){mask|=0X01;p++;}//遇到小数点了
            else if(*p>'9'||(*p<'0'))    //有非法字符
            {    
                ilen=0;
                flen=0;
                break;
            }    
            if(mask&0X01)flen++;
            else ilen++;
            p++;
        }
        if(mask&0X02)buf++;    //去掉负号
        for(i=0;i<ilen;i++)    //得到整数部分数据
        {  
            ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');
        }
        if(flen>5)flen=5;    //最多取5位小数
        *dx=flen;             //小数点位数
        for(i=0;i<flen;i++)    //得到小数部分数据
        {  
            fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');
        } 
        res=ires*NMEA_Pow(10,flen)+fres;
        if(mask&0X02)res=-res;           
        return res;
    }
    
    

           GPS.h

    
    
    
    #ifndef __gps_H
    #define __gps_H
    
    
    #include "main.h"
    #include "string.h"
    #include "stdio.h"
    #include "usart.h"
    typedef struct  
    {                                            
        uint8_t latitude[10];                //纬度 
        uint8_t longitude[11];            //经度     
        uint8_t Location[1];            //定位有效A 定位无效V 
        
        uint8_t lat[20];                //纬度 
        uint8_t lon[20];
    
        uint8_t latt;    //经度     
    }Mgps_msg; 
    extern  Mgps_msg Mgps;
    
    
    
    
    void Andly_GPS(Mgps_msg *Mgps,uint8_t *buf);    
    uint8_t NMEA_Comma_Pos(uint8_t *buf,uint8_t cx);
    void Gps_Msg_Show(void);//显示GPS定位信息 
    int NMEA_Str2num(uint8_t *buf,uint8_t*dx);
    
    
    #endif 
    

    3、串口1开启接收

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
    {		 
    	if(huart->Instance == USART2)
    		{
    //			HAL_UART_Transmit(&huart1,OTA_buff,1,100);//串口1发送接收buff里的东西	
    			HAL_UART_Receive_IT(&huart2,USART2_RX_BUF,1);	//重新开启串口3接收中断
    					
    			if(USART2_RX_STA<1023)	//还可以接收数据
    			{
    				
    				OTA_buff[USART2_RX_STA]=USART2_RX_BUF[0];	
    				USART2_RX_STA++;	//记录接收到的值	
    				if(strstr((const char *)OTA_buff,"RMC")!=NULL) 
    				{
    					GPS_flag =1;//接到RMC
                    
    				}
    
     				
    			}
    
    		}
    }
    

    4、main.c

    HAL_UART_Receive_IT(&huart2,USART2_RX_BUF,1);
    	  if(GPS_flag ==1){
    	  
    			Andly_GPS(&Mgps,OTA_buff);	
    			char *la= NULL; 
    			la = Mgps.latitude;	
    			printf("纬度:");			
    			printf("\r\n%s\r\n",Mgps.latitude);
    			char *lo= NULL;
    			lo = Mgps.longitude;
    			printf("经度:");
    			printf("\r\n%s\n",Mgps.longitude);
    			HAL_Delay(100);
    	  
    	  
    	  
    	  
    	  }
    

    总结

    解析到的GPS存放在Mgps.longitude和Mgps.latitude中

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32GPS定位 NEO_6M

    发表评论