迪文科技论坛

 找回密码
 立即注册
搜索
查看: 405|回复: 2

【开源】车载北斗 GPS 定位 更新时间

[复制链接]

9

主题

15

回帖

896

积分

高级会员

Rank: 4

积分
896
QQ
发表于 2024-7-15 09:04:41 | 显示全部楼层 |阅读模式
视频效果如下:
https://v.youku.com/v_show/id_XNjQwNjE4MTI2OA==.html

不需要通过网络,或者手动去更新时间,直接通过北斗卫星校时,不管的地球的哪个角落,都能够收到时间和定位

使用了北斗GPS 双模定位模块,屏幕代码使用的迪文的82 83指令代码为基础,可以过DGUS_V7624 的串口下载功能,直接更新代码,
下载13 14.bin使用上极其方便,不能频繁拔插TF卡,就是爽。
电脑通过串口2进行下载,串口4接北斗模块 。直接卫星去更新时间,非常的精准。


界面上比较简单,






屏幕代码如下:
Main.c 主要是负责总体框架

       INIT_CPU();  //系统初始化
       PORT_Init();//IO口初始化

       T0_Init();//定时器0初始化
//     T1_Init();
       T2_Init();//定时器2初始化
//     WDT_ON();           //打开开门狗 喂狗在定时器T2中      
       my_UART4_Init(115200);
       uart_init();//串口初始化

ws2812_writ_byte(8); //LED初始化
//     data_save_init();//数据改变自动保存初始化
       BeiDouInit();
       ChangePage(1);

       while(1){
              Uart_Handle_all();
              OneMsHandle();//1Ms一次

   Read_0xF00();//数据自动上传
//            data_change_sava();//数据改变自动保存

       }


BdidouGPS.c 负责北斗接收代码的框架处理

nmea_msg gpsx;

u8 HasUpdateTime=1;
u8 handUpdateTime=0;
u8 LoaUpdateTimeCrc=0;
//u8 JunHaoWarn=0;
u16 ReadTimeDelay=0;
u8 BeiDouCanDis=0;
u8 Timer3DelayZ=0;
u8 Gps_On=0;

