视频效果如下:
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); } |