基于51的GPS定位程序和原理图
这个东西,你完全可以买个gps模块,然后再看看例子。
买了,没有给我
#define GPS_NULL 0x00 //GPS语句类型
#define GPS_GPGGA 0x01
#define GPS_GPGSA 0x02
#define GPS_GPGSV 0x04
#define GPS_GPRMC 0x08
//定义时间日期结构体
typedef struct
{
unsigned char Year[2];
unsigned char Month[2];
unsigned char Day[2];
unsigned char Week[1];
unsigned char Hour[2];
unsigned char Min[2];
unsigned char Sec[2];
}Struc_Date;
//定义格式化后的GPS数据结构体
typedef struct
{ unsigned int degree; //航向
unsigned char speed; //GPS速度
unsigned char year; //年
unsigned char month; //月
unsigned char day; //日
unsigned char week; //星期
unsigned char hour; //小时
unsigned char min; //分
unsigned char sec; //秒
}Struc_GPS;
//定义GPS语句中的GPRMC结构体
typedef struct
{
unsigned char Block;
unsigned char BlockIndex;
unsigned char UTCTime[10]; //hhmmss.mmm
unsigned char Status; //A- 有效定位 V-无效定位
unsigned char Latitude[9]; //ddmm.mmmm
unsigned char NS; //N/S
unsigned char Longitude[10]; //dddmm.mmmm
unsigned char EW; //E/W
unsigned char Speed[5]; //速率000.0~999.9节
unsigned char Course[5]; //航向000.0~359.9度
unsigned char UTCDate[6]; //ddmmyy
}stru_GPSRMC;
//定义GPS语句中的GPGGA结构体
typedef struct
{
unsigned char Block;
unsigned char BlockIndex;
// unsigned char UTCTime[10]; //hhmmss.mmm RMC中已有, 所以不解析
// unsigned char Latitude[9]; //ddmm.mmmm
// unsigned char NS; //N/S
// unsigned char Longitude[10]; //dddmm.mmmm
// unsigned char EW; //E/W
unsigned char PositionFix; //0,1,2,6
unsigned char SateUsed[2]; //00~12
// unsigned char HDOP[4]; //0.5~99.9
unsigned char Altitude[7]; //-9999.9~99999.9
}stru_GPSGGA;
//定义GPS语句中的GPGSA结构体
typedef struct
{
unsigned char Block;
unsigned char BlockIndex;
unsigned char Mode; //A-自动 /M-手动
unsigned char Mode2; //0,1,2,3
unsigned char SateUsed[12][2];
unsigned char PDOP[4];
unsigned char HDOP[4];
unsigned char VDOP[4];
}stru_GPSGSA;
//定义GPS语句中的卫星数据结构体
typedef struct
{
unsigned char SatelliteID[2];//卫星编号
// unsigned char Elevation[2]; //0-90 degree //不显示GPS卫星的方位图, 所以不解析, 节省 5*12 RAM
// unsigned char Azimuth[3]; //0-359 degree//需要解析时去除注释'//'和解析前的'//'即可
//unsigned char SNR[2]; //0-99 dbHz
}stru_SatelliteInfo;
//定义GPS语句中的GPGSV结构体
typedef struct
{
unsigned char Block;
unsigned char BlockIndex;
unsigned char SateInView[2];
unsigned char GSVID;//当前 GSV语句编号
stru_SatelliteInfo SatelliteInfo[12];
}stru_GPSGSV;
//定义每次行程油耗、里程结构体
typedef struct
{ unsigned char yh;
unsigned int lc;
}Struc_YHrecoder;
//全局变量
/////////////////////GPS语句解析中用到的变量//////////////////////////////
unsigned char GPSDataType=GPS_NULL; //GPS语句类型
unsigned char GPSDataTypeStrBuff[]="$GPxxx,"; //GPS语句类型缓存, 判断类型时使用,
unsigned char GPSDataTypeStrBuffIndex=0; //GPS语句类型字符串的当前位置
bit GPSDataStart=0; //GPS语句开始. 检测到 $ 时置1
bit ReciveFlag=0; //数据接收完成. 最后一条 GPRMC 语句发送完毕置1,
stru_GPSRMC GPS_RMC_Data;
stru_GPSGGA GPS_GGA_Data;
stru_GPSGSA GPS_GSA_Data;
stru_GPSGSV GPS_GSV_Data;
char MainLatitude[15];
char MainLongitude[15];
//////////////////////////////////////////////////////////////////////////
unsigned char counter2,counter3,counter4,counter5=4;
bit s_counter,s2_counter,ms_counter,ms20_counter,ms500_counter; //1秒及2秒定时标志
/
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
if(++counter3>=18)
{ counter3=0;
ms_counter=1;
}
if(++counter4>=8)
{ if(counter4==75)
{ counter4=0; }
ms500_counter=1;
}
else
{ ms500_counter=0; }
ms20_counter=1;
}
// 串口1接收中断函数,用于接收GPS数据
interrupt [USART1_RXC] void usart1_rx_isr(void)
{
unsigned char data;
char status;
status=UCSR1A;
data=UDR1;
if(ReciveFlag==0){
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{ if(GPSDataStart)
{ //已经判断到GPS语句头字符$,
switch(GPSDataTypeStrBuffIndex)
{ //已经读取了多少个表示GPS数据类型的字符
case 6:
{ //已经全部读取, 开始判断
if(GPSDataTypeStrBuff[4]=='G'&&GPSDataTypeStrBuff[5]=='A') GPSDataType=GPS_GPGGA;
if(GPSDataTypeStrBuff[4]=='S'&&GPSDataTypeStrBuff[5]=='A') GPSDataType=GPS_GPGSA;
if(GPSDataTypeStrBuff[5]=='V') GPSDataType=GPS_GPGSV;
if(GPSDataTypeStrBuff[5]=='C') GPSDataType=GPS_GPRMC;
if(data==',') GPSDataTypeStrBuffIndex=255; //判断完毕, 数据接收开始
break;
}
case 255:
{ //GPS数据类型的字符全部读取并判断完毕, 正接收数据
switch(GPSDataType)
{ //该句的类型
case GPS_GPGGA:
{
switch(data)
{
case '*': //语句结束
GPSDataStart=0;
break;
case ',': //该字段结束, 下一个
GPS_GGA_Data.Block++;
GPS_GGA_Data.BlockIndex=0; //字段索引置0:第一个字符
break;
default:
{ //字段字符
switch(GPS_GGA_Data.Block)
{ //判断当前处于哪个字段
// case 0:
// GPS_GGA_Data.UTCTime[GPS_GGA_Data.BlockIndex]=data;
// break;
// case 1:
// GPS_GGA_Data.Latitude[GPS_GGA_Data.BlockIndex]=data;
// break;
// case 2:
// GPS_GGA_Data.NS=data;
// break;
// case 3:
// GPS_GGA_Data.Longitude[GPS_GGA_Data.BlockIndex]=data;
// break;
// case 4:
// GPS_GGA_Data.EW=data;
// break;
case 5:
GPS_GGA_Data.PositionFix=data;
break;
case 6:
GPS_GGA_Data.SateUsed[GPS_GGA_Data.BlockIndex]=data;
break;
// case 7:
// GPS_GGA_Data.HDOP[GPS_GGA_Data.BlockIndex]=data;
// break;
case 8:
GPS_GGA_Data.Altitude[GPS_GGA_Data.BlockIndex]=data;
break;
}
GPS_GGA_Data.BlockIndex++; //字段索引++, 指向下一个字符
}
}
break;
}
case GPS_GPRMC:
{
switch(data)
{
// SerialSendChar(data);
case '*':
{
GPSDataStart=0;
GPSDataTypeStrBuffIndex=0;
ReciveFlag=1; //接收完毕, 可以处理
break;
}
case ',':
{
GPS_RMC_Data.Block++;
GPS_RMC_Data.BlockIndex=0;
break;
}
default:
{
switch(GPS_RMC_Data.Block)
{
case 0:
GPS_RMC_Data.UTCTime[GPS_RMC_Data.BlockIndex]=data;
break;
case 1:
GPS_RMC_Data.Status=data;
break;
case 2:
GPS_RMC_Data.Latitude[GPS_RMC_Data.BlockIndex]=data;
break;
case 3:
GPS_RMC_Data.NS=data;
break;
case 4:
GPS_RMC_Data.Longitude[GPS_RMC_Data.BlockIndex]=data;
break;
case 5:
GPS_RMC_Data.EW=data;
break;
case 6:
GPS_RMC_Data.Speed[GPS_RMC_Data.BlockIndex]=data;
break;
case 7:
GPS_RMC_Data.Course[GPS_RMC_Data.BlockIndex]=data;
break;
case 8:
GPS_RMC_Data.UTCDate[GPS_RMC_Data.BlockIndex]=data;
break;
}
GPS_RMC_Data.BlockIndex++;
}
}
break;
}
case 14:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+2].SNR[GPS_GSV_Data.BlockIndex]=data;
break;
case 15:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].SatelliteID[GPS_GSV_Data.BlockIndex]=data;
break;
// case 16:
// GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].Elevation[GPS_GSV_Data.BlockIndex]=data;
// break;
// case 17:
// GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].Azimuth[GPS_GSV_Data.BlockIndex]=data;
// break;
case 18:
GPS_GSV_Data.SatelliteInfo[GPS_GSV_Data.GSVID*4+3].SNR[GPS_GSV_Data.BlockIndex]=data;
break;
}
GPS_GSV_Data.BlockIndex++;
}
}
break;
}*/
default:
{ //GPS类型判断失败, 进入未接收到GPS语句($)的状态, 重新循环
GPSDataStart=0;
GPSDataType=GPS_NULL;
}
}
break;
}
default:
{ //未判断, 继续接收, Index++
GPSDataTypeStrBuff[GPSDataTypeStrBuffIndex]=data;
GPSDataTypeStrBuffIndex++;
}
}
}
else
{ //未发现语句头字符, 继续接收并判断
if (data=='$')
{ //接收到$, 下一个字符即为类型判断字符, 先进行相关变量初始化
GPSDataTypeStrBuff[0]=data;
GPSDataStart=1; //从头存放GPS类型字符到变量
GPSDataType=GPS_NULL;
GPSDataTypeStrBuffIndex=1;
GPS_RMC_Data.Block=0; //每种语句的标志位
GPS_RMC_Data.BlockIndex=0;
GPS_GSV_Data.Block=0;
GPS_GSV_Data.BlockIndex=0;
GPS_GGA_Data.Block=0;
GPS_GGA_Data.BlockIndex=0;
GPS_GSA_Data.Block=0;
GPS_GSA_Data.BlockIndex=0;
}
}
}}
}
//字符形式的16进制转换成10进制数
//如:字符FE,转换成10进制254
unsigned char HexStrTODec(unsigned char HexH,unsigned char HexL)
{ unsigned char Dec;
if(HexH>=0x41 && HexH<=0x46) //如果是字符A-F,则减去0x37后×16,转换为十位数
Dec=(HexH-0x37)*16;
else
Dec=(HexH-0x30)*16; //如果是数字0-9,则减去0x30
if(HexL>=0x41 && HexL<=0x46) //处理个位
Dec=Dec+HexL-0x37;
else
Dec=Dec+HexL-0x30;
return(Dec);
}
//判定是否闰年
char runYear(int year)
{ if((year%400==0)||((year%4==0)&&(year%100!=0)))
{ return 1; }
else
{ return 0; }
}
//根据给定的年、月、日,计算星期
//根据公式:w=(y+d+1+2*m+3*(m+1)/5+y/4-y/100+y/400) % 7
//条件:当m=1或2时,m=m+12,y=y-1 即将1月和2月看作上一年的13月和14月
//返回1-7代表星期一-星期日
unsigned char DaytoWeek(unsigned char year,unsigned char month,unsigned char day)
{ unsigned char w;
unsigned int y;
y=2000+year;
if(month==1 || month==2)
{ month+=12;
y-=1;
}
w=(y+day+1+2*month+3*(month+1)/5+y/4-y/100+y/400) % 7;
if(w==0) w=7;
return w;
}
//刷新时间及日期显示
void DispTimeZone()
{ Struc_Date SYS_Date;
rtc_get_date(SYS_Date.Day,SYS_Date.Month,SYS_Date.Year,SYS_Date.Week);
rtc_get_time(SYS_Date.Hour,SYS_Date.Min,SYS_Date.Sec);
Display_Year(SYS_Date.Year);
Display_Month(SYS_Date.Month);
Display_Day(SYS_Date.Day);
Display_Week(SYS_Date.Week);
Display_Hour(SYS_Date.Hour);
Display_Min(SYS_Date.Min);
Display_Sec(SYS_Date.Sec);
}
//格式化GPS数据中的航向
unsigned int Format_degree()
{
unsigned int degree;
unsigned char dot_index;
dot_index=strpos(&GPS_RMC_Data.Course [0],'.');
switch(dot_index)
{
case 1:
{ degree=(GPS_RMC_Data.Course [0]-0x30)+(unsigned char)(GPS_RMC_Data.Course [2]>=5);
break;}
case 2:
{ degree=(GPS_RMC_Data.Course [0]-0x30)*10+(GPS_RMC_Data.Course [1]-0x30)+(unsigned char)(GPS_RMC_Data.Course [3]>=5);
break;}
case 3:
{ degree=(GPS_RMC_Data.Course [0]-0x30)*100+(GPS_RMC_Data.Course [1]-0x30)*10+(GPS_RMC_Data.Course [2]-0x30)+(unsigned char)(GPS_RMC_Data.Course [4]>=5);
break;}
default:
{
degree=360;
break;
}
return degree;
}
//格式化GPS中的速度
unsigned char Format_GPS_Speed()
{ unsigned char dot_index;
unsigned int Speed_temp;
unsigned char GPS_Speed;
dot_index=strpos(&GPS_RMC_Data.Speed[0],'.');
switch(dot_index)
{ case 1:
{ Speed_temp=(GPS_RMC_Data.Speed [0]-0x30)*185+(GPS_RMC_Data.Speed [2]-0x30)*185/10;
break;
}
case 2:
{ Speed_temp=((GPS_RMC_Data.Speed [0]-0x30)*10+(GPS_RMC_Data.Speed [1]-0x30))*185+(GPS_RMC_Data.Speed [3]-0x30)*185/10;
break;
}
case 3:
{ Speed_temp=((GPS_RMC_Data.Speed [0]-0x30)*100+(GPS_RMC_Data.Speed [1]-0x30)*10+(GPS_RMC_Data.Speed [2]-0x30))*185+(GPS_RMC_Data.Speed [4]-0x30)*185/10;
break;
}
default:
{ Speed_temp=0;
break;
}
}
if(Speed_temp%100>50)
{ GPS_Speed=Speed_temp/100+1; }
else
{ GPS_Speed=Speed_temp/100; }
return GPS_Speed;
}
//格式化GPS中的日期及时间
void Format_DateTime(unsigned char *GPS_Year,unsigned char *GPS_Month,unsigned char *GPS_Day,unsigned char *GPS_Hour,unsigned char *GPS_Min,unsigned char *GPS_Sec)
{ *GPS_Year=(GPS_RMC_Data.UTCDate[4]-0x30)*10+(GPS_RMC_Data.UTCDate [5]-0x30);
*GPS_Month=(GPS_RMC_Data.UTCDate [2]-0x30)*10+(GPS_RMC_Data.UTCDate [3]-0x30);
*GPS_Day=(GPS_RMC_Data.UTCDate [0]-0x30)*10+(GPS_RMC_Data.UTCDate [1]-0x30);
*GPS_Hour=(GPS_RMC_Data.UTCTime [0]-0x30)*10+(GPS_RMC_Data.UTCTime [1]-0x30)+8;
if(*GPS_Hour>=24)
{ *GPS_Hour-=24;
(*GPS_Day)++;
if(*GPS_Day>31) //日期+1后=32,则月份+1,日期变为1
{ *GPS_Day=1;
(*GPS_Month)++;
}
else
{ if(*GPS_Day==31) //日期+1后=31,判定月份
{ if(*GPS_Month==4 || *GPS_Month==6 || *GPS_Month==9 || *GPS_Month==11) //如果是4。6。9。11月,则月份+1,日期变为1
{ (*GPS_Month)++;
*GPS_Day=1;
}
}
else
{ if(*GPS_Day==30) //日期+1后=30,且是2月,则月份+1,日期变为1
{ if(*GPS_Month==2)
{ (*GPS_Month)++;
*GPS_Day=1;
}
}
else
{ if(*GPS_Day==29) //日期+1后=29,判定是否是2月,是否是闰年
{ if(*GPS_Month==2 && runYear(2000+*GPS_Year)==0) //如果是2月,并且不是闰年,月份+1,日期变为1
{ (*GPS_Month)++;
*GPS_Day=1;
}
}
}
}
}
}
*GPS_Min=(GPS_RMC_Data.UTCTime [2]-0x30)*10+(GPS_RMC_Data.UTCTime [3]-0x30);
*GPS_Sec=(GPS_RMC_Data.UTCTime [4]-0x30)*10+(GPS_RMC_Data.UTCTime [5]-0x30);
}
//获取纬度
void GetLatitude()
{
long s;
MainLatitude[0]=GPS_RMC_Data.NS; //北纬 南纬标志
MainLatitude[2]=GPS_RMC_Data.Latitude[0]-'0'; //度, 直接提取
MainLatitude[3]=GPS_RMC_Data.Latitude[1]-'0';
MainLatitude[4]=0x02; //度(°)符号
MainLatitude[5]=GPS_RMC_Data.Latitude[2]-'0'; //分, 直接提取
MainLatitude[6]=GPS_RMC_Data.Latitude[3]-'0';
//直接提取后四位分并扩大10000倍为整数存于Long型, 避免小数运算
s=(long)(GPS_RMC_Data.Latitude[5]-'0')*1000+(long)(GPS_RMC_Data.Latitude[6]-'0')*100+(long)(GPS_RMC_Data.Latitude[7]-'0')*10+(GPS_RMC_Data.Latitude[8]-'0');
s*=60; //转换成单位 秒(")
//提取到字符串中
MainLatitude[8]=s/100000;
s=s%100000;
MainLatitude[9]=s/10000;
s=s%10000;
MainLatitude[11]=s/1000;
s=s%1000;
MainLatitude[12]=s/100;
s=s%100;
MainLatitude[13]=s/10;
s=s%10;
MainLatitude[14]=s;
}
//获取经度
void GetLongitude()
{
long s;
MainLongitude[0]=GPS_RMC_Data.EW;
MainLongitude[1]=GPS_RMC_Data.Longitude[0]-'0';
MainLongitude[2]=GPS_RMC_Data.Longitude[1]-'0';
MainLongitude[3]=GPS_RMC_Data.Longitude[2]-'0';
MainLongitude[4]=0x02;
MainLongitude[5]=GPS_RMC_Data.Longitude[3]-'0';
MainLongitude[6]=GPS_RMC_Data.Longitude[4]-'0';
s=(long)(GPS_RMC_Data.Longitude[6]-'0')*1000+(long)(GPS_RMC_Data.Longitude[7]-'0')*100+(long)(GPS_RMC_Data.Longitude[8]-'0')*10+(GPS_RMC_Data.Longitude[9]-'0');
s*=60;
MainLongitude[8]=s/100000;
s=s%100000;
MainLongitude[9]=s/10000;
s=s%10000;
MainLongitude[11]=s/1000;
s=s%1000;
MainLongitude[12]=s/100;
s=s%100;
MainLongitude[13]=s/10;
s=s%10;
MainLongitude[14]=s;
}
//燃油数据中值滤波函数
//对7个数进行排序,取中间位的值
unsigned char Fuel_filter(unsigned char *addr)
{ unsigned char i,j;
unsigned char temp;
for(i=0;i<6;i++)
{ for(j=0;j<6-i;j++)
{ if(*(addr+j)>*(addr+j+1))
{ temp=*(addr+j);
*(addr+j)=*(addr+j+1);
*(addr+j+1)=temp;
}
}
}
return *(addr+3);
}
//计算两个年之间间隔的天数
unsigned int comYear(int y1,int y2)
{ unsigned int sum=0;
unsigned int i;
for(i=(y1+1);i<y2;i++)
{ if(runYear(i))
{ sum+=366; }
else
{ sum+=365; }
}
return sum;
}
//计算两个月份间隔的天数
unsigned int comMonth(int y1,char m1,int y2,char m2)
{ unsigned int sum=0;
int i;
if(y1!=y2)
{
if(runYear(y1))
{
mon[1]=29;
}
if(m1!=m2)
{
for(i=m1;i<12;i++)
{
sum+=mon[i];
}
mon[1]=28;
if(runYear(y2))
{
mon[1]=29;
}
for(i=0;i<m2-1;i++)
{
sum+=mon[i];
}
mon[1]=28;
}
else
{
for(i=m1-1;i<12;i++)
{
sum+=mon[i];
}
mon[1]=28;
if(runYear(y2))
{
mon[1]=29;
}
for(i=0;i<m2-1;i++)
{
sum+=mon[i];
}
mon[1]=28;
}
}
else
{
if(runYear(y1))
{
mon[1]=29;
}
for(i=m1;i<m2-1;i++)
{
sum+=mon[i];
}
mon[1]=28;
}
return sum;
}
//计算两个天之间的间隔
unsigned int comDay(int y1,char m1,char d1,int y2,char m2,char d2)
{ unsigned int sum=0;
if(m1!=m2)
{
if(runYear(y1))
{
mon[1]=29;
}
sum+=(mon[m1-1]-d1);
sum+=d2;
mon[1]=28;
}
else
{
sum+=(d2-d1);
}
return sum;
}
//计算两个给定日期间隔天数
unsigned int TS(unsigned int y1,char m1,char d1,unsigned int y2,char m2,char d2)
{ unsigned int sum=0;
y1+=2000;
y2+=2000;
sum=sum+comYear(y1,y2)+comMonth(y1,m1,y2,m2)+comDay(y1,m1,d1,y2,m2,d2);
return sum;
}
void beep()
{ if(!ms500_counter)
{ BeepON; }
else
{ BeepOFF; }
}
void main()
{
Struc_Eng OBD_Data;
Struc_GPS GPS_Data;
unsigned char com_count=0;
bit Time_Reset=0;
unsigned char n,i,to;
char temp;
unsigned char temp_di;
long Distance_xj=0,Distance_total=0;
unsigned int Distance_xh=0;
unsigned int Distance_bc=0;
unsigned int Distance_by=0;
float OilPerHour,OilPerHour_ave=0,OilPerHour_sum=0; //瞬时每小时耗油量(L/Hr),平均每小时耗油量(L/Hr)
long OilPerHour_count=0;
bit isOilave=1;
unsigned int oil=0;
long Count;
float Oil_ave_temp=0,Oil_lc_temp=0;
unsigned char Oil_ave;
unsigned char CurSpeedMax=0;
char DispMode=0;
char *p;
char Takebackposi;
int Oil_volume=0;
int Oil_price=0;
long Oil_totalprice=0;
unsigned char Fuellevel_last,Fuellevel_current;
unsigned int Fuellevel_current_temp=0;
char page=0;
char m;
char year,month,day,hour,min,sec;
int t=0;
unsigned int d=0;
bit noReset=1;
bit longpress=0;
long ErrorCount=0;
delay_ms(500);
start:
Time_Reset=0;
Sysinit(); //系统初始化
rtc_init(1,1,1); //初始化DS1302
DispMode=0;
OBD_init_state=0;
OBD_Data.Airtmp=0;
OBD_Data.ShortFuelTrim=0;
OBD_Data.Coolingtmp=0;
OBD_Data.Distance=0;
OBD_Data.EngRPM=0;
OBD_Data.MAP=0;
OBD_Data.Fuellevel=0;
OBD_Data.Speed=0;
Distance_xj=EE_Distance_xj;
Distance_total=EE_Distance_total;
Fuellevel_last=EE_Fuellevel_last;
Oil_ave=EE_Oil_ave;
Count=EE_Oil_count;
rtc_get_date10(&day,&month,&year); //读取年月日
if(EE_month!=month) //上次熄火时日期和当前不是同一月
{ Distance_by=0; } //本月里程为0
else
{ Distance_by=EE_Distance_by[month]; } //读取本月行驶里程
lcdint(); //初始化液晶
GPS_Data.degree=360;
//GPS_Data.year=12;
//GPS_Data.month=6;
//GPS_Data.day=30;
//DispLogo();
/*
do
{ delay_ms(2000);
}
while(!OBDInit()); //和车辆的OBD模块建立联系
*/
OBD_R_OK=0;
//SendOBDCommand(&OBD_Command[com_count][0]);
//DispLogo(); //显示LOGO
#asm("sei")
while(1)
{ switch(DispMode)
{ case(1):
{ flashbackground();
DispAlamIcon(EE_Speed_alam_en);
DispTimeZone();
while(DispMode==1)
{
if(ReciveFlag) //GPS数据接收完毕
{ //UCSR1B=0x58; //关串口1中断,停止接收GPS数据
GPS_Data.degree=Format_degree(); //格式化航向
GPS_Data.speed=Format_GPS_Speed(); //格式化GPS速度
if((!Time_Reset) && (GPS_RMC_Data.Status=='A')) //自动校时
{ Format_DateTime(&GPS_Data.year,&GPS_Data.month,&GPS_Data.day,&GPS_Data.hour,&GPS_Data.min,&GPS_Data.sec);//格式化日期及时间
GPS_Data.week=DaytoWeek(GPS_Data.year,GPS_Data.month,GPS_Data.day); //计算星期
rtc_set_date(GPS_Data.day,GPS_Data.month,GPS_Data.year,GPS_Data.week);
rtc_set_time(GPS_Data.hour,GPS_Data.min,GPS_Data.sec);
Time_Reset=~Time_Reset;
}
ReciveFlag=0;
//UCSR1B=0xD8; //开串口1中断,继续GPS接收
}
if(OBD_R_OK) //接收到一帧OBD数据
{ OBD_R_OK=0;
if(OBD_R[1]=='1' && OBD_R[2]==0x20) //如果是发动机数据
{ FormatOBD(&OBD_Data.Airtmp,&OBD_Data.ShortFuelTrim,&OBD_Data.Coolingtmp,&OBD_Data.Distance,&OBD_Data.EngRPM,&OBD_Data.MAP,&OBD_Data.Fuellevel,&OBD_Data.Speed);
//根据发动机数据计算相应参数
if(OBD_Data.Distance > SavedDistance)
{ Distance_xj=Distance_xj+OBD_Data.Distance-SavedDistance;
Distance_total=Distance_total+OBD_Data.Distance-SavedDistance;
Distance_bc=Distance_bc+(OBD_Data.Distance-SavedDistance);
Distance_by=Distance_by+(OBD_Data.Distance-SavedDistance);
SavedDistance=OBD_Data.Distance;
}
if(OBD_Data.Speed > EE_Speed_max) //记录最大速度
{ EE_Speed_max=OBD_Data.Speed; }
if(OBD_Data.Speed > CurSpeedMax) CurSpeedMax=OBD_Data.Speed; //记录本次最大速度
OilPerHour=0.0107*(long)OBD_Data.MAP*(long)OBD_Data.EngRPM/(273+(long)OBD_Data.Airtmp); //计算当前的瞬时每小时油耗(L/Hr)
OilPerHour_sum=OilPerHour_sum+OilPerHour;
OilPerHour_count++;
OilPerHour_ave=OilPerHour_sum/OilPerHour_count; //平均每小时耗油量(L/Hr)
if(speed_ave!=0) //计算平均百公里油耗(L/100Km)
{ oil=(unsigned int)(1000*OilPerHour_ave/speed_ave); }
if(oil!=0) //根据平均百公里油耗计算续航里程
{ Distance_xh=OBD_Data.Fuellevel*450/oil; }
}
else
{
}
}
if(ms_counter) //360ms定时时间到
{ ms_counter=0;
SendOBDCommand(&OBD_Command[com_count][0]); //向串口发送OBD命令
com_count++;
if(com_count>13) com_count=0; //循环发送
}
if(s_counter) //1秒定时到
{ s_counter=0;
DispTimeZone(); //刷新日期及时间显示
if(counter5 > 3)
{ Display_Speed(OBD_Data.Speed); } //刷新车速显示
else
{ Display_Speed(EE_Speed_alam);
Takeback(1,0,48,30);
}
for(n=0;n<ds18B20_devices;n++) //显示车内及车外温度
{ read_temp(&ds18B20_rom_codes[n][0],&temp,&temp_di);
if((temp<127) && (temp_di<10))
{ Display_Temp(temp,temp_di,n); }
}
ds18b20_convert();
}
if(s2_counter) //2秒定时到
{ s2_counter=0;
Display_Course(GPS_Data.degree); //显示航向
Display_Altitude(&GPS_GGA_Data.Altitude [0]); //显示海拔
Display_Distance(Distance_xj,0); //显示小计里程
Display_Distance(Distance_by,1); //显示总计里程
Display_Oil(oil); //显示平均油耗
if(isOilave) //显示续航里程
{ Display_XDistance(Distance_xh);
isOilave=~isOilave;
}
else //显示平均油耗
{ Display_Oil_ave(Oil_ave);
isOilave=~isOilave;
}
}
if((EE_Speed_alam_en != 0) && (OBD_Data.Speed >= EE_Speed_alam)) //报警标志允许且车速大于报警速度
{ beep(); }
else
{ BeepOFF; }
if((SYS_PowerV)==0) //检测到掉电
{ #asm("cli") //关中断
if(oil>40 && oil<140)
{
EE_YH_recoder[Count].yh=oil; //记录本次油耗
EE_YH_recoder[Count].lc=Distance_bc; //记录本次里程
Count++; //记录数加1
if(Count==100) //如果记录数超过100,从0开始记录,同时做标记
{ Count=0;
EE_Oil_sum=1;
}
EE_Oil_count=Count;
if(EE_Oil_sum==1) //如果记录数多于100了,按100计算
{ to=100; }
else
{ to=Count; }
for(i=0;i<to;i++)
{ Oil_lc_temp+=EE_YH_recoder[i].lc; //记算总里程
}
for(i=0;i<to;i++)
{ Oil_ave_temp+=((float)EE_YH_recoder[i].yh*(float)EE_YH_recoder[i].lc/Oil_lc_temp); //计算平均油耗
}
EE_Oil_ave=(unsigned char)ceil(Oil_ave_temp);
}
EE_Distance_xj=Distance_xj; //存储小计里程
EE_Distance_total=Distance_total;
//rtc_get_date10(&day,&month,&year);
EE_month=month; //存储本次开机时的月份,如果开机和关机时间跨两个月,则本次里程记录到前一个月
EE_Distance_by[month]=Distance_by; //存储本月行驶里程
if(SavedDistance > 0)
{ EE_OR_lastdistance=SavedDistance; }
//EE_OR_day=TS(EE_OR_lastyear,EE_OR_lastmonth,EE_OR_lastday,GPS_Data.year,GPS_Data.month,GPS_Data.day);
if((OBD_Data.Fuellevel > 0) && (OBD_Data.Fuellevel <=100 ) && noReset)
{ EE_Fuellevel_last=OBD_Data.Fuellevel; }
DispReport(Time,Distance_bc,oil,CurSpeedMax,(unsigned char)speed_ave);
delay_ms(5000); //延时3秒
if((SYS_PowerV)==0) //仍然是掉电状态
{
delay_ms(3000);
SYS_PowerOFF;
while(1);
} //关机
else
{ goto start; } //转到程序头重新开始执行
}
if(ms20_counter) //每20ms扫描键盘
{ GetKey(&KeyValue);
switch(KeyValue)
{ case(KEY_VALUE_RIGHT | KEY_UP):
{ DispMode++;
if(DispMode > 3) DispMode=1;
break;
}
case(KEY_VALUE_LEFT | KEY_UP):
{ DispMode--;
if(DispMode < 1) DispMode=6;
break;
}
case(KEY_VALUE_UP | KEY_LONG):
{ #asm("cli")
if(EE_Speed_alam_en==0)
{ EE_Speed_alam_en=1; }
else
{ EE_Speed_alam_en=0; }
#asm("sei")
DispAlamIcon(EE_Speed_alam_en);
longpress=1;
break;
}
case(KEY_VALUE_DOWN | KEY_LONG):
{ longpress=1;
Distance_xj=0;
break;
}
case(KEY_VALUE_DOWN | KEY_UP):
{ if((EE_Speed_alam_en==1) && !longpress)
{ counter5=0;
#asm("cli")
EE_Speed_alam--;
#asm("sei")
}
longpress=0;
break;
}
case(KEY_VALUE_UP | KEY_UP):
{ if((EE_Speed_alam_en==1) && !longpress)
{ counter5=0;
#asm("cli")
EE_Speed_alam++;
#asm("sei")
}
longpress=0;
break;
}
}
ms20_counter=0;
}
}
break;
}
case(2): //GPS信息显示
{ BeepOFF;
flashbackground2();
DispTimeZone();
while(DispMode==2)
{ if(ReciveFlag) //GPS数据接收完毕
{ //UCSR1B=0x58; //关串口1中断,停止接收GPS数据
GPS_Data.degree=Format_degree(); //格式化航向
GPS_Data.speed=Format_GPS_Speed(); //格式化GPS速度
GetLatitude(); //获取纬度
GetLongitude(); //获取经度
if((!Time_Reset) && (GPS_RMC_Data.Status=='A')) //自动校时
{ Format_DateTime(&GPS_Data.year,&GPS_Data.month,&GPS_Data.day,&GPS_Data.hour,&GPS_Data.min,&GPS_Data.sec);//格式化日期及时间
GPS_Data.week=DaytoWeek(GPS_Data.year,GPS_Data.month,GPS_Data.day); //计算星期
rtc_set_date(GPS_Data.day,GPS_Data.month,GPS_Data.year,GPS_Data.week);
rtc_set_time(GPS_Data.hour,GPS_Data.min,GPS_Data.sec);
Time_Reset=~Time_Reset;
}
ReciveFlag=0;
//UCSR1B=0xD8; //开串口1中断,继续GPS接收
}
if(ms20_counter) //每20ms扫描键盘
{ GetKey(&KeyValue);
switch(KeyValue)
{ case(KEY_VALUE_RIGHT | KEY_UP):
{ DispMode++;
if(DispMode > 3) DispMode=1;
break;
}
case(KEY_VALUE_LEFT | KEY_UP):
{ DispMode--;
if(DispMode < 1) DispMode=3;
break;
}
}
ms20_counter=0;
}
if(s_counter) //1秒定时到
{ s_counter=0;
DispTimeZone(); //刷新日期及时间显示
Display_Speed(GPS_Data.speed); //刷新车速显示
Display_Course(GPS_Data.degree); //显示航向
Display_Altitude(&GPS_GGA_Data.Altitude [0]); //显示海拔
Display_Latitude(MainLatitude); //显示纬度
Display_Longitude(MainLongitude); //显示经度
}
if((SYS_PowerV)==0) //检测到掉电
{ #asm("cli") //关中断
if(oil>40 && oil<140)
{ EE_YH_recoder[Count].yh=oil; //记录本次油耗
EE_YH_recoder[Count].lc=Distance_bc; //记录本次里程
Count++; //记录数加1
if(Count==100) //如果记录数超过100,从0开始记录,同时做标记
{ Count=0;
EE_Oil_sum=1;
}
EE_Oil_count=Count;
if(EE_Oil_sum==1) //如果记录数多于100了,按100计算
{ to=100; }
else
{ to=Count; }
for(i=0;i<to;i++)
{ Oil_lc_temp+=EE_YH_recoder[i].lc; //记算总里程
}
for(i=0;i<to;i++)
{ Oil_ave_temp+=((float)EE_YH_recoder[i].yh*(float)EE_YH_recoder[i].lc/Oil_lc_temp); //计算平均油耗
}
EE_Oil_ave=(unsigned char)ceil(Oil_ave_temp);
}
EE_Distance_xj=Distance_xj; //存储小计里程
EE_Distance_total=Distance_total;
//rtc_get_date10(&day,&month,&year);
EE_month=month; //存储本次开机时的月份,如果开机和关机时间跨两个月,则本次里程记录到前一个月
EE_Distance_by[month]=Distance_by; //存储本月行驶里程
if(SavedDistance > 0)
{ EE_OR_lastdistance=SavedDistance; }
//EE_OR_day=TS(EE_OR_lastyear,EE_OR_lastmonth,EE_OR_lastday,GPS_Data.year,GPS_Data.month,GPS_Data.day);
if((OBD_Data.Fuellevel > 0) && (OBD_Data.Fuellevel <=100 ) && noReset)
{ EE_Fuellevel_last=OBD_Data.Fuellevel; }
DispReport(Time,Distance_bc,oil,CurSpeedMax,(unsigned char)speed_ave);
delay_ms(5000); //延时3秒
if((SYS_PowerV)==0) //仍然是掉电状态
{
delay_ms(3000);
SYS_PowerOFF;
while(1);
} //关机
else
{ goto start; } //转到程序头重新开始执行
}
}
break;
}
case(3): //加油统计
{ BeepOFF;
//flashbackground3();
rtc_get_date10(&day,&month,&year);
if((EE_OR_volume>=currentOil) && (SavedDistance>EE_OR_distance))
{ t=(int)((float)(EE_OR_volume-currentOil)/(float)(SavedDistance-EE_OR_distance)*1000); }
else
{ t=0; }
if(SavedDistance==0)
{ d=EE_OR_lastdistance-EE_OR_distance; }
else
{ d=SavedDistance-EE_OR_distance; }
OilReport(EE_OR_lastyear,EE_OR_lastmonth,EE_OR_lastday,EE_OR_lasthour,EE_OR_lastmin,EE_OR_volume,TS(EE_OR_lastyear,EE_OR_lastmonth,EE_OR_lastday,year,month,day),EE_OR_price,d,t);
page=0;
while(DispMode==3)
{
if(ms20_counter) //每20ms扫描键盘
{ GetKey(&KeyValue);
switch(KeyValue)
{ case(KEY_VALUE_RIGHT | KEY_UP):
{ if(page < 2)
{ wrctrl(0x00,0x08,0x42);
DispMode++;
if(DispMode > 3) DispMode=6;
}
else
{ page++;
if(page ==3)
{ Takeback(96,4,32,16);
Takeback(96,13,32,16);
}
if(page ==4)
{ Takeback(96,13,32,16);
Takeback(96,22,32,16);
}
if(page > 4) page=4;
}
break;
}
case(KEY_VALUE_LEFT | KEY_UP):
{ if(page < 2)
{ wrctrl(0x00,0x08,0x42);
DispMode--;
if(DispMode < 1) DispMode=3;
}
else
{ page--;
if(page ==2)
{ Takeback(96,13,32,16);
Takeback(96,4,32,16);
}
if(page ==3)
{ Takeback(96,13,32,16);
Takeback(96,22,32,16);
}
if(page < 2 ) page=2;
}
break;
}
case(KEY_VALUE_DOWN | KEY_UP):
{ page++;
if(page == 1)
{ wrctrl(0xa0,0x0d,0x42); }
if(page ==2 )
{ Takeback(96,4,32,16); }
if(page == 3) //明细
{ Takeback(96,4,32,16);
wrctrl(0x00,0x08,0x42);
DispMode=5;
}
if(page ==4 ) //增加
{ Takeback(96,13,32,16);
wrctrl(0x00,0x08,0x42);
DispMode=4;
}
if(page ==5 ) //复位
{ Takeback(96,22,32,16);
wrctrl(0x00,0x08,0x42);
rtc_get_date10(&day,&month,&year);
rtc_get_time10(&hour,&min,&sec);
#asm("cli")
EE_Oil_recoder_num=0;
EE_OR_lastyear=year;
EE_OR_lastmonth=month;
EE_OR_lastday=day;
EE_OR_lasthour=hour;
EE_OR_lastmin=min;
EE_OR_volume=0; //总加油量
EE_OR_day=0; //总计天数
EE_OR_distance=SavedDistance; //总计里程
EE_OR_price=0; //总计费用
EE_Fuellevel_last=0;
noReset=0;
//EE_OR_oil=0; //平均油耗
//EE_OR_aveprice1=0; //平均费用
//EE_OR_aveprice2=0; //平均每公里费用
#asm("sei")
DispMode=1;
}
break;
}
case(KEY_VALUE_UP | KEY_UP):
{ page--;
if(page==1)
{ Takeback(96,4,32,16); }
if(page==3)
{ page=1;
Takeback(96,22,32,16);
}
if(page==2)
{ page=1;
Takeback(96,13,32,16);
}
if(page==0)
{ wrctrl(0x00,0x08,0x42); }
if(page < 0)
{