void BeiDouInit(void)
{
       u16BeiDouTimeInit=0;
       constchar *BeidouBate="$PCAS01,5*19\r\n";
       constchar *BeidouSetting="$PCAS03,1,0,0,1,1,0,0,1,0,0,,,0,0*02\r\n";
       charcmdbuf1[50] = "$PCAS02,1000*2E\r\n";    /*NMEA command, write(fd, cmdbuf, strlen(cmdbuf)); */

//     PushSysInfo(BeiDouModuleInfo,(u8*)"北斗:初始化",DevNoOper);
       //设置定位信息更新速度为5Hz,顺便判断GPS模块是否在位.
       BeiDouTimeInit=0;

       my_UART4_Init(9600);
       delay_ms(1000);
       SkyTra_Send_Date((u8*)BeidouBate,strlen(BeidouBate));
       delay_ms(300);
       SkyTra_Send_Date((u8*)BeidouBate,strlen(BeidouBate));
       delay_ms(200);
       my_UART4_Init(115200);

//     printf("S1216F8-BDSetting...");
       do
       {
              delay_ms(500);
              BeiDouTimeInit++;
              if(BeiDouTimeInit>2)
              {
//                   DevERR_TORecord(Dev_Gps_Err);
//                   PushSysInfo(BeiDouModuleInfo,(u8*)"北斗:离线",DevErrorInfo);
                     BeiDouCanDis=1;
                     BeiDouTimeInit=0;
                     break;
              }
       }
       while((uart4_rx_count&0X7FFF)<10);//配置SkyTraF8-BD的更新速率为5Hz
//     DelDevErr_Record(Dev_Gps_Err);
//     PushSysInfo(BeiDouModuleInfo,(u8*)"正常",DevOk);
//     DMT_LenOne(DMTDisplay_ID,0x180b,1);
//char cmdbuf[] ="$PCAS03,1,0,0,1,1,0,0,1,0,0,,,0,0*02\r\n";    /* NMEA command, write(fd, cmdbuf, strlen(cmdbuf)); */
       SkyTra_Send_Date((u8*)BeidouSetting,strlen(BeidouSetting));
       SkyTra_Send_Date((u8*)cmdbuf1,strlen(cmdbuf1));

       delay_ms(500);
//     if(g_stDataTotal.SysGPSOpen)
//     {
              memset(cmdbuf1,0,sizeof(cmdbuf1));
              strcpy(cmdbuf1,"$PCAS04,3*1A\r\n");
              Gps_On=1;
//     }
//     else
//     {
//            memset(cmdbuf1,0,sizeof(cmdbuf1));
//            strcpy(cmdbuf1,"$PCAS04,2*1B\r\n");
//            Gps_On=0;
//     }
       SkyTra_Send_Date((u8*)cmdbuf1,strlen(cmdbuf1));
       delay_ms(500);

       BeiDouCanDis=1;
}
void UTCToBeijing(unsigned intUTCyear,unsigned char UTCmonth,unsigned char UTCday,
                                                               unsignedint UTChour,unsigned char UTCminute,unsigned char UTCsecond)
{
              intyear=0,month=0,day=0,hour=0;
   int lastday = 0;// 月的最后一天日期
//   int lastlastday = 0;//上月的最后一天日期

         year=UTCyear;
              month=UTCmonth;
         day=UTCday;
         hour=UTChour+8;//UTC+8转换为北京时间

         if(month==1 || month==3 || month==5 ||month==7 || month==8 || month==10 || month==12)
              {
       lastday = 31;
       if(month == 3)
                            {
//           if((year%400 == 0)||(year%4 ==0 && year%100 != 0))//判断是否为闰年
//                lastlastday = 29;//闰年的2月为29天,平年为28天
//            else
//                lastlastday = 28;
       }
//       if(month == 8)
//            lastlastday = 31;
    }
   else
              if(month== 4 || month == 6 || month == 9 || month == 11)
              {
       lastday = 30;
//       lastlastday = 31;
    }
   else
              {
//       lastlastday = 31;
       if((year%400 == 0)||(year%4 == 0 && year%100 != 0))//闰年的2月为29天,平年为28天
           lastday = 29;
       else
           lastday = 28;
    }
              if(hour>= 24)//当算出的时大于或等于24:00时,应减去24:00,日期加一天
              {
                            hour-= 24;
                            day+= 1;
                            if(day> lastday)//当算出的日期大于该月最后一天时,应减去该月最后一天的日期,月份加上一个月
                            {
                                          day-= lastday;
                                          month+= 1;

                                          if(month> 12)//当算出的月份大于12,应减去12,年份加上1年
                                          {
                                                        month-= 12;
                                                        year+= 1;
                                          }
                            }
              }

              gpsx.utc.year=year;
              gpsx.utc.month=month;
              gpsx.utc.date=day;
              gpsx.utc.hour=hour;

//            sprintf((char*)bjttbuf,"%02d/%02d/%02d,%02d:%02d:%02d",
//                                               year-2000,month,day,hour,gpsx.utc.min,gpsx.utc.sec);    //UTC日期时分秒转换成北京时间
}


void DispTimeUpdate(void)
{
       u8buff[32];
       intyear,month,date,hour,min,sec;

       if(!gpsx.UtcTimeOK)
              return;
       UTCToBeijing(gpsx.utc.year,gpsx.utc.month,gpsx.utc.date,
                                                 gpsx.utc.hour,gpsx.utc.min,gpsx.utc.sec);

       memset(buff,0,sizeof(buff));
       year=gpsx.utc.year;
       month=gpsx.utc.month;
       date=gpsx.utc.date;
       hour=gpsx.utc.hour;
       min=gpsx.utc.min;
       sec=gpsx.utc.sec;

       sprintf(buff,"%04d-%02d-%02d%02d:%02d:%02d",
                                                                                           year,
                                                                                           month,
                                                                                           date,
                                                                                           hour,
                                                                                           min,
                                                                                           sec);

       write_dgusii_vp(0x3000,buff,11);
}

void BeiDouTianxian(void)
{
       char*beidoutian=0;

       if(BeiDouAntST==ANT_OPEN)
       {
              beidoutian="天线未插入  ";
       }
       elseif(BeiDouAntST==ANT_OK)
       {
              beidoutian="天线已经插入  ";
       }
       else
       {
              beidoutian="天线有问题  ";
       }

       write_dgusii_vp(0x3100,beidoutian,strlen(beidoutian)/2);
}

void Gps_Msg_Show(void)
{
       u8dtbuf[32][2];                                                           //打印缓存器
       floattp;
       inttemp=0;

       DispTimeUpdate();

       tp=gpsx.longitude;         
       memset(dtbuf,0,sizeof(dtbuf));
       sprintf((char*)dtbuf,"经度:%.5f %1c    ",tp/=100000,gpsx.ewhemi);      //得到经度字符串
       write_dgusii_vp(0x3020,dtbuf,16);

       tp=gpsx.latitude;      
       memset(dtbuf,0,sizeof(dtbuf));
       sprintf((char*)dtbuf,"纬度:%.5f %1c   ",tp/=100000,gpsx.nshemi);  //得到纬度字符串
       write_dgusii_vp(0x3040,dtbuf,16);

       memset(dtbuf,0,sizeof(dtbuf));
       tp=gpsx.altitude;      
       sprintf((char*)dtbuf,"海拔高度:%.1fm     ",tp/=10);                                //得到高度字符串
       write_dgusii_vp(0x3060,dtbuf,16);

       memset(dtbuf,0,sizeof(dtbuf));
       tp=gpsx.speed;        
       sprintf((char*)dtbuf,"运行速度:%.3fkm/h     ",tp/=1000);                               //得到速度字符串
       write_dgusii_vp(0x3080,dtbuf,16);

       temp=gpsx.posslnum;
       memset(dtbuf,0,sizeof(dtbuf));
       sprintf((char*)dtbuf,"北斗GPS定位卫星:%02d 颗",temp);                   //用于定位的GPS卫星数
       write_dgusii_vp(0x30A0,dtbuf,16);

       temp=gpsx.svnum;
       memset(dtbuf,0,sizeof(dtbuf));
       sprintf((char*)dtbuf,"GPS可见卫星:%02d 颗",temp%100);                    //可见GPS卫星数
       write_dgusii_vp(0x30C0,dtbuf,16);

       temp=gpsx.beidou_svnum;
       memset(dtbuf,0,sizeof(dtbuf));
       sprintf((char*)dtbuf,"北斗可见卫星:%02d 颗",temp%100);                    //可见北斗卫星数
       write_dgusii_vp(0x30E0,dtbuf,16);

       BeiDouTianxian();
}



void GPS_BeiDouHandle(void)
{
       memset(&gpsx,0,sizeof(gpsx));

       GPS_Analysis(&gpsx,Uart4_Rx);//分析字符串
       Gps_Msg_Show();

       memset(Uart4_Rx,0,sizeof(Uart4_Rx));
       uart4_rx_count=0;
}


Gps.c 主要处理分析接收到的数据

#include "gps.h"
//#include "led.h"
//#include "delay.h"                                                                                                        
#include "stdio.h"   
#include "stdarg.h"      
#include "string.h"  
#include "sys.h"     
#include "overTime.h"

#define USART2_MAX_SEND_LEN                    1024

const u32BAUD_id[9]={4800,9600,19200,38400,57600,115200,230400,460800,921600};//模块支持波特率数组
//从buf里面得到第cx个逗号所在的位置
//返回值:0~0XFE,代表逗号所在位置的偏移.
//      0XFF,代表不存在第cx个逗号                                                
u8 NMEA_Comma_Pos(u8 *buf,u8 cx)
{                     
       u8*p=buf;
       while(cx)
       {              
              if(*buf=='*'||*buf<''||*buf>'z')return 0XFF;//遇到'*'或者非法字符,则不存在第cx个逗号
              if(*buf==',')cx--;
              buf++;
       }
       returnbuf-p;   
}
//m^n函数
//返回值:m^n次方.
u32 NMEA_Pow(u8 m,u8 n)
{
       u32result=1;   
       while(n--)result*=m;   
       returnresult;
}

//m^n函数
//返回值:m^n次方.
double NMEAdoule_Pow(double m,u8 n)
{
       doubleresult=1;     
       while(n--)result*=m;   
       returnresult;
}


//str转换为数字,以','或者'*'结束
//buf:数字存储区
//dx:小数点位数,返回给调用函数
//返回值:转换后的数值
s32 NMEA_Str2num(u8 *buf,u8*dx)
{
       u8*p=buf;
       u32ires=0,fres=0;
       u8ilen=0,flen=0,i;
       u8mask=0;
       s32res;
       while(1)//得到整数和小数的长度
       {
              if(*p=='-'){mask|=0X02;p++;}//是负数
              if(*p==','||(*p=='*'))break;//遇到结束了
              if(*p=='.'){mask|=0X01;p++;}//遇到小数点了
              elseif(*p>'9'||(*p<'0'))   //有非法字符
              {      
                     ilen=0;
                     flen=0;
                     break;
              }      
              if(mask&0X01)flen++;
              elseilen++;
              p++;
       }
       if(mask&0X02)buf++;   //去掉负号
       for(i=0;i<ilen;i++)  //得到整数部分数据
       {  
              ires+=NMEA_Pow(10,ilen-1-i)*(buf-'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;               
       returnres;
}                                                      
//分析GPGSV信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_GPGSV_Analysis(nmea_msg *gpsx,u8*buf)
{
       u8*p,*p1,dx;
       u8len,i,j,slx=0;
       u8posx;      
       p=buf;
       p1=(u8*)strstr((constchar *)p,"$GPGSV");
       len=p1[7]-'0';                                                  //得到GPGSV的条数
       posx=NMEA_Comma_Pos(p1,3);                                  //得到可见卫星总数
       if(posx!=0XFF)gpsx->svnum=NMEA_Str2num(p1+posx,&dx);
       for(i=0;i<len;i++)
       {      
              p1=(u8*)strstr((constchar *)p,"$GPGSV");  
              for(j=0;j<4;j++)
              {        
                     posx=NMEA_Comma_Pos(p1,4+j*4);
                     if(posx!=0XFF)gpsx->slmsg[slx].num=NMEA_Str2num(p1+posx,&dx);  //得到卫星编号
                     elsebreak;
                     posx=NMEA_Comma_Pos(p1,5+j*4);
                     if(posx!=0XFF)gpsx->slmsg[slx].eledeg=NMEA_Str2num(p1+posx,&dx);//得到卫星仰角
                     elsebreak;
                     posx=NMEA_Comma_Pos(p1,6+j*4);
                     if(posx!=0XFF)gpsx->slmsg[slx].azideg=NMEA_Str2num(p1+posx,&dx);//得到卫星方位角
                     elsebreak;
                     posx=NMEA_Comma_Pos(p1,7+j*4);
                     if(posx!=0XFF)gpsx->slmsg[slx].sn=NMEA_Str2num(p1+posx,&dx);     //得到卫星信噪比
                     elsebreak;
                     slx++;        
              }   
             p=p1+1;//切换到下一个GPGSV信息
       }   
}
//分析BDGSV信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_BDGSV_Analysis(nmea_msg *gpsx,u8*buf)
{
       u8*p,*p1,dx;
       u8len,i,j,slx=0;
       u8posx;      
       p=buf;
       p1=(u8*)strstr((constchar *)p,"$BDGSV");
       len=p1[7]-'0';                                                  //得到BDGSV的条数
       posx=NMEA_Comma_Pos(p1,3);                                  //得到可见北斗卫星总数
       if(posx!=0XFF)gpsx->beidou_svnum=NMEA_Str2num(p1+posx,&dx);
       for(i=0;i<len;i++)
       {      
              p1=(u8*)strstr((constchar *)p,"$BDGSV");  
              for(j=0;j<4;j++)
              {        
                     posx=NMEA_Comma_Pos(p1,4+j*4);
                     if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_num=NMEA_Str2num(p1+posx,&dx);      //得到卫星编号
                     elsebreak;
                     posx=NMEA_Comma_Pos(p1,5+j*4);
                     if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_eledeg=NMEA_Str2num(p1+posx,&dx);//得到卫星仰角
                     elsebreak;
                     posx=NMEA_Comma_Pos(p1,6+j*4);
                     if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_azideg=NMEA_Str2num(p1+posx,&dx);//得到卫星方位角
                     elsebreak;
                     posx=NMEA_Comma_Pos(p1,7+j*4);
                     if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_sn=NMEA_Str2num(p1+posx,&dx);  //得到卫星信噪比
                     elsebreak;
                     slx++;        
              }   
             p=p1+1;//切换到下一个BDGSV信息
       }   
}

//分析GNGGA信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_GNGGA_Analysis(nmea_msg *gpsx,u8*buf,u8 isBeiDou)
{
       u8*p1,dx;                     
       u8posx;   

       if(isBeiDou)
              p1=(u8*)strstr((constchar *)buf,"$BDGGA");
       else
              p1=(u8*)strstr((constchar *)buf,"$GNGGA");
       posx=NMEA_Comma_Pos(p1,6);                                                  //得到GPS状态
       if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx);      
       posx=NMEA_Comma_Pos(p1,7);                                                  //得到用于定位的卫星数
       if(posx!=0XFF)gpsx->posslnum+=NMEA_Str2num(p1+posx,&dx);
       posx=NMEA_Comma_Pos(p1,9);                                                  //得到海拔高度
       if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);  
}

//分析BDGGA信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_BDGGA_Analysis(nmea_msg *gpsx,u8*buf)
{
       u8*p1,dx;                     
       u8posx;   
       p1=(u8*)strstr((constchar *)buf,"$BDGGA");
       posx=NMEA_Comma_Pos(p1,6);                                                  //得到GPS状态
       if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx);      
       posx=NMEA_Comma_Pos(p1,7);                                                  //得到用于定位的卫星数
       if(posx!=0XFF)gpsx->posslnum+=NMEA_Str2num(p1+posx,&dx);
       posx=NMEA_Comma_Pos(p1,9);                                                  //得到海拔高度
       if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);  
}

//分析GNGSA信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_GNGSA_Analysis(nmea_msg *gpsx,u8*buf)
{
       u8*p1,dx;                     
       u8posx;
       u8i;   
       p1=(u8*)strstr((constchar *)buf,"$GNGSA");
       posx=NMEA_Comma_Pos(p1,2);                                                  //得到定位类型
       if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx);     
       for(i=0;i<12;i++)                                                                   //得到定位卫星编号
       {
              posx=NMEA_Comma_Pos(p1,3+i);                                 
              if(posx!=0XFF)gpsx->possl=NMEA_Str2num(p1+posx,&dx);
              elsebreak;
       }                             
       posx=NMEA_Comma_Pos(p1,15);                                                       //得到PDOP位置精度因子
       if(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx);  
       posx=NMEA_Comma_Pos(p1,16);                                                       //得到HDOP位置精度因子
       if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);  
       posx=NMEA_Comma_Pos(p1,17);                                                       //得到VDOP位置精度因子
       if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx);  
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

4

主题

12

回帖

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2024-9-9 20:22:53 | 显示全部楼层
定位芯片什么型号啊
回复

使用道具 举报

9

主题

15

回帖

896

积分

高级会员

Rank: 4

积分
896
QQ
 楼主| 发表于 2024-9-28 09:32:42 | 显示全部楼层
zhangshoubu 发表于 2024-9-9 20:22
定位芯片什么型号啊

中科微 北斗模块
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-11-23 00:49 , Processed in 0.067113 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表