程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> c語言解碼GPS--實現篇

c語言解碼GPS--實現篇

編輯:關於C語言

  通過自己這幾天的努力終於把GPS數據全部進行了解碼,相信看了我的日志的人也期待了好久,資源在於分享,才能獲得進步;相對於網上直接調用接口不同的是從C的方向解決問題能讓問題更加的清晰,本設計芯片采用的是聯星的CC550-BG模塊,滿足大多數芯片性能,系統是在LINUX系統下面實現,選用ttyS0節點,根據不同借口,串口線選擇的是RS-232,相信大家也有所了解,詳細的請看我代碼,都有詳細的解釋,希望幫到大家,這裡我只解析了GPRMC格式的編碼,大家也可以把其他幾種格式的編碼解析同樣解析出來,只要在read_data()函數裡面strncmp()的array數組改變名稱就可以,可以把他寫成Switch格式的解碼選擇器,好了廢話不多說,貼上我的代碼!

[html] 
#include <stdio.h>      /*標准輸入輸出定義*/ 
#include <stdlib.h>     /*標准函數庫定義*/ 
#include <unistd.h>     /*Unix 標准函數定義*/ 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <errno.h> 
#include <string.h> 
#include <fcntl.h> 
#include <termios.h> 
 
//#define  dev  "/dev/ttyS0" 
#define  BUFF_SIZE 512 
#define  MAX_COM_NUM 3 
 
int  SectionID=0,i=0; 
 
 struct data 

    char GPS_time[20];          //UTC時間 
    char GPS_sv;               //使用衛星 
    char GPS_wd[12];           //緯度 
    char GPS_jd[12];           //經度 
    //char GPS_warn;             //定位警告  
    char GPS_speed[5];         //速度 
    char GPS_date[8];          //UTC日期           
         
}GPS_DATA; 
 
 
 
int set_com_config(int fd,int baud_rate,int data_bits,char parity,int stop_bits) 

    struct termios new_cfg,old_cfg; 
    int speed; 
    //保存並測試現有串口參數設置,在這裡如果串口號出錯,會有相關的出錯信息 
     
    if(tcgetattr(fd,&old_cfg)!=0) 
    { 
        perror("tcgetattr"); 
        return -1; 
    } 
     tcflush(fd, TCIOFLUSH); 
    new_cfg=old_cfg; 
    cfmakeraw(&new_cfg);//配置為原始模式 
    new_cfg.c_cflag&=~CSIZE; 
 
    //設置波特率 
    switch(baud_rate) 
    { 
        case 2400: 
        { 
            speed = B2400; 
            break; 
        } 
        case 4800: 
        { 
            speed = B4800; 
            break; 
        } 
        case 9600: 
        { 
            speed = B9600; 
            break; 
        } 
        case 19200: 
        { 
            speed = B19200; 
            break; 
        } 
        case 38400: 
        { 
            speed = B38400; 
            break; 
        } 
        case 115200: 
        { 
            speed = B115200; 
            break;  
        } 
         
 
    } 
    cfsetispeed(&new_cfg,speed); 
    cfsetospeed(&new_cfg,speed); 
    //設置數據位 
 
    switch(data_bits) 
    { 
        case 7: 
        { 
            new_cfg.c_cflag|=CS7; 
            break; 
        } 
         
        case 8: 
        { 
            new_cfg.c_cflag|=CS8; 
            break; 
        } 
         
    } 
 
    //設置停止位 
    switch(stop_bits) 
    { 
        case 1: 
        { 
            new_cfg.c_cflag &=~CSTOPB; 
            break; 
        } 
 
        case 2: 
        { 
            new_cfg.c_cflag |=CSTOPB; 
            break; 
        } 
         
         
    } 
 
    //設置奇偶校驗位 
    switch(parity) 
    { 
        case 'o': 
        case 'O': 
        { 
            new_cfg.c_cflag|=(PARODD|PARENB); 
            new_cfg.c_iflag|=(INPCK |ISTRIP); 
            break; 
        } 
        case 'e': 
        case 'E': 
        { 
            new_cfg.c_cflag |=PARENB; 
            new_cfg.c_cflag &=~PARODD; 
            new_cfg.c_iflag |=(INPCK | ISTRIP); 
            break; 
        } 
        case 's': 
        case 'S': 
        { 
            new_cfg.c_cflag &=~PARENB; 
            new_cfg.c_cflag &=~CSTOPB; 
            break; 
        } 
         
        case 'n': 
        case 'N': 
        { 
            new_cfg.c_cflag &=~PARENB; 
            new_cfg.c_iflag &=~INPCK; 
            break; 
        } 
         
    } 
 
        new_cfg.c_cc[VTIME] =10; 
    new_cfg.c_cc[VMIN] =5; 
    //處理未接收字符 
     tcflush(fd,TCIFLUSH); 
      
    if((tcsetattr(fd,TCSANOW,&new_cfg))!=0) 
    { 
        perror("tcsetattr"); 
        return -1; 
    } 
     
    return 0; 

 
 
//打開串口函數 
int open_port(int com_port) 

    int fd; 
    #if (COM_TYPE == GNR_COM)  //使用普通串口 
         char* dev[] = {"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"}; 
    #else//使用USB轉串口 
         char* dev[] = {"/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2"}; 
    #endif 
        if((com_port<0)||(com_port > MAX_COM_NUM)) 
        { 
            return -1; 
        } 
        //打開串口 
        if((fd=open(dev[com_port-1],O_RDWR|O_NOCTTY|O_NDELAY))<0) 
        { 
            perror("open serial port"); 
            return -1; 
        } 
        //恢復串口為堵塞狀態 
        if(fcntl(fd,F_SETFL,0) <0 ) 
        { 
            perror("fcntl F_SETFL\n"); 
            return -1; 
             
        } 
        //測試是否為終端設備 
        if(isatty(STDIN_FILENO)==0) 
        { 
            perror("standard input is not a terminal device"); 
        } 
        return fd; 

 
void print_info(void) 

    //打印選擇界面,即引導的字符號 
    printf("Now the receive time is %s\n",GPS_DATA.GPS_time); 
    printf("The star is %c 3\n",GPS_DATA.GPS_sv); 
    printf("The earth latitude is :%s\n",GPS_DATA.GPS_wd); 
    printf("The earth longitude is :%s\n",GPS_DATA.GPS_jd);  
    printf("The train speed is:%s km/h\n",GPS_DATA.GPS_speed); 
    printf("The date is:%s\n",GPS_DATA.GPS_date); 
     

 
 
void GPS_resolve_GPRMC(char data) 

//$GPRMC,092427.604,V,4002.1531,N,11618.3097,E,0.000,0.00,280812,,E,N*08 
 
     
    if(data==',') 
    { 
        ++SectionID; 
        i=0; 
    } 
    else 
    { 
        switch(SectionID) 
        { 
            case 1://02:48:13        
                    GPS_DATA.GPS_time[i++]=data;         
                    if(i==2 || i==5) 
                    {        
                        GPS_DATA.GPS_time[i++]=':';      
                    }                
                    GPS_DATA.GPS_time[8]='\0'; 
                break; 
            case 2: 
                if(data=='A') 
                    GPS_DATA.GPS_sv='>'; 
                else 
                    GPS_DATA.GPS_sv='<'; 
                break; 
            case 3://3158.4608 
                    GPS_DATA.GPS_wd[++i]=data;   
                    GPS_DATA.GPS_wd[12]='\0';                    
                break; 
                 
            case 4: 
                if(data=='N') 
                    GPS_DATA.GPS_wd[0]='N'; 
                else if(data=='S') 
                    GPS_DATA.GPS_wd[0]='S'; 
             
                break; 
            case 5://11848.3737,E 
                 
                    GPS_DATA.GPS_jd[++i]=data;   
                    GPS_DATA.GPS_jd[12]='\0'; 
                break; 
                 
            case 6: 
                if(data=='E') 
                    GPS_DATA.GPS_jd[0]='E'; 
                else if(data=='W') 
                    GPS_DATA.GPS_jd[0]='W'; 
                 
                break; 
            case 7://10.05 
                    GPS_DATA.GPS_speed[i++]=data; 
                    GPS_DATA.GPS_speed[4]='\0';                      
                break; 
            case 9://15-07-06 -> 06-07-15 
                    GPS_DATA.GPS_date[i++]=data;     
                    if(i==2 || i==5)                         
                    { 
                        GPS_DATA.GPS_date[i++]='-'; 
                    }                                
                    GPS_DATA.GPS_date[8]='\0';                   
                break; 
        } 
    }        
 

 
void read_data(int fd) 

    char buffer[BUFF_SIZE],dest[1024];    
    char array[10]="$GPRMC"; 
    int  res,i=0,j=0,k; 
    int data=1,len=0; 
    memset(dest,0,sizeof(dest)); 
     
do 
{     
     memset(buffer,0,sizeof(buffer)); 
//$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50 
        if(res=read(fd,buffer,1)>0) 
        {        
                //此處源源不斷傳入參數,一次讀到數據可能為($GPRMC,024),res為讀到長度,現在把每一位傳入函數處理;    
            strcat(dest,buffer); 
            if(buffer[0]=='\n') 
            { 
                i=0; 
                if(strncmp(dest,array,6)==0) 
                {                
                        printf("%s",dest); 
                        len=strlen(dest); 
                        for(k=0;k<len;k++) 
                        { 
                            GPS_resolve_GPRMC(dest[k]); 
                        }        
                            SectionID=0; 
                             
                        print_info(); 
                } 
                bzero(dest,sizeof(dest)); 
            } 
                 
        } 
}while(1); 
    close(fd); 
 

 
int main(int argc,char*argv[]) 
{        
        int fd=0;       
        int HOST_COM_PORT=1;      
        fd=open_port(HOST_COM_PORT); 
        if(fd<0)  
        { 
             perror("open fail!"); 
        } 
        printf("open sucess!\n"); 
        if((set_com_config(fd,9600,8,'N',1))<0)   
        { 
            perror("set_com_config fail!\n"); 
        } 
        printf("The received worlds are:\n"); 
        read_data(fd); 
     return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved