微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 基于51的GPS定位程序和原理图

基于51的GPS定位程序和原理图

时间:10-02 整理:3721RD 点击:
基于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)
{

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top