一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 1619|回复: 4

[其他综合] 求助哪位大哥可以帮忙看一下这个程序gps+1602定位

[复制链接]
发表于 2013-9-10 21:54 | 显示全部楼层 |阅读模式
/*************************************
        GPS解码显示程序,
***************************************/
#include<reg52.h>
#include "1602.h"
//#include"math.h"
//#include <stdlib.h>

sbit GPS_SPD=P2^6;                                //GPS模块速率设置
sbit KEY1=P2^7;                        //显示内容分屏切换,(T0,T1引脚 的第二功能为计数器。)
char code TIME_AREA= 8;                //时区
/***************************************
       这是做的部分更改
************************************/
unsigned long maxspeed,b;
unsigned int count=0;
unsigned int a[5];
unsigned char hspeed[5];
unsigned int dot_count;        //小数点计数器
//unsigned char x;
//GPS数据存储数组
unsigned char JD[10];                //经度
unsigned char JD_a;                //经度方向
unsigned char WD[9];                //纬度
unsigned char WD_a;                //纬度方向
unsigned char date[6];                //日期
unsigned char time[6];                //时间
unsigned char speed[5]={'0','0','0','.','0'};                //速度
unsigned char high[6];                //高度
unsigned char angle[5]={'0','0','0','0','0'};                //方位角
unsigned char use_sat[2];        //使用的卫星数
unsigned char total_sat[2];        //天空中总卫星数
unsigned char lock;                        //定位状态

//串口中断需要的变量
unsigned char seg_count;        //逗号计数器
unsigned char byte_count;        //位数计数器
unsigned char cmd_number;        //命令类型
unsigned char mode;                        //0:结束模式,1:命令模式,2:数据模式
unsigned char buf_full;                //1:整句接收完成,相应数据有效。0:缓存数据无效。
unsigned char cmd[5];                //命令类型存储数组

//显示需要的变量
unsigned int dsp_count;                //刷新次数计数器
//unsigned char time_count;
bit page;

void sys_init(void);
bit chk_key(void);

main()
{
        unsigned char i;
        char Bhour;
        sys_init();

        lock=1;
        use_sat[0]='0';
        use_sat[1]='0';
        total_sat[0]='0';
        total_sat[1]='0';

        while(1){
            if(buf_full==0)                                //无GPS信号时
                {
                        dsp_count++;
                        if(dsp_count>=65000){
                                LCD_cls();                        //清屏
                                LCD_write_string(0,0,"No GPS connect..");
                                LCD_write_string(0,1,"Please Check..");
                                while(buf_full==0);
                                LCD_cls();       
                                dsp_count=0;
                        }
                }
                else{                                                //有GPS信号时
/*************************************
        最大速度处理
*************************************/
                     dot_count=0;
                                          b=0;
                      for(i=0;i<5;i++)
                                          {
                                              if(speed[i]!='.')
                                                     dot_count++;
                                                  else

                                                     break ;
                                          }
                                          switch(dot_count)
                                          {
                                             
                                                 case 1:
                                                      b=((speed[0]-'0')*10+(speed[2]-'0'))*1.852;
                                                          break;
                                                 case 2:
                                                      b=((speed[0]-'0')*100+(speed[1]-'0')*10+(speed[4]-'0'))*1.852;
                                                          break;
                                                 case 3:
                                                      b=((speed[0]-'0')*1000+(speed[1]-'0')*100+(speed[2]-'0')*10+(speed[4]-'0'))*1.852;
                                                          break;
                                               
                                           }
                      if(b>maxspeed)
                                          {
                                            maxspeed=b;
                                      }


/*************************************
        最大速度处理
*************************************/



            

                        if(chk_key()){                                //检测到按键切换显示
                                page=!page;
                                LCD_cls();
                        }

                        if(!page){                                                //页面1


                                           
                                if(buf_full|0x01){                                //GGA语句
                                        if(lock==0){                                        //如果未定位
                                                LCD_write_string(0,0,"*---.--.----  ");
                                                LCD_write_string(0,1,"* --.--.----  ");                                       
                                        }else{                                                        //如果已定位


                                            LCD_write_char(0,0,JD_a);                        //显示经度
                                            for(i=0;i<3;i++)
                                                {
                                                  LCD_write_char(i+1,0,JD[i]);
                                                  }
                        LCD_write_char(4,0,'.');
                        for(i=3;i<10;i++)
                                                {
                                                  LCD_write_char(i+2,0,JD[i]);
                                                  }

                                                LCD_write_char(0,1,WD_a);                        //显示纬度
                                                LCD_write_char(1,1,' ');
                                            for(i=0;i<2;i++)
                                                {
                                                        LCD_write_char(i+2,1,WD[i]);
                                                }
                                                LCD_write_char(4,1,'.');

                        for(i=2;i<9;i++)
                                                {
                                                        LCD_write_char(i+3,1,WD[i]);
                                                }
                                                                                               
                                                }
                                        LCD_write_char(14,1,use_sat[0]);                //显示接收卫星数
                                        LCD_write_char(15,1,use_sat[1]);
                                        buf_full&=~0x01;
                                        dsp_count=0;
                        }
                                if(buf_full|0x02){                                //GSV语句
                                        LCD_write_char(14,1,total_sat[0]);
                                        LCD_write_char(15,1,total_sat[1]);
                                        buf_full&=~0x02;
                                        dsp_count=0;
                                }
                                if(buf_full|0x04){
                                        if(lock==0){                                        //如果未定位
                                                LCD_write_string(0,0,"*---.--.----  ");
                                                LCD_write_string(0,1,"* --.--.----  ");                                       
                                        }else{                                                        //如果已定位



                                LCD_write_char(0,0,JD_a);                        //显示经度
                                    for(i=0;i<3;i++)
                                        {
                                          LCD_write_char(i+1,0,JD[i]);
                                          }
                    LCD_write_char(4,0,'.');
                    for(i=3;i<10;i++)
                                        {
                                          LCD_write_char(i+2,0,JD[i]);
                                          }
                                        LCD_write_char(0,1,WD_a);                        //显示纬度
                               
                                        LCD_write_char(1,1,' ');
                        for(i=0;i<2;i++)
                                        {
                                                LCD_write_char(i+2,1,WD[i]);
                                        }
                                        LCD_write_char(4,1,'.');

                    for(i=2;i<9;i++)
                                        {
                                                LCD_write_char(i+3,1,WD[i]);
                                        }

                                     }
                                        LCD_write_char(14,0,use_sat[0]);                //显示接收卫星数
                                        LCD_write_char(15,0,use_sat[1]);
                                        buf_full&=~0x04;
                                        dsp_count=0;
                                }
                        }
                        else{                                                        //页面2
                                if(buf_full|0x01){                                //GGA语句
                                        buf_full&=~0x01;
                                        dsp_count=0;
                                }
                                if(buf_full|0x02){
                                        buf_full&=~0x02;
                                        dsp_count=0;
                                }
                                if(buf_full|0x04){                                //RMC语句
                                        Bhour=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA;
                                        if(Bhour>=24){
                                                Bhour-=24;
                                        }else if(Bhour<0){
                                                Bhour+=24;
                                        }

                                        LCD_write_char(0,1,date[4]);
                                        LCD_write_char(1,1,date[5]);
                                        LCD_write_char(2,1,date[2]);
                                        LCD_write_char(3,1,date[3]);
                                        LCD_write_char(4,1,date[0]);
                                        LCD_write_char(5,1,date[1]);

                                        LCD_write_char(8,1,Bhour/10+0x30);
                                        LCD_write_char(9,1,Bhour%10+0x30);
                                        LCD_write_char(10,1,':');
                                        LCD_write_char(11,1,time[2]);
                                        LCD_write_char(12,1,time[3]);
                                        LCD_write_char(13,1,':');
                                        LCD_write_char(14,1,time[4]);
                                        LCD_write_char(15,1,time[5]);

                                        LCD_write_string(5,0,"knot A");         

                                        if(lock=='0'){                                        //如果未定位
                                                LCD_write_string(0,0,"---.-");
                                                LCD_write_string(11,0,"---.-");
                                        }else{                                                      //已经定位,在此处做的改动。
/*******************************************************************************/


                     
                                                       
                           if(count<10)
                                                   {
                           
                            for(i=0;i<5;i++)
                                                        {                       
                                                        LCD_write_char(i,0,speed[i]);//knot显示
                                                        }
                                                        count++;
                                                  }
                                                  else
                                                  {
                                                    if(count>15)
                                                    {  
                                                           count=0;
                                                        }

                                  hspeed[0]=maxspeed/1000+0x30;                     //把小数转成字符数组
                                                          hspeed[1]=(maxspeed/100)%10+0x30;
                                                          hspeed[2]=(maxspeed/10)%10+0x30;
                                                          hspeed[3]='.';
                                                          hspeed[4]= maxspeed%10+0x30;

                                                     
                                                    count++;
                                                        LCD_write_string(5,0,"Km/h A");
                            LCD_write_char(0,0,hspeed[0]);
                                                        LCD_write_char(1,0,hspeed[1]);       
                                                        LCD_write_char(2,0,hspeed[2]);
                                                        LCD_write_char(3,0,hspeed[3]);
                                                        LCD_write_char(4,0,hspeed[4]);        //最大速度显  */
                                                }
                        
/*******************************************************************************/
                                                         for(i=0;i<5;i++){
                                                                LCD_write_char(11+i,0,angle[i]);
                                                }
                                        }
                                        buf_full&=~0x04;
                                        dsp_count=0;
                                }
                        }

                }
        }
}

bit chk_key(void)
{
        if(!KEY1){
                delayms(10);
                if(!KEY1){
                        while(!KEY1);
                        delayms(10);
                        return(1);
                }
        }
    LCD_cls();                        //清屏
        return(0);
}

//系统初始化
void sys_init() {
        unsigned char i;
        SCON = 0x50;         /* SCON: mode 1, 8-bit UART, enable rcvr */
        TMOD = 0x21;         /* TMOD: timer 1, mode 2, 8-bit reload */
        if(GPS_SPD){
                TH1 = 0xfa;                 /* TH1: reload value for 9600 baud @ 11.059MHz */
        }else{
                TH1 = 0xfd;                        /* TH1: reload value for 4800 baud @ 11.059MHz */
        }
        TR1 = 1;                 /* TR1: timer 1 run */
        LCD_init(8);                //初始化LCD
        LCD_write_string(0,0," GPS SIRF II 2 ");
        LCD_write_string(0,1," 11-11-23 1342 ");



       
        for(i=1;i<4;i++){
                delayms(250);
        }
        //LCD_cls();
        IE=0x90;                        //开总中断、串口中断
}

//串口接收中断
void uart(void) interrupt 4
{
        unsigned char tmp;
        if(RI){
                tmp=SBUF;
                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;
                                }
                                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;
                                                                                }
                                                                        }
                                                                        else if(cmd[3]=='S'){
                                                                                if(cmd[4]=='V'){
                                                                                        cmd_number=2;
                                                                                        mode=2;
                                                                                        seg_count=0;
                                                                                        byte_count=0;
                                                                                }
                                                                        }
                                                                }
                                                                else if(cmd[2]=='R'){
                                                                        if(cmd[3]=='M'){
                                                                                if(cmd[4]=='C'){
                                                                                        cmd_number=3;
                                                                                        mode=2;
                                                                                        seg_count=0;
                                                                                        byte_count=0;
                                                                                }
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }
                                else if(mode==2){
                                        //接收数据处理
                                        switch (cmd_number){
                                                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;
                                                                        }
                                                                        break;
                                                        }
                                                        break;
                                                case 2:                                //类型2数据接收。GPGSV
                                                        switch(seg_count){
                                                                case 3:                //天空中的卫星总数
                                                                        if(byte_count<2){
                                                                                total_sat[byte_count]=tmp;
                                                                        }
                                                                        break;
                                                        }
                                                        break;
                                                case 3:                                //类型3数据接收。GPRMC
                                                        switch(seg_count){
                                                                case 1:                //时间处理
                                                                        if(byte_count<6){                               
                                                                                time[byte_count]=tmp;       
                                                                        }
                                                                        break;
                                                                case 2:                //定位判断                                               
                                                                        if(byte_count<1){
                                                                          if (tmp=='A') {lock=1;}
                                                                          else{
                                                                            lock=0;}
                                                                        }
                                                                        break;
                                                                case 3:                //纬度处理                                               
                                                                        if(byte_count<9){
                                                                                WD[byte_count]=tmp;
                                                                        }
                                                                        break;
                                                                case 4:                //纬度方向处理                                               
                                                                        if(byte_count<1){
                                                                                WD_a=tmp;
                                                                        }
                                                                        break;
                                                                case 5:                //经度处理                                               
                                                                        if(byte_count<10){
                                                                                JD[byte_count]=tmp;
                                                                        }
                                                                        break;
                                                                case 6:                //经度方向处理                                               
                                                                        if(byte_count<1){
                                                                                JD_a=tmp;
                                                                        }
                                                                        break;
                                                                case 7:                //速度处理                                               
                                                                        if(byte_count<5){
                                                                                speed[byte_count]=tmp;
                                                                        }
                                             

                                                                        break;
                                                                case 8:                //方位角处理                                               
                                                                        if(byte_count<5){
                                                                                angle[byte_count]=tmp;
                                                                        }
                                                                        break;
                                                                case 9:                //方位角处理                                               
                                                                        if(byte_count<6){
                                                                                date[byte_count]=tmp;
                                                                        }
                                                                        break;

                                                        }
                                                        break;
                                        }
                                }
                                byte_count++;                //接收数位加1
                                break;
                }
        }
        RI=0;
}
还有个1602

/*
LCD1602驱动,兼容LCD2402
*/

sbit LCD_DB0= P1^0;
sbit LCD_DB1= P1^1;
sbit LCD_DB2= P1^2;
sbit LCD_DB3= P1^3;

sbit LCD_DB4= P1^4;
sbit LCD_DB5= P1^5;
sbit LCD_DB6= P1^6;
sbit LCD_DB7= P1^7;
sbit LCD1602_RS=P2^0;
sbit LCD1602_RW=P2^1;
sbit LCD1602_EN=P2^2;

void LCD_write_char( unsigned x,unsigned char y,unsigned char dat);        //在指定位置显示字符
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);//在指定位置显示字符串
void LCD_cls(void);//清屏
void LCD_en_command(unsigned char command);
void LCD_en_dat(unsigned char temp);
void LCD_set_xy( unsigned char x, unsigned char y );
void LCD_init(unsigned char bw);
void SET_LCD(unsigned char IO_temp);
void delayms(unsigned char ms);
void lcddelay(void);

unsigned char LCDIO;
unsigned char BitWidth;

void LCD_cls(void)
{
        LCD_en_command(0x01);        //0x01 清屏
    delayms(2);
}

void LCD_en_command(unsigned char command)
{
        LCD1602_RS=0;   
        LCD1602_RW=0;
        LCD1602_EN=0;
        switch(BitWidth){
          case 4:
                LCDIO=(command & 0xf0);          //取高4位
                break;
          case 8:
                LCDIO=command;
            break;
        }
        SET_LCD(LCDIO);
        LCD1602_EN=1;
        lcddelay();
        LCD1602_EN=0;

        if (BitWidth==4){
                LCDIO=(command & 0x0f)<<4;                //取低4位
                SET_LCD(LCDIO);
                LCD1602_EN=1;
                lcddelay();
                LCD1602_EN=0;
        }

}

void SET_LCD(unsigned char IO_temp)
{   
        //高4位
        LCD_DB7=IO_temp&0x80;
        LCD_DB6=IO_temp&0x40;
        LCD_DB5=IO_temp&0x20;
        LCD_DB4=IO_temp&0x10;
        //低4位
        if (BitWidth==8){
                LCD_DB3=IO_temp&0x08;
                LCD_DB2=IO_temp&0x04;
                LCD_DB1=IO_temp&0x02;
                LCD_DB0=IO_temp&0x01;
        }
}

void LCD_en_dat(unsigned char dat)
{
        LCD1602_RS=1;
        LCD1602_RW=0;
        LCD1602_EN=0;
        switch(BitWidth){
          case 4:
                LCDIO=(dat & 0xf0);                 //取高4位
                break;
          case 8:
                LCDIO=dat;
                break;
        }
        SET_LCD(LCDIO);
        LCD1602_EN=1;
        lcddelay();
        LCD1602_EN=0;
               
        if (BitWidth==4){
                LCDIO=(dat & 0x0f)<<4;         //取低4位
                SET_LCD(LCDIO);
                LCD1602_EN=1;
                lcddelay();
                LCD1602_EN=0;
        }

}
/*=======================================================
*1602
* 输入参数:x、y : 显示字符串的坐标,X:0-15,Y:0-1
*LCD第一行显示寄存器地址:0X80-0X8F
*LCD第二行显示寄存器地址:0XC0-0XCF  

*2404
*LCD第1行显示地址:1~20(0x80~0x93)
*LCD第2行显示地址:1~20(0xc0~0xd3)
*LCD第3行显示地址:1~20(0x94~0xa7)
*LCD第4行显示地址:1~20(0xd4~0xe7)
=======================================================*/
void LCD_set_xy( unsigned char x, unsigned char y )
{
        unsigned char address;
        if (y ==0)
          address = 0x80 + x;
        else
          if(y==1)
                address = 0xC0 + x;
          else
            if(y==2)
                  address = 0x94 + x;
                else
                  if(y==3)
                    address = 0xD4 + x;

        LCD_en_command(address);
}

void LCD_write_char( unsigned x,unsigned char y,unsigned char dat)
{
        LCD_set_xy( x, y );
        LCD_en_dat(dat);
}

void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
{
    LCD_set_xy( X, Y );    //set address
    while (*s)       // write character
    {
                LCDIO=*s;
                SET_LCD(LCDIO);
                LCD_en_dat(*s);   
                s ++;
    }
}

void LCD_init(unsigned char bw)
{
        BitWidth=bw;
        switch(BitWidth){
          case 4:
                LCD_en_command(0x33);        //
                delayms(20);
                LCD_en_command(0x32);        //
                delayms(20);
                break;

      case 8:
                LCD_en_command(0x38);        //
                delayms(20);
                LCD_en_command(0x38);        //
                delayms(20);
                break;
        }

        LCD_en_command(0x08);        //0x08 令显示器off
        delayms(5);
        LCD_en_command(0x01);        //0x01 清屏                        清屏指令
        delayms(5);
        LCD_en_command(0x06);        //0x06 光标模式设置        进入模式设置指令 写入数据后光标右移
        delayms(5);
        LCD_en_command(0x0c);        //0x0c 显示开                    令光标,0x0c=不显示,0x0d=显示闪动
        delayms(5);
}

void delayms(unsigned char ms)       
{
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i < 115; i++);
        }
}

void lcddelay(void)       
{
        unsigned char i;
        for(i = 0; i < 2; i++);
}
 楼主| 发表于 2013-9-10 21:56 | 显示全部楼层
用 的9600的波特率。现在出现是一上电显示一下,经纬度,  就没有显示了。
回复

使用道具 举报

发表于 2013-9-10 23:50 | 显示全部楼层
能显示,问题就不大,断点跟踪看看
回复

使用道具 举报

发表于 2013-11-4 11:03 | 显示全部楼层
不知道你的P2^6脚怎么接的,单从备注上看9600的应该设置TH1 = 0xfd;
回复

使用道具 举报

发表于 2013-11-13 21:27 | 显示全部楼层
进度怎么样了?期待成功


能上个完整的电路图吗?
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-11-1 01:24 , Processed in 0.032526 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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