⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picceeprom.c

📁 非常好的GPS数据接收程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include  <pic18fxx2.h>
#include  <stdlib.h>
#include  <string.h>
#include  <math.h>
#include  "mydef.h"
#define uchar unsigned char
#define uint unsigned int
#define MAX_CS    RC2
#define LED_ON 				0
#define LED_OFF 			1
#define KEYSPORT PORTA
#define KEY_UP          	1
#define KEY_DOWN         	2
#define KEY_LEFT         	3
#define KEY_RIGHT        	4
#define KEY_UPDOWN       	5
#define KEY_LFTRIT       	6
#define KEY_ALL          	7
#define DISLEN    			6
#define TRUE 				1
#define FALSE				0

void interrupt low_priority LOW_ISR(void);
void interrupt HI_ISR(void);
void mydisplay(unsigned long num);
void display(void);
void test(void);
void mymode(void);
void keyserve(void);
void spiinit(void);
void tmrinit(void);
void init_USART(void);
unsigned char getch();
void PORTINIT(void);                    //端口初始化
unsigned long ReadEEPROM(char Addr);              //EEPROM 读取
char WriteEEPROM(char Addr,uchar data);           //写EEPROM
char getGPGGA(void);    //接收GPS命令GPGG
char getPGRMF(void);
void write_divide(unsigned long wr);
uchar displaybit[6]={0};
uchar dist[5]={0};
void devide(unsigned long num);
uchar N_case(uchar num);
uchar led_case(uchar num);
//以下是用于,gps接收的,计算用的变量
char getGPGGA(void);    //接收GPS命令GPGGA
int cont;
int lattemp1;
unsigned long lattemp2;              
uchar *pAdd;             
uchar Name[6]="";//当前收到的GPS命令的名称
uchar kind=0xFF;     //当前收到的GPS命令的种类号
uchar len=0;
uchar flagGPS=0,seg=1;
uchar firstflag=0,statusofstart=0,counter=0;
char temp;
unsigned long overflowdistance=0,overflowsubdist=0;
unsigned long wr_data_distance=0;
unsigned long wr_data_subdist=0;
double lon1,lon2,lat1,distlat,distlong,lat2,lat3;
unsigned long  distance,subdist;
	uchar Time[6];		//UTC时间
	uchar latitude[10]; //纬度
	uchar NorS[1];
	uchar longitude[10];//经度
	uchar EorW[1];
	uchar Status[1];		//GPS状态
	uchar workNums[2];	//连接卫星数目
	uchar HDOP[4];		//HDOP水平精度因子
	uchar Aultitude[7];	//海拔高度
	uchar M1[1];
	uchar Heigth[7];		//地球椭球面相对大地水准面的高度
	uchar M2[1];
	uchar DifTime[1];	//差分时间
	uchar DifID[4];		//差分站ID号
	
	
	uchar NumWeeks[4];
	uchar NumSeconds[6];
	uchar Date[6];
	uchar Time[6];
	uchar GPSJunpSec[6];
	uchar latitude[10]; //纬度	
	uchar NorS[1];
	uchar longitude[10];//经度
	uchar EorW[1];
	uchar Mode[1];
	uchar Status2[1];
	uchar Velocity[4];
	uchar Direction[3];
	uchar PDOP[1];
	uchar TDOP[1];
	
//以下的定义是用于键盘和显示器的变量
uchar displayflag;	//"1"时显示器显示的是总长ALL_length_display,"0"时为一次行程长度LENGTH
uchar KEYUP,KEYDOWN;//键盘按下与松开标志。
uchar number;	//闪动位次
uchar keyflag;		
uchar KEY_NUM;		//键盘号。
uchar KEY1,KEY2;
uchar subdist_change_flag=1;//SUBDIST改变标志。
uchar long_flag1=0,long_flag2=0,lat0_flag=0,lat1_flag=0;//100度标志位;
double lon_2=0,lon_1=0,lat_1=0,lat_2=0,mylat2=0;
float scale=0;
uchar mylatitude[10],mylongitude[10];
uchar latflag1,latflag2,lonflag1,lonflag2;
unsigned long displaynum;
unsigned long length_display;
unsigned long all_length_display;
uchar dist_read[5];
//--------------------------
float velo;
float distanceofvelo;
unsigned long distanceofvelo_long;
uchar myvelocity[4];
uchar flag_GPS2;
void main(void)
{
	char a,b;
	unsigned long g,h;
	int i;
	unsigned long distance0=0,subdist0=0;
	unsigned long c,d,f,e=0;
	double lat2_decade,lat1_decade,lon2_decade,lon1_decade;
	SWDTEN=1;
	PORTINIT();
	spiinit();	           //
    MAX_CS =LED_OFF; 
	SSPEN=1;
	EEIF=0;
	EEIP=1;			//eeprom 开中断
	EEIE=1; 
	INTCON=0X20;
	INTCON3=0X00;
	INTCON2=0X00;
	IPEN=1;
	mymode();//译码模h
	test();				//测试LED;    
	scale=1;			//初始加减权;
	displayflag=2;		//总长或单次长度的显示标志位;
	tmrinit(); 
	init_USART();
	PEIE=1;               //开中断
    GIE=1;               //
    distance=ReadEEPROM(0x30);
	subdist=ReadEEPROM(0x40);
	overflowdistance=ReadEEPROM(0x50);
	overflowsubdist=ReadEEPROM(0x60);
	distanceofvelo_long=ReadEEPROM(0x70);
	/*overflowdistance=0;
	overflowsubdist=1;
	distance=0xfff00000;
	subdist=0xff000000;*/
	distance0=distance;subdist0=subdist;
	number=4;				//
	keyflag=1;	
	length_display=(unsigned long)(subdist/10)+overflowsubdist*4294;//10need to be100000
	all_length_display=(unsigned long)(distance/10)+overflowdistance*4294;
//	wr_data_distance=(unsigned long)distance;
//	wr_data_subdist=(unsigned long)subdist;
	displaynum=0;//显示?j
  //////////////////////////// ///
while (1)
 {		
        display();
        keyserve();
        asm("CLRWDT");
     if(subdist_change_flag==1)//当距离改变而要写EEPROM的条件
     {
     	wr_data_distance=distance;
		wr_data_subdist=subdist;	
		//wr_data_overflowdistance=overflowdistance;
		//wr_data_overflowsubdist=overflowsubdist;
     	write_divide(wr_data_distance);//按十进制与入每两个位。
		for(a=0;a<5;a++){
			b=a+0x30;
			WriteEEPROM(b,dist[a]);
			}
		write_divide(wr_data_subdist);
		for(a=0;a<5;a++){
			b=a+0x40;
			WriteEEPROM(b,dist[a]);
			}
			write_divide(overflowdistance);//按十进制与入每两个位。
		for(a=0;a<5;a++){
			b=a+0x50;
			WriteEEPROM(b,dist[a]);
			}
		write_divide(overflowsubdist);
		for(a=0;a<5;a++){
			b=a+0x60;
			WriteEEPROM(b,dist[a]);
			}
		write_divide(distanceofvelo_long);//按十进制与入每两个位。
		for(a=0;a<5;a++){
			b=a+0x70;
			WriteEEPROM(b,dist[a]);
			}
		subdist_change_flag=0;		//恢复标志。
 	   }  
   		//status_flag=atof(Status);
   		//	statusflag=(int)status_flag;
   	if(flagGPS==1&&Status[0]=='1'&&statusofstart==0)
   	{
	   	flagGPS=0;
	   	counter++;
	   	if(counter==2)statusofstart=1;
	}
	   	
   	if(flagGPS==1&&Status[0]=='1')//计算;
	   	{ 
		   	for(i=0;i<10;i++)
		   	{
			   	mylatitude[i]=latitude[i];
			   	mylongitude[i]=longitude[i];
			}
		   	flagGPS=0;
			long_flag1=longitude[0];
			long_flag2=longitude[1];
			longitude[0]='0';
			longitude[1]='0';
			lat1_flag=latitude[0];
			latitude[0]='0';
			latflag2=(mylatitude[0]-'0')*10+mylatitude[1]-'0';
			lonflag2=(mylongitude[0]-'0')*100
					+(mylongitude[1]-'0')*10+(mylongitude[2]-'0');
			mylatitude[0]='0';
			mylatitude[1]='0';
			mylongitude[0]='0';
			mylongitude[1]='0';
			mylongitude[2]='0';
		   	if (firstflag==0)//第一次接收时候要读一次EEPROOM并初始化LON1,LAT1。
		   	{
			latflag1=latflag2;
			lonflag1=lonflag2;	
			lon_1=atof(longitude);
			lon1=atof(mylongitude);
			e=(unsigned long)(lon_1*10)+100000*(long_flag1-'0')+10000*(long_flag2-'0');
			//unsigned long lon1
			   			lon2=lon1;
			   			lat_1=atof(latitude);
			   			lat1=atof(mylatitude);
			   			lat0_flag=lat1_flag;
			f=(unsigned long)(lat_1*10)+10000*(lat0_flag-'0');
			//unsigned long lat1;
			   			//length4=(unsigned long)lat1;
			   			lat2=lat1;
			   			firstflag=1;
			   			distance=ReadEEPROM(0x30);
			   			subdist=ReadEEPROM(0x40);
			   			overflowdistance=ReadEEPROM(0x50);
			   			overflowsubdist=ReadEEPROM(0x60);
			   			}
		//e=(unsigned long)(lon_1*10)+100000*(long_flag1-'0')+10000*(long_flag2-'0');
		//f=(unsigned long)(lat_1*10)+10000*(lat0_flag-'0');
			  lon_2=atof(longitude);
			  lon2=atof(mylongitude);
		c=(unsigned long)(lon_2*10)+100000*(long_flag1-'0')+10000*(long_flag2-'0');
		//unsigned long lon2
			  lat_2=atof(latitude);	
			  lat2=atof(mylatitude);
			  mylat2=lat_2+1000.0*(lat1_flag-'0');	
		d=(unsigned long)(lat_2*10)+10000*(lat1_flag-'0');//unsigned long lat2
			  	
			  a=0;//没用。
//if(((long)lon2-(long)lon1)>=1||((long)lat2-(long)lat1)>=1||((long)lon1-(long)lon2)>=1||((long)lat1-(long)lat2)>=1)       //满足计算条件
//if((long)(20*(lon2-lon1))>=1||(long)(20*(lon1-lon2))>=1||(long)(20*(lat2-lat1))>=1||(long)(20*(lat1-lat2))>=1)
if(c>=e)g=c-e;else g=e-c;
if(d>=f)h=d-f;else h=f-d;
if(g>=5||h>=5)
	{/////以下是算法语言。
		
		lat2_decade=latflag2*60+lat2;//转变为十r;
		lat1_decade=latflag1*60+lat1;//转变为十r;
		lon1_decade=lonflag1*60+lon1;
		lon2_decade=lonflag2*60+lon2;
		lattemp1=(int)lat2_decade;
		lattemp1=(int)lat1_decade;
		lattemp2=(unsigned long)(lon1_decade*10);
		lattemp2=(unsigned long)(lon2_decade*10);
		distlat=1849.1*(fabs(lat2_decade-lat1_decade));
					   		 
						lat3=(float)latflag2+lat2/60.0;
					   	lat3=lat3/180.0*3.14159265;
					   	lattemp1=(unsigned long)(cos(lat3)*1000.0);
		distlong=cos(lat3)*1855.3*(fabs(lon2_decade-lon1_decade));
		lattemp2=(int)distlong;
		lattemp2=(int)distlat;
		distance0=distance;subdist0=subdist;//溢出叛断用的中间变量。
	lattemp2=(unsigned long)(sqrt)(distlat*distlat+distlong*distlong);			        
		scale=scale+sqrt(distlat*distlat+distlong*distlong);  
		lattemp2=(int)scale;
		if(scale>=10000.0)
			{
				distance+=(unsigned long)scale;
				subdist+=(unsigned long)scale;
				write_divide(distance);//按十进制与入每两个位。
				for(a=0;a<5;a++){
					b=a+0x30;
					WriteEEPROM(b,dist[a]);
					}
				write_divide(subdist);
				for(a=0;a<5;a++){
					b=a+0x40;
					WriteEEPROM(b,dist[a]);
					}
				scale=0.0;
			}
		
      	if(distance<distance0)
      		{
	      		overflowdistance++;
				write_divide(overflowdistance);//按十进制与入每两个位。
				for(a=0;a<5;a++){
					b=a+0x50;
					WriteEEPROM(b,dist[a]);
					}
			}
	      			
		if(subdist<subdist0)
			{
				overflowsubdist++;
				write_divide(overflowsubdist);
				for(a=0;a<5;a++){
						b=a+0x60;
						WriteEEPROM(b,dist[a]);
						}
			}
	length_display=subdist/10+overflowsubdist*4294+(unsigned long)(scale/10.0);//10need to be100000
	all_length_display=distance/10+overflowdistance*4294+(unsigned long)(scale/10.0);

			lon1=lon2;lon_1=lon_2;e=c;lonflag1=lonflag2;
			lat1=lat2;lat_1=lat_2;f=d;latflag1=latflag2;
		}
			a=0;//没用。

			}//end if flaggps.
	if(flag_GPS2==1&&Status2[0]!='0')
	{
		flag_GPS2=0;
		velo=atof(Velocity);
		for(i=0;i<=3;i++)
			Velocity[i]=0;
		distanceofvelo=distanceofvelo+velo/3.6;
		if(distanceofvelo>=1000.0)
		{
			distanceofvelo_long+=(unsigned long)distanceofvelo;
			distanceofvelo=0;
			write_divide(distanceofvelo_long);
			for(a=0;a<5;a++){
				b=a+0x70;
				WriteEEPROM(b,dist[a]);
				}
		} 
	}
}         //end while
}//end main

void write_divide(unsigned long wr)//写EEPROM的分解函数。
{
	dist[0]=(uchar)((wr)%100);
     dist[1]=(uchar)((wr/100)%100);
     dist[2]=(uchar)((wr/10000)%100);
    dist[3]=(uchar)((wr/1000000)%100);
     dist[4]=(uchar)((wr/100000000)%100);
}
unsigned char 
getch() {
	/* retrieve one byte */
	while(!RCIF)	/* set when register is not empty */
		continue;
	return RCREG;	
}
void PORTINIT(void)               //初始化端口
{
  ADCON1=0X07;
  PORTA=0;
  LATA=0;
  TRISA = 0x0F;
  
  PORTB = 0;
  LATB = 0;
  TRISB = 0x0B;  //RB.3 RB.1 RB.0 as Input
  
  PORTC = 0;
  LATC = 0;
  TRISC = 0x80; //RC.7 as Input others as output;
}
void spiinit(void)//SPI方式显示初始化,
{
PIR1=0;
SSPCON1=0X32;
SSPSTAT=0XC0;

}
void tmrinit(void)//定时器初始化,
{
T08BIT=0;
T0CS=0;
PSA=1;
TMR0IF=0;
TMR0IP=0;
TMR0IE=1;
}
void init_USART(void)		//GPS	接收端口及中断寝化。
{
SPBRG = 0X19;   
RCSTA = 0X90;         //SPEN置1,
TXSTA = 0X04;         //传输使能,高速模式,异步八位通
RCIF=0;
RCIE = 1;
RCIP = 1;
IPR1=0x20;
IPR2=0X10;
TXIE=0;
}
void interrupt low_priority LOW_ISR(void)//低级中断服务。
{
uchar press;
	
  	if (TMR0IF)
    {                                   //check for TMR0 overflow
      	TMR0IF = 0;            //clear interrupt flag
      	TMR0H = 0;
  		TMR0L = 0;

		KEYUP=TRUE;
		press=KEYSPORT;
		press=press|0xf0;
		if(press!=0xff)
  			{
    			KEYDOWN=TRUE;
    			KEYUP=FALSE;
				if(PORTA==0X0e)KEY_NUM=KEY_UP;
				if(PORTA==0X0d)KEY_NUM=KEY_DOWN; 
				if(PORTA==0x0b)KEY_NUM=KEY_LEFT;
				if(PORTA==0x07)KEY_NUM=KEY_RIGHT;
				if(PORTA==0x0c)KEY_NUM=KEY_UPDOWN;
				if(PORTA==0x03)KEY_NUM=KEY_LFTRIT;
				if(PORTA==0x00)KEY_NUM=KEY_ALL;

   			 }
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -