完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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 { 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 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 sum+=mon[i]; } mon[1]=28; } } else { if(runYear(y1)) { mon[1]=29; } for(i=m1;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 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 } for(i=0;i } 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 } for(i=0;i } 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) { page=0; } break; } } ms20_counter=0; } if((SYS_PowerV)==0) //检测到掉电 { wrctrl(0x00,0x08,0x42); #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 } for(i=0;i } 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(4): //新增加油记录 { BeepOFF; //flashbackground3(); AddOilReport(); Takebackposi=0; if(EE_Oil_recoder_num!=0) //读取上次燃油价格, { Oil_price=EE_Oil_recoder[EE_Oil_recoder_num-1].price; } else { Oil_price=0; } AddOilReport_Takeback(Takebackposi); while(DispMode==4) { Oil_totalprice=(long)(((float)Oil_price)/100*((float)Oil_volume)); Display_AddOil(Oil_volume,Oil_price,Oil_totalprice); if(ms20_counter) //每20ms扫描键盘 { GetKey(&KeyValue); switch(KeyValue) { case(KEY_VALUE_RIGHT | KEY_UP): { Takebackposi++; AddOilReport_Takeback(Takebackposi-1); if(Takebackposi > 11) Takebackposi=0; AddOilReport_Takeback(Takebackposi); break; } case(KEY_VALUE_LEFT | KEY_UP): { Takebackposi--; AddOilReport_Takeback(Takebackposi+1); if(Takebackposi < 0) Takebackposi=11; AddOilReport_Takeback(Takebackposi); break; } case(KEY_VALUE_UP | KEY_UP): { switch(Takebackposi) { case(0): { //Oil_volume+=10000; //if(Oil_volume > 99999) //{ Oil_volume/=100000; } break; } case(1): { Oil_volume+=1000; if(Oil_volume > 9999) { Oil_volume/=10000; } break; } case(2): { Oil_volume+=100; break; } case(3): { Oil_volume+=10; break; } case(4): { Oil_volume++; break; } case(5): { //Oil_price+=10000; break; } case(6): { Oil_price+=1000; if(Oil_price > 9999) { Oil_price/=10000; } break; } case(7): { Oil_price+=100; break; } case(8): { Oil_price+=10; break; } case(9): { Oil_price++; break; } } break; } case(KEY_VALUE_DOWN | KEY_UP): { if(Takebackposi ==10) //按“确定”执行的代码 { #asm("cli") rtc_get_date10(&day,&month,&year); EE_Oil_recoder[EE_Oil_recoder_num].year=year; EE_Oil_recoder[EE_Oil_recoder_num].month=month; EE_Oil_recoder[EE_Oil_recoder_num].day=day; EE_Oil_recoder[EE_Oil_recoder_num].price=Oil_price; EE_Oil_recoder[EE_Oil_recoder_num].volume=Oil_volume; EE_Oil_recoder[EE_Oil_recoder_num].total=(int)(Oil_totalprice/100); EE_Oil_recoder_num++; EE_OR_volume+=(int)(Oil_volume/100); //修改总加油量 EE_OR_price+=(int)(Oil_totalprice/100); //修改总计费用 EE_Fuellevel_last=Fuellevel_current; #asm("sei") DispMode=1; } else { if(Takebackposi == 11) //按“取消”执行的代码 { DispMode=1; } } switch(Takebackposi) { case(0): { Oil_volume-=10000; if(Oil_volume < 0) { Oil_volume+=10000; } break; } case(1): { Oil_volume-=1000; if(Oil_volume < 0) { Oil_volume+=1000; } break; } case(2): { Oil_volume-=100; if(Oil_volume < 0) { Oil_volume+=100; } break; } case(3): { Oil_volume-=10; if(Oil_volume < 0) { Oil_volume+=10; } break; } case(4): { Oil_volume--; if(Oil_volume < 0) { Oil_volume = 9; } break; } case(5): { //Oil_price+=10000; break; } case(6): { Oil_price-=1000; if(Oil_price < 0) { Oil_price+=1000; } break; } case(7): { Oil_price-=100; if(Oil_price < 0) { Oil_price+=100; } break; } case(8): { Oil_price-=10; if(Oil_price < 0) { Oil_price+=10; } break; } case(9): { Oil_price--; if(Oil_price < 0) { Oil_price = 9; } break; } } break; } } ms20_counter=0; } 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 } for(i=0;i } 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; } 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秒 |
|
|
|
|
|
|
|
|
|
|
|
自己以解决谢谢大家的的建议
|
|
|
|
已经解决了,也共享一下啊,,,
|
|
|
|
|
|
|
|
几百行的代码你也贴出来。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
哇 好长的代码
|
|
|
|
同求GPS接收机原理图和源代码
|
|
|
|
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
串口发送中断中对发送I/O口定义为GPIO输出,出现发送数据不完整,缺少2个字节,求解答
1168 浏览 3 评论
728 浏览 0 评论
【xG24 Matter开发套件试用体验】10-Bluetooth示例1
836 浏览 0 评论
919 浏览 0 评论
【xG24 Matter开发套件试用体验】power specification电源规格参数配置
747 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
10853 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-25 16:16 , Processed in 1.050479 second(s), Total 106, Slave 89 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191