搜索
bottom↓
回复: 28

新手写的邮购部GPS(370C+M16+1602)解析程序,实现全部解析,但有几个问题,请高手帮忙改改!(

[复制链接]

出0入0汤圆

发表于 2010-9-10 17:56:58 | 显示全部楼层 |阅读模式
我的程序也是参考、抄袭论坛上的程序基础上写的,现在有几个问题,请高手帮忙改改!
1.日期显示错误,2000/00/00,时间可以正常显示,
2.速度显示为海里,努力多次没有转换成公里,汗!
3.方位角量示正确,但想能够实现方位提示:N NW W WS S SE E EN,
我在邮购部买的370C 发送的数据如下:
$GPGGA,111634.000,29**.**32,N,111**.**08,E,1,05,1.7,22.0,M,,,18.8,0000*22
$GPGSA,A,3,02,04,10,12,17,,,,,,,,3.5,1.7,3.0*33
$GPGSV,3,1,11,04,61,338,38,17,57,084,31,05,48,277,,10,48,197,33*78
$GPGSV,3,2,11,02,38,281,45,07,32,316,,28,19,164,29,12,16,318,41*78
$GPGSV,3,3,11,23,15,075,26,20,05,040,23,09,02,242,*47
$GPRMC,111634.000,A,29**.**32,N,111**.**08,E,0.00,,090910,,*1D
经纬度处理过!请原谅!
原程序如下:
1.main.c

#include <ioM16v.h>
#include <macros.h>
#include "delay.h"
#include "1602.h"
#include "uart.h"
#include "GPS.h"



/*******************系统初始化********************/
void INIT_devices(void)
{
CLI(); //禁止所有中断
MCUCR  = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR   = 0x00;
LCD_init();//1602初始
LCD_clear();//清屏
Uart_init(9600);//串口初始
Logo_show();//显示欢迎界面
SEI();//开全局中断
}

/*******************显示欢迎界面********************/
void Logo_show(void)//显示欢迎界面
{
    unsigned int show_num;
        LCD_clear();//1602清屏
    LCD_write_string(4,0,"Welcome!");
    LCD_write_string(0,1,"V:2010-09-10.3");
        delay_nms(1200);
        LCD_clear();//1602清屏
        LCD_write_string(0,0,"Initializing...");
        for(show_num=0;show_num<16;show_num++)
                {
                LCD_write_char(show_num,1,0xFF);
                delay_nms(100);
                }
        LCD_clear();//1602清屏
}


/*******************主函数********************/
void main(void)
{
INIT_devices();
while(1)
{
Gps_display();
}
}


GPS.h


#define TIME_AREA 8    //时区
//GPS数据存储数组
unsigned char speed_km[7];        //速度km/h

unsigned char JD[11];                        //经度
unsigned char JD_a;                        //经度方向
unsigned char WD[10];                        //纬度
unsigned char WD_a;                        //纬度方向
unsigned char time[6]={"000000"};                //时间
unsigned char date[6]={"000000"};                //日期
unsigned char speed[7];                //速度 1海里=1.852M/H
unsigned char high[6];                //高度
unsigned char DD[3];                //二维三维定位标志
unsigned char angle[6];                //方位角
unsigned char use_sat[3];        //使用的卫星数
unsigned char total_sat[3];        //天空中总卫星数
unsigned char DW[3];                //定位标志 V未定位 A已定位
//串口中断需要的变量
unsigned char seg_count;                //逗号计数器
unsigned char dot_count;                //小数点计数器
unsigned char byte_count;                //位数计数器
unsigned char cmd_number;                //命令类型
unsigned char mode;                                //0:结束模式,1:命令模式,2:数据模式
volatile unsigned char buf_full;//:整句接收完成,相应数据有效。0:缓存数据无效。
unsigned char cmd[5];                        //命令类型存储数组

//显示需要的变量
unsigned char dsp_count;                //刷新次数计数器
unsigned char time_count;  
volatile unsigned char high_num,a_num,s_num,d_num,t_num;

unsigned char i;
unsigned char Bhour=0,Bday=0,Bmonth=0;
unsigned int Byear=0;
unsigned char week(unsigned char year, unsigned char mon, unsigned char day);



void GPS_expan(void)//串口接收中断
    {
        unsigned char tmp;
        while(!(UCSRA & (1<<RXC)));
        tmp=UDR;
   switch(tmp){
                case '$':
                        cmd_number=0;                //命令类型清空
                        mode=1;                                //接收命令模式
                        byte_count=0;                //接收位数清空
                        break;
                case ',':
                        seg_count++;                //逗号计数加1
                        byte_count=0;
                        break;
                case '*':
                        switch(cmd_number)
                                {
                                case 1:
                                        buf_full|=0x01;
                                        break;
                                case 2:
                                        buf_full|=0x02;
                                        break;
                                case 3:
                                        buf_full|=0x04;
                                        break;
                                case 4:
                                    buf_full|=0x08;
                                        break;
                                }
                        mode=0;
                        break;
                default:
                        if(mode==1){
                                //命令种类判断
                                cmd[byte_count]=tmp;                        //接收字符放入类型缓存
                                if(byte_count>=4){                                //如果类型数据接收完毕,判断类型
                                        if(cmd[0]=='G'){
                                                if(cmd[1]=='P'){
                                if(cmd[2]=='G'){
                                                                if(cmd[3]=='G'){
                                                                        if(cmd[4]=='A'){
                                                                                cmd_number=1;
                                                                                mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                                                                high_num=0;
                                                                        }
                                                                }
                                                                else if(cmd[3]=='S'){
                                                                        if(cmd[4]=='V'){
                                                                                cmd_number=2;
                                                                                mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                    }
                                                                        if(cmd[4]=='A'){
                                                                            cmd_number=3;
                                                                                mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                                                        }
                                                                       
                                                                }
                                                        }
                                                        else if(cmd[2]=='R'){
                                                                if(cmd[3]=='M'){
                                                                        if(cmd[4]=='C'){
                                                                                cmd_number=4;
                                                                                mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                                                                a_num=0;
                                                                                s_num=0;
                                                                                d_num=0;
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                       
                                }
                        }
                        else if(mode==2){
                                //接收数据处理
                                switch (cmd_number){
                                 /******************GPGGA*****************/
                                        case 1:                                //类型1数据接收。GPGGA
                                                switch(seg_count){
                                                        case 2:                                                                //纬度处理
                                                                if(byte_count<9){

                                                                       
                                                                        WD[byte_count]=tmp;

                                                                }
                                                                break;
                                                        case 3:                                                                //纬度方向处理
                                                                if(byte_count<1){
                                                                        WD_a=tmp;
                                                                }
                                                                break;
                                                        case 4:                                                                //经度处理
                                                                if(byte_count<10){
                                                                        JD[byte_count]=tmp;
                                                                }
                                                                break;
                                                        case 5:                                                                //经度方向处理
                                                                if(byte_count<1){
                                                                        JD_a=tmp;
                                                                }
                                                                break;
                                                        /*case 6:                                //定位判断
                                if(byte_count<1){
                                     lock=tmp;
                                 }
                                 break;*/
                                                        case 7:                                                                //定位使用的卫星数
                                                                if(byte_count<2){
                                                                        use_sat[byte_count]=tmp;
                                                                }
                                                                break;
                                                        case 9:                                                                //高度处理
                                                                if(byte_count<6){
                                                                        high[byte_count]=tmp;
                                                                        high_num++;
                                                                }
                                                                break;
                                                }
                                                break;
                 /******************GPGSV*****************/
                                        case 2:                                //类型2数据接收。GPGSV
                                                switch(seg_count){
                                                        case 3:                                                                //天空中的卫星总数
                                                                if(byte_count<2){
                                                                        total_sat[byte_count]=tmp;
                                                                }
                                                                break;
                                                }
                                                break;
                                /******************GPGSA*****************/
                                        case 3:                                //类型数据接收。GPGSA
                                                switch(seg_count){
                                                        case 2:
                                                                if(byte_count<1){                                //二维三维定位标志处理
                                        DD[byte_count]=tmp;       
                                                                }
                                                                break;
                            }
                                                break;
                 /******************GPRMC*****************/
                                        case 4:                                //类型3数据接收。GPRMC
                                                switch(seg_count){
                                                    case 1 :                                                                //时间
                                                                if(byte_count<6){
                                                                        time[byte_count]=tmp;
                                                            }
                                                                break;
                                                        case 2 :                                                                //定位标志
                                                                if(byte_count<1){
                                                                        DW[byte_count]=tmp;
                                                            }
                                                                break;
                                                        case 7:                                                                //速度处理,单位节,1节=1852M/H
                                                                if(byte_count<5){
                                                                        speed[byte_count]=tmp;
                                                                        //s_num++;
                                                                }
                                                                break;
                                                        case 8:                                                                //方位角处理
                                                                if(byte_count<5){
                                                                        angle[byte_count]=tmp;
                                                                        //a_num++;
                                                                }
                                                                break;
                                                        case 9:                                                                //日期处理
                                                                if(byte_count<6){
                                                                        data[byte_count]=tmp;
                                                                        //d_num++;
                                                                }
                                                                break;
                                                }
                                                break;
               
                                }
                        }
                        byte_count++;                //接收数位加1
                        break;
        }
}

void Gps_display()//GGA   GSV   GPZDA   GPGSA GPVTG GPRMC
        {
                if(buf_full==0)//无GPS信号时
                {
                        dsp_count++;
                        delay_nms(10);
                        if(dsp_count>=200){
                                LCD_clear();//清屏  */
                                 LCD_write_string(0,0,"No GPS connect..");
                                while(buf_full==0);
                                LCD_clear();//清屏  */
                                dsp_count=0;
                        }
                }
                else
                        {                                                //有GPS信号时
                           if(buf_full&0x01)
                             {                                //GGA语句
                                //LCD_write_string(0, 0,"E");
                                     //LCD_write_string(0, 0,JD);
                                   // LCD_write_string(0, 1,"N");
                                     //LCD_write_string(0, 1,WD);//显示纬度
                     LCD_write_string(14, 0,use_sat);//显示接收卫星数
                                         LCD_write_string(9,1,"H");
                                        if(high_num<6)                                                        //高度显示
                                {
                                        for(i=0;i<(6-high_num);i++)
                                        {
                                                LCD_write_string(10+i,1," ");
                                                LCD_write_string(11+i, 1,high);
                                        }
                                }
                                else
                                {
                    LCD_write_string(10, 1,high);  //高度显示
                                }
                                        buf_full&=~0x01;
                                        dsp_count=0;
            if(buf_full&0x02)
                                   {                                //GSV语句
                                        //LCD_write_string(14,0,total_sat);//天空卫星总数
                                        buf_full&=~0x02;
                                        dsp_count=0;
                               }
                                  
                         if(buf_full&0x04)
                               {                    //$GPGSA

                                        /*LCD_write_string(96, 48,DD); //二维三维定位标志*/
                                        buf_full&=~0x16;
                                        dsp_count=0;
                               }  
                        if(buf_full&0x08)
                                   {                    //GPRMC
                                 /* if(Bhour!=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA){
                                        Bhour=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA;                        //北京时间转换
                                        Bday=(date[0]-0x30)*10+date[1]-0x30;
                                        Bmonth=(date[2]-0x30)*10+date[3]-0x30;
                                        Byear=(date[4]-0x30)*10+date[5]-0x30+2000;
                                        if(Bhour>=24){                                        //如果小时数大于24
                                                Bhour-=24;                                                //小时数减24
                                                Bday++;                                                        //日期数加1
                                                switch(Bday){                                                //判断日期
                                                        case 29:                                                        //普通年的2月份
                                                                if((!((Byear%400==0)||((Byear%4==0)&&(Byear%100!=0)))&&(Bmonth==2))){
                                                                        Bday=1;
                                                                        Bmonth++;
                                                                }
                                                                break;
                                                        case 30:                                                        //如果是闰年的2月
                                                                if(((Byear%400==0)||((Byear%4==0)&&(Byear%100!=0)))&&(Bmonth==2)){
                                                                        Bday=1;
                                                                        Bmonth++;
                                                                }
                                                                break;
                                                        case 31:
                                                                if((Bmonth==4)||(Bmonth==6)||(Bmonth==9)||(Bmonth==11)){
                                                                        Bday=1;
                                                                        Bmonth++;
                                                                }
                                                                break;
                                                        case 32:
                                                                Bday=1;
                                                                Bmonth++;
                                                                if(Bmonth>=13){
                                                                        Byear++;
                                                                        Bmonth=1;
                                                                }
                                                                break;
                                                }
                                        }
                                }
                                LCD_write_string(0,0,"20");
                                LCD_write_char(2,0,(Byear%100)/10+0x30);
                                LCD_write_char(3,0,Byear%10+0x30);
                                LCD_write_string(4,0,"/");
                                LCD_write_char(5,0,Bmonth/10+0x30);
                                LCD_write_char(6,0,Bmonth%10+0x30);
                                LCD_write_string(7,0,"/");
                                LCD_write_char(8,0,Bday/10+0x30);
                                LCD_write_char(9,0,Bday%10+0x30);
                               
                               
                                if(Bhour/10!=0)
                                {
                                        LCD_write_char(0,1,Bhour/10+0x30);
                                }
                                else
                                {
                                        LCD_write_string(0,1,"0");
                                }
                                LCD_write_char(1,1,Bhour%10+0x30);
                                LCD_write_string(2,1,":");
                                LCD_write_char(3,1,time[2]);
                                LCD_write_char(4,1,time[3]);
                                LCD_write_string(5,1,":");
                                LCD_write_char(6,1,time[4]);
                                LCD_write_char(7,1,time[5]);*/       
                               
                               
                            LCD_write_string(12,0,DW);//定位标志
                                LCD_write_string(0,1,"AG");
                                LCD_write_string(2,1,angle);//方位角显示
                                //LCD_write_string(0,0,"SP");
                                LCD_write_string(2,0,speed);//速度显示(海里)
                               
                                         buf_full&=~0x04;
                                         dsp_count=0;
                                }  
           
                }
        }
}




请高手帮忙改下,就算带带新手,好让更多人买阿莫的GPS 来玩,拜托了!

出0入0汤圆

 楼主| 发表于 2010-9-10 22:39:24 | 显示全部楼层
自己顶下,别沉了,

出0入0汤圆

 楼主| 发表于 2010-9-12 19:04:27 | 显示全部楼层
不知道怎么没人帮我,这两天自已又参考了别人的程序更改了一下,日期时间显示正确了,但速度转为公里还是错误的,方位角显示有问题,但可能是我的GPS模块有问题,也可能是程序有问题,方位角数据解析成方位(0到99度)时都会显示成北方,这是方位角收到的数据为四位造成的(如12.3度),四位前加"0"就正确了(012.3度),收到五位的数据就一切正常,如123.4度,看数据手册说方位角前面的"0"也会发送的,但我的串口收不到前面的0,这些都是可以用程序实现,但自已还是个新手,真心希望有高手带带,帮忙改下程序。附上最新修改的GPS.h,给跟我一样的新手参考下,

#include "KEY.h"
//定义北京时间与UTC的时差
#define  Time_Zone  8       
unsigned char Time[9];                        //时间变量
unsigned char WD[10];                        //纬度变量 ddmm.mmmm
unsigned char WD_a;                //纬度方向 N 北纬   S 南纬
unsigned char JD[11];                        //经度变量 dddmm.mmmm
unsigned char JD_a;                //经度方向 E 东经   W 西经
unsigned char speed[5];                //速度变量
unsigned char FW[5];                        //方位角变量
unsigned char Date[6];                        //日期变量
unsigned char DD[3];                //二维三维定位标志
unsigned char use_sat[3];        //使用的卫星数
unsigned char total_sat[3];        //天空中总卫星数
unsigned char HI[6];                //海拔高度变量
unsigned char DW[3];                //定位标志 V未定位 A已定位

unsigned char seg_count;                     //逗号计数器
unsigned char cmd_number;                        //命令类型 1=GPGGA  2=GPRMC
unsigned char data_mode;                //数据类型 0=无效 1=命令 2=数据
unsigned char cmd_type[5];                //命令类型变量
unsigned char byte_count;                //字符计数器
unsigned char menu_count;                //菜单计数器
unsigned char dsp_count;                //显示计数器
unsigned int volt;                                //系统电压变量
unsigned char volt_disp[4];                //系统电压显示数组
unsigned int count;                                //系统计数器变量
unsigned char bj_hour;                        //北京时间小时变量
unsigned char bj_day;                        //北京时间日变量
unsigned char bj_month;                        //北京时间月份变量
unsigned char bj_year;                        //北京时间年份变量
unsigned int km;                                //公里单位变量       
volatile unsigned char buf_full;//:整句接收完成,相应数据有效。0:缓存数据无效。

unsigned long speed_angle_kph_temp;
unsigned char i_sd;                /*循环用的变量*/
unsigned long j_sd;
unsigned char k_sd;
unsigned char i_fw;//方位用变量

void GPS_expan(void)//串口接收中断
    {
        unsigned char temp;
        while(!(UCSRA & (1<<RXC)));
        temp=UDR;
        count++;
   switch(temp){
                case '$':
                        cmd_number=0;                //命令类型清空
                        data_mode=1;                                //接收命令模式
                        byte_count=0;                //接收位数清空
                        break;
                case ',':
                        seg_count++;                //逗号计数加1
                        byte_count=0;
                        break;
                case '*':
                        switch(cmd_number)
                                {
                                case 1:
                                        buf_full|=0x01;
                                        break;
                                case 2:
                                        buf_full|=0x02;
                                        break;
                                case 3:
                                        buf_full|=0x04;
                                        break;
                                case 4:
                                    buf_full|=0x08;
                                        break;
                                }
                        data_mode=0;
                        break;
                default:
                        if(data_mode==1){
                                //命令种类判断
                                cmd_type[byte_count]=temp;                        //接收字符放入类型缓存
                                if(byte_count>=4){                                //如果类型数据接收完毕,判断类型
                                        if(cmd_type[0]=='G'){
                                                if(cmd_type[1]=='P'){
                                if(cmd_type[2]=='G'){
                                                                if(cmd_type[3]=='G'){
                                                                        if(cmd_type[4]=='A'){
                                                                                cmd_number=1;
                                                                                data_mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                                                        }
                                                                }
                                                                else if(cmd_type[3]=='S'){
                                                                        if(cmd_type[4]=='V'){
                                                                                cmd_number=2;
                                                                                data_mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                    }
                                                                        if(cmd_type[4]=='A'){
                                                                            cmd_number=3;
                                                                                data_mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                                                        }
                                                                       
                                                                }
                                                        }
                                                        else if(cmd_type[2]=='R'){
                                                                if(cmd_type[3]=='M'){
                                                                        if(cmd_type[4]=='C'){
                                                                                cmd_number=4;
                                                                                data_mode=2;
                                                                                seg_count=0;
                                                                                byte_count=0;
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                       
                                }
                        }
                        else if(data_mode==2){
                                //接收数据处理
                                switch (cmd_number){
                                 /******************GPGGA*****************/
                                        case 1:                                //类型1数据接收。GPGGA
                                                switch(seg_count){
                                                        case 7:                                                                //定位使用的卫星数
                                                                if(byte_count<2){
                                                                        use_sat[byte_count]=temp;
                                                                }
                                                                break;
                                                        case 9:                                                                //高度处理
                                                                if(byte_count<7){
                                                                        HI[byte_count]=temp;
                                                                }
                                                                break;
                                                }
                                                break;
                 /******************GPGSV*****************/
                                        case 2:                                //类型2数据接收。GPGSV
                                                switch(seg_count){
                                                        case 3:                                                                //天空中的卫星总数
                                                                if(byte_count<2){
                                                                        total_sat[byte_count]=temp;
                                                                }
                                                                break;
                                                }
                                                break;
                                /******************GPGSA*****************/
                                        case 3:                                //类型数据接收。GPGSA
                                                switch(seg_count){
                                                        case 2:
                                                                if(byte_count<1){                                //二维三维定位标志处理
                                        DD[byte_count]=temp;       
                                                                }
                                                                break;
                            }
                                                break;
                 /******************GPRMC*****************/
                                        case 4:                                //类型3数据接收。GPRMC
                                                switch(seg_count){
                                                    case 1 :                                                                //时间
                                                                if(byte_count<9){
                                                                        Time[byte_count]=temp;
                                                            }
                                                                break;
                                                        case 2 :                                                                //定位标志
                                                                if(byte_count<1){
                                                                        DW[byte_count]=temp;
                                                            }
                                                                break;
                                                        case 3 :                                                                //纬度
                                                                if(byte_count<9){
                                                                        WD[byte_count]=temp;
                                                            }
                                                                break;
                                                        case 4 :                                                                //纬度标识
                                                                if(byte_count<1){
                                                                        WD_a=temp;
                                                            }
                                                                break;
                                                        case 5:                                                                //经度
                                                                if(byte_count<10){
                                                                        JD[byte_count]=temp;
                                                                }
                                                                break;
                                                        case 6:                                                                //经度标识
                                                                if(byte_count<1){
                                                                        JD_a=temp;
                                                                }
                                                                break;
                                                        case 7:                                                                //速度处理,单位节,1节=1852M/H
                                                                if(byte_count<5){
                                                                        speed[byte_count]=temp;
                                                                        }
                                                                break;
                                                        case 8:                                                                //方位角处理
                                                                if(byte_count<5){
                                                                        FW[byte_count]=temp;
                                                                        //a_num++;
                                                                }
                                                                break;
                                                        case 9:                                                                //日期处理
                                                                if(byte_count<6){
                                                                        Date[byte_count]=temp;
                                                                        //d_num++;
                                                                }
                                                                break;
                                                }
                                                break;
               
                                }
                        }
                        byte_count++;                //接收数位加1
                        break;
        }
}

/************************数据显示******************************/

/*******************显示所有数据到1602***************************/
void Gps_display(void)
{
unsigned char temp;
  if(KEY_LEFT == 0)
  {
   delay_nms(20);
   if(KEY_LEFT == 0)
   {
   while(KEY_LEFT == 0);
    LCD_clear();                                                                                                //清屏
        menu_count++;                                                                //菜单计数器加1  范围:0-2
        if(menu_count>3)
        {
         menu_count=0;
        }
   }
  }
  
if(buf_full==0)//无GPS信号时
                {
                        dsp_count++;
                        delay_nms(10);
                        if(dsp_count>=200){
                                LCD_clear();//清屏  */
                                 LCD_write_string(0,0,"No GPS connect..");
                                while(buf_full==0);
                                LCD_clear();//清屏  */
                                dsp_count=0;
                        }
                }
                else
                {
  //转换UTC日期时间为北京日期时间
  bj_hour = ((Time[0]-'0')*10+(Time[1]-'0')) + Time_Zone;
  bj_day  = ((Date[0]-'0')*10+(Date[1]-'0'));
  bj_month= ((Date[2]-'0')*10+(Date[3]-'0'));
  bj_year = ((Date[4]-'0')*10+(Date[5]-'0'));

  if (bj_hour>=24)
   {
    bj_hour -= 24;
        bj_day++;
        switch(bj_month)                                        //判断大小月份
        {
         case 1:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          
          }
          break;
         }
         
         case 2:
         {
          if (((bj_year%4==0) && (bj_year%4!=0))        ||         bj_year%400==0)        //判断是否为闰年
          {
       if(bj_day>29)
           {
                   bj_day = 1;
                   bj_month++;
                if(bj_month>12)
                {
                 bj_month = 1;
                 bj_year++;
                }
           }
          }       
      else
          {
           if(bj_day>28)
           {
                   bj_day = 1;
                   bj_month++;
                if(bj_month>12)
                {
                 bj_month = 1;
                 bj_year++;
                }
           }
          }
      
          break;
         }
         
         case 3:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 4:
         {
          if(bj_day>30)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 5:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 6:
         {
          if(bj_day>30)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 7:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 8:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 9:
         {
          if(bj_day>30)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 10:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 11:
         {
          if(bj_day>30)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
         case 12:
         {
          if(bj_day>31)
          {
           bj_day = 1;
           bj_month++;
           if(bj_month>12)
           {
                   bj_month = 1;
                bj_year++;
           }
          }
          break;
         }
         
        }
   }

     
  //显示GPS数据到LCD1602
  switch(menu_count){
   case 0:                                                                                  //第1屏数据显示
   {
    LCD_write_char(0,0,JD_a);
    LCD_write_string(1,0,":");
    LCD_write_string(2,0,JD);
    LCD_write_char(0,1,WD_a);
        LCD_write_string(1,1,":");
        LCD_write_string(3,1,WD);
        LCD_write_string(14,0,DW);       
        LCD_write_string(14,1,DD);
        LCD_write_string(15,1,"D");       

        break;
   }
   case 1:                                                                                    //第2屏数据显示
   {
    LCD_write_string(0,0,"Date:");                                 //显示日期
        LCD_write_string(5,0,"20");
        LCD_write_char(7,0,bj_year/10+'0');
        LCD_write_char(8,0,bj_year%10+'0');
        LCD_write_char(9,0,'-');
        LCD_write_char(10,0,bj_month/10+'0');
        LCD_write_char(11,0,bj_month%10+'0');
        LCD_write_char(12,0,'-');
        LCD_write_char(13,0,bj_day/10+'0');
        LCD_write_char(14,0,bj_day%10+'0');
       
        LCD_write_string(0,1,"Time:");                                   //显示时间
        LCD_write_char(5,1,bj_hour/10+'0');
        LCD_write_char(6,1,bj_hour%10+'0');
        LCD_write_char(7,1,':');
        LCD_write_char(8,1,Time[2]);
        LCD_write_char(9,1,Time[3]);
        LCD_write_char(10,1,':');
        LCD_write_char(11,1,Time[4]);
        LCD_write_char(12,1,Time[5]);
       
        break;
   }
   case 2:                                                                                   //第3屏数据显示
   {
    LCD_write_string(0,0,"FW:");                          //显示方位角
       
     LCD_write_char(3,0,FW[0]);       
         LCD_write_char(4,0,FW[1]);
         LCD_write_char(5,0,FW[2]);
         LCD_write_char(6,0,FW[3]);
         LCD_write_char(7,0,FW[4]);
         
                speed_angle_kph_temp = 0;       
                        speed_angle_kph_temp=((FW[0]-'0')*1000)+((FW[1]-'0')*100)+((FW[2]-'0')*10)+(FW[4]-'0');
                                       
                                if(speed_angle_kph_temp>3375 || speed_angle_kph_temp < 226)
                                        LCD_write_string(10,0,"Bei");
                                else if(speed_angle_kph_temp>2925)
                                        LCD_write_string(10,0,"X B");
                                else if(speed_angle_kph_temp>2475)
                                        LCD_write_string(10,0,"X i");
                                else if(speed_angle_kph_temp>2025)
                                        LCD_write_string(10,0,"X N");
                                else if(speed_angle_kph_temp>1575)
                                        LCD_write_string(10,0,"Nan");
                                else if(speed_angle_kph_temp>1125)
                                        LCD_write_string(10,0,"D N");
                                else if(speed_angle_kph_temp>675)
                                        LCD_write_string(10,0,"Don ");
                                else if(speed_angle_kph_temp>225)
                                        LCD_write_string(10,0,"D B");

       
       
           LCD_write_string(0,1,"SD:");                          //显示速度
          //变换速度单位海里为公里 1海里=1.852公里
            temp = ((speed[0]-'0')*1000)+((speed[1]-'0')*100)+((speed[2]-'0')*10)+(speed[4]-'0');
            km = temp + (temp<<3)/10 + (temp*5)/100 + (temp<<1)/1000;
          LCD_write_char(4,1,km/1000+'0');
          LCD_write_char(5,1,(km%1000)/100+'0');
          LCD_write_char(6,1,((km%1000)%100)/10+'0');
          LCD_write_char(7,1,speed[3]);
          LCD_write_char(8,1,((km%1000)%100)%10+'0');
       
        LCD_write_string(9,1,"KM/h");
                       
        break;
   }
   case 3:                                                                           //第4屏数据显示
   {
    LCD_write_string(0,0,"HI:");                 //显示海拔
        LCD_write_string(3,0,HI);
        LCD_write_string(8,0,"M");
       
        LCD_write_string(11,0,use_sat);
        LCD_write_string(13,0,"/");
        LCD_write_string(14,0,total_sat);//显示捕获卫星数量
       
        /*if(count>1000)                                                         //降低电压AD采样速度,count>1000采样
        {
        c_current = charge_current();  //充电电流
    b_vol = battery_vol();      //电池电压
    change(c_current,I_Data);
    change(b_vol,V_Data);
   
    LCD_write_char(2,0,I_Data[0]);
    LCD_write_char(3,0,'.');
    LCD_write_char(4,0,I_Data[1]);
    LCD_write_char(5,0,I_Data[2]);
   
    LCD_write_char(11,1,V_Data[0]);
    LCD_write_char(12,1,'.');
    LCD_write_char(13,1,V_Data[1]);
    LCD_write_char(14,1,V_Data[2]);
         count = 0;                                                                      //采样显示结束后count计数器清零
        }  */
        LCD_write_string(0,1,"I:");
        LCD_write_string(6,1,"A");
        LCD_write_string(9,1,"V:");
        LCD_write_string(15,1,"v");
        break;
   }
  }
}//if buf_full  else end
}//void end

出0入0汤圆

发表于 2010-9-12 19:43:06 | 显示全部楼层
兄弟

我这个是51的

你拿去看看,偶写的也不好

互相学习

我这个经纬度是转换成

完全角度模式

另外我一直以为输出的速度单位为公里了

这种转换应该比较简单

点击此处下载 ourdev_582412KO4DMZ.rar(文件大小:44K) (原文件名:2004.rar)

出0入0汤圆

 楼主| 发表于 2010-9-13 07:05:51 | 显示全部楼层
谢谢LS!学习......

出0入0汤圆

发表于 2010-9-13 08:19:54 | 显示全部楼层
你把海里乘个常数1.852不就是公里了?

出0入0汤圆

发表于 2010-9-13 08:28:22 | 显示全部楼层
#include "gps.h"
#include "LCD.h"
uchar GPS_buf[512]; //GPS数据缓冲区
uint  GPS_con; //GPS数据缓冲区长度
uchar time_buf[16]; //时间数据缓冲:时时分分秒秒.秒秒秒 日日月月年年
uchar N_buf[16];
uchar E_buf[16];
/****************************************************************************
$GPGGA,050901,3931.4449,N,11643.5123,E,1,07,1.4,76.2,M,-7.0,M,,*65
其标准格式为:
$GPGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF)
各部分所对应的含义为:
(1)定位UTC时间:05时09分01秒
(2)纬度(格式ddmm.mmmm:即dd度,mm.mmmm分);
(3)N/S(北纬或南纬):北纬39度31.4449分;
(4)经度(格式dddmm.mmmm:即ddd度,mm.mmmm分);
(5)E/W(东经或西经):东经116度43.5123分;
(6)质量因子(0=没有定位,1=实时GPS,2=差分GPS):1=实时GPS;
(7)可使用的卫星数(0~8):可使用的卫星数=07;
(8)水平精度因子(1.0~99.9);水平精度因子=1.4;
(9)天线高程(海平面,-9999.9~99999.9,单位:m);天线高程=76.2m);
(10)大地椭球面相对海平面的高度(-999.9~9999.9,单位:m):-7.0m;
(11)差分GPS数据年龄,实时GPS时无:无;
(12)差分基准站号(0000~1023),实时GPS时无:无;
*总和校验域;
hh 总和校验数:65
(CR)(LF)回车,换行。


GPRMC(建议使用最小GPS数据格式)

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11><CR><LF>
$GPRMC,013500.497,V,3410.5356,N,11709.6093,E,,,260810,,*15
1) 标准定位时间(UTC time)格式:时时分分秒秒.秒秒秒(hhmmss.sss)。
2) 定位状态,A = 数据可用,V = 数据不可用。
3) 纬度,格式:度度分分.分分分分(ddmm.mmmm)。
4) 纬度区分,北半球(N)或南半球(S)。
5) 经度,格式:度度分分.分分分分。
6) 经度区分,东(E)半球或西(W)半球。
7) 相对位移速度, 0.0 至 1851.8 knots
8) 相对位移方向,000.0 至 359.9度。实际值。
9) 日期,格式:日日月月年年(ddmmyy)。
10) 磁极变量,000.0 至180.0。
11) 度数。
12) Checksum.(检查位)


$GPGGA,013500.497,3410.5356,N,11709.6093,E,0,00,,,M,,,,0000*02
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,10,23,09,317,31,31,60,025,,16,53,232,,14,42,136,*73
$GPGSV,3,2,10,32,36,266,,29,30,067,,20,24,285,,30,12,046,*7F
$GPGSV,3,3,10,06,12,182,,03,00,195,*78
$GPRMC,013500.497,V,3410.5356,N,11709.6093,E,,,260810,,*15
******************************************************************************/
void get_GPRMC(void)
{
  uint i,j;
  uchar k;
  uint con[12];
  k = 0;
  CLI();
  if(GPS_con) //接收到数据
   {
    //首先查找$GPRMC
        for(i=0;i<GPS_con;i++)
         {
           if((GPS_buf=='$')&(GPS_buf[i+1]=='G')&(GPS_buf[i+2]=='P')&(GPS_buf[i+3]=='R')&(GPS_buf[i+4]=='M')&(GPS_buf[i+5]=='C'))
           {
          asm("nop");
                  break;
           }
         }
         asm("nop");
         //查找','
        for(j=i;j<GPS_con;j++)
        {
         if(GPS_buf[j] == 0x2c)
          {
           con[k] = j;
           k++;
          }
         if(k>11) break;
        }
  for(k=0;k<10;k++) time_buf[k] = GPS_buf[con[0] + 1 + k];
  for(k=0;k<6;k++)  time_buf[k + 10] = GPS_buf[con[8]+ 1 + k];
  //显示时间
  disp_two_char(0x90,time_buf[0],time_buf[1]);  
  disp_two_char(0x91,':',time_buf[2]);
  disp_two_char(0x92,time_buf[3],':');
  disp_N_char(0x93,6,&time_buf[4]);  
  
  disp_two_char(0x84,time_buf[14],time_buf[15]);
  disp_two_char(0x85,'-',time_buf[12]);
  disp_two_char(0x86,time_buf[13],'-');
  disp_two_char(0x87,time_buf[10],time_buf[11]);  
  //显示经纬度

  if(GPS_buf[con[1]+ 1] == 'A') //数据有效
  {
    for(k=0;k<16;k++)
    {
     N_buf[k] = ' ';
         E_buf[k] = ' ';
    }
    for(k=0;k<(con[3]-con[2]-1);k++)
        {
         N_buf[k] = GPS_buf[con[2] + 1 + k];
        }
    for(k=0;k<(con[5]-con[4]-1);k++)
        {
         E_buf[k] = GPS_buf[con[4] + 1 + k];
        }
  disp_N_char(0x89,14,N_buf);
  disp_N_char(0x99,14,E_buf);
  disp_one_word(0x97,"√");
  }
  if(GPS_buf[con[1]+ 1] != 'A') disp_one_word(0x97,"×");//数据无效
  GPS_con = 0; //处理结束
   }
SEI();
}
这个是我写的 数据解析 GPRMC 部分数据。其它的类似。

出0入0汤圆

 楼主| 发表于 2010-9-13 23:21:39 | 显示全部楼层
370C输出的速度数据的位数是不固定的,如:5.5,55.5,加上"."有时三位,有时四位,我看资料说是有五位,前面的0也会发送,如果是标准的五位如:005.5,055.5,就好转换了,直接乘1.852,以上是我的理解,请大家指正,

出0入0汤圆

发表于 2010-9-14 10:29:17 | 显示全部楼层
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4249763&bbs_page_no=1&bbs_id=3072

有没试过这个帖子说的方法,貌似要减少你2/3的代码

出0入0汤圆

发表于 2010-10-18 07:13:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-18 07:47:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-18 08:58:38 | 显示全部楼层
标记一下。

出0入0汤圆

发表于 2011-2-14 17:01:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-14 17:31:30 | 显示全部楼层
标记一下。

出0入0汤圆

发表于 2011-3-2 14:17:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-3 13:50:53 | 显示全部楼层
mark,我也正在做gps的GPRMC解码

参考lz的程序了

谢谢

出0入0汤圆

发表于 2011-3-7 23:38:40 | 显示全部楼层
我买了一个holux GR-87,发现实在不懂怎么玩。。。

出0入0汤圆

发表于 2011-3-15 13:05:17 | 显示全部楼层
刚买了个MTK的,有时间玩一下,学习一下

出0入0汤圆

发表于 2011-3-19 18:15:42 | 显示全部楼层
太好了

出0入0汤圆

发表于 2011-3-19 19:18:03 | 显示全部楼层
学习啊

出0入0汤圆

发表于 2011-5-18 09:49:12 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2011-5-19 10:27:22 | 显示全部楼层
回复【楼主位】liliuqun
-----------------------------------------------------------------------

我想问一下LZ,GPS模块和单片机是如何连接的,我的如果在电脑上运行GPS Views软件是可以看到GPS的信息,但是单片机我就不知道如何连接了,感觉的我程序一直就进不去串口中断子程序。

出0入0汤圆

发表于 2011-6-29 23:41:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-13 14:31:49 | 显示全部楼层
回复【2楼】liliuqun
-----------------------------------------------------------------------

回复【3楼】format
-----------------------------------------------------------------------

请教一下
case '*':
   switch(cmd_number)
   {
   case 1:
      buf_full|=0x01;
      break;
   case 2:
      buf_full|=0x02;
      break;
   case 3:
      buf_full|=0x04;
      break;
   case 4:
      buf_full|=0x08;
      break;
}
这部分是什么意思?我看了好久,不明白!

出0入0汤圆

发表于 2011-7-13 17:04:08 | 显示全部楼层
求解啊!!!

出0入0汤圆

发表于 2011-7-23 14:18:15 | 显示全部楼层
学习下

出0入0汤圆

发表于 2011-11-9 16:26:13 | 显示全部楼层
标记一下,以后能用到

出0入0汤圆

发表于 2012-2-4 23:32:44 | 显示全部楼层
楼主还给出了原始数据啊,哈哈。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 17:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表