gps 信号解析与显示

/*   ; 使用AVR单片机解析出GPSRM数据段的信息,提取时间、经纬度、指示出南北半球及东西经、日期、以及当前数据是否有效的标识位,   ; 并将这些信息显示在1602液晶屏上。     ; 网站:  http://www.ruixuedz.cn   ;email: unaided@tom.com   ; 作者:  老蒋   */         #include <AVR_PQ1A.H>       //包含自定义常量头文件     #include <AVR interrupt.h>         uchar buf[500];      //串口接受数据缓冲区     uint readCount=0;    //串口解析数据计数      uint writeCount=0;   //串口接受数据计数     uchar Time[6];       //gps时间     uchar Date[6];       //gps日期     uchar Status;        //gps有效性     uchar Latitude[9];   //gps纬度     uchar NSIndicator;   //gps南北半球标识位     uchar Longitude[10]; //gps经度     uchar EWIndicator;   //gps东西经标识位     uchar Speed[4];      //gps速度         /*******************************************   函数名称: Uart_init   功    能: 异步串口初始化   参    数: baud--设置的波特率   返回值  : 无   ********************************************/     void  Uart_init(uint baud)                                 {        baud=MCLK/16/baud-1;                    //波特率最大为65K        UCSRB=0x00;        UCSRA=0x00;                             //控制寄存器清零        UCSRC=(1<<URSEL)|(0<<UPM0)|(3<<UCSZ0); UBRRH= "baud"  UBRRL= "baud;"  选择UCSRC,异步模式,禁止校验,1位停止位,8位数据位>>8;                           //设置波特率        UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);  if (writeCount ++writeCount; 将接收到的数据存入全局数组 buf[writeCount]= "UDR;"  关闭接收中断 UCSRB&= "~BIT(RXCIE);"  { ISR(USART_RXC_vect) ******************************************** 无 : 返回值 数: 参 异步串口接收 能: 功 Uart_RX 函数名称: ******************************************* } Uart_sendB(*sendpt++); 字符串未结束则继续发送  while (*sendpt) *sendpt) Uart_sentstr(uchar  void  sendpt--发送的数组指针 异步串口发送一个字符串 Uart_sentstr 清除发送完毕状态位 UCSRA|= "1<<TXC;"  等待发送完毕  while (!(UCSRA&(1<<TXC))); 发送数据 UDR= "sendB;"  等待发送缓冲区为空  while (!(UCSRA&(1<<UDRE))); sendB) Uart_sendB(uchar sendB--发送的字节数据 异步串口发送一个字节 Uart_sendB 配置TX为输出(很重要) DDRD|= "0X02;"  全局中断开放 sei(); 接收、发送使能,接收中断使能> 499)        writeCount = 0;     UCSRB|=BIT(RXCIE);                      //使能接收中断     }        /*******************************************   函数名称: Read_byte   功    能: 从接受缓冲区中读取一个字节   参    数: 无   返回值  : temp--读取到的数据   ********************************************/     uchar Read_byte( void )    {        uchar temp;         while (readCount == writeCount)        {            Delayms(10);            }        temp = buf[readCount];        ++readCount;         if (readCount > 499)            readCount = 0;         return  temp;        }        /*******************************************   函数名称: LCD1602_portini   功    能: 初始化1602液晶用到的IO口   参    数: 无   返回值  : 无   ********************************************/     void  LCD1602_portini( void )    {        LCDa_CTRL_DDR |= BIT(LCDa_RS)|BIT(LCDa_RW)|BIT(LCDa_E); //配置控制管脚为输出         LCDa_DATA_DDR |= 0xFF; //配置数据管脚为输出     }        /*******************************************   函数名称: LCD1602_readbyte   功    能: 从1602液晶读出一个字节数据或者指令   参    数: DatCmd--为iDat时是数据,为iCmd时是指令   返回值  : dByte--读回的数据或者指令   ********************************************/     uchar LCD1602_readbyte(uchar DatCmd)    {        uchar dByte;         if  (DatCmd == iCmd)       //指令操作             LCDa_CLR_RS;         else             LCDa_SET_RS;                    LCDa_SET_RW;              //读操作         LCDa_SET_E;        LCDa_DATA_DDR=0x00;       //数据总线定义为输入         dByte=LCDa_DI;            //读数据或者指令         Delayms(1);               //时序调整         LCDa_CLR_E;         LCDa_DATA_DDR|=0xff;      //数据总线还原为输出          return  dByte;    }        /*******************************************   函数名称: LCD1602_sendbyte   功    能: 向1602液晶写入一个字节数据或者指令   参    数: DatCmd--为iDat时是数据,为iCmd时是指令             dByte--为写入1602的数据或者指令   返回值  : 无   ********************************************/     void  LCD1602_sendbyte(uchar DatCmd, uchar dByte)    {         if  (DatCmd == iCmd)      //指令操作             LCDa_CLR_RS;         else             LCDa_SET_RS;         //数据操作                     LCDa_CLR_RW;             //写操作操作         LCDa_SET_E;        LCDa_DO = dByte;         //写入数据         Delayms(1);        LCDa_CLR_E;     }        /*******************************************   函数名称: LCD1602_sendstr   功    能: 向1602液晶写入一个字符串   参    数: ptString--字符串指针   返回值  : 无   ********************************************/     void  LCD1602_sendstr(uchar *ptString)    {         while ((*ptString)!= '\0' )          //字符串未结束就一直写         {            LCD1602_sendbyte(iDat, *ptString++);        }    }        /*******************************************   函数名称: LCD1602_clear   功    能: 1602液晶清屏   参    数: 无   返回值  : 无   ********************************************/     void  LCD1602_clear( void )    {        LCD1602_sendbyte(iCmd,LCDa_CLS); //写入清屏指令         Delayms(40); // 清屏指令写入后,2ms 的延时是很必要的!!!     }        /*******************************************   函数名称: LCD1602_readBF   功    能: 1602液晶清屏   参    数: 无   返回值  : busy--为1时是忙状态,为0时可以接收指令   ********************************************/     uchar LCD1602_readBF( void )    {             uchar busy;        busy=LCD1602_readbyte(iCmd);         //读回BF标志(忙标志)和地址          if (busy&0x80)                        //如果忙返回正在忙的状态             busy=1;         else                                  //如果不忙,可以写入             busy=0;         return  busy;    }        /*******************************************   函数名称: LCD1602_gotoXY   功    能: 移动到指定位置   参    数: Row--指定的行             Col--指定的列   返回值  : 无   ********************************************/     void  LCD1602_gotoXY(uchar Row, uchar Col)    {            switch  (Row)           //选择行         {             case  1:                LCD1602_sendbyte(iCmd, LCDa_L1 + Col);  break ;    //写入第1行的指定列               case  2:                LCD1602_sendbyte(iCmd, LCDa_L2 + Col);  break ;    //写入第2行的指定列               default :                 break ;                        }    }        /*******************************************   函数名称: LCD1602_initial   功    能: 1602液晶初始化   参    数: 无   返回值  : 无   ********************************************/     void  LCD1602_initial( void )    {        Delayms(100);                //上电后等待内部复位         LCD1602_portini();           //端口初始化                 LCD1602_sendbyte(iCmd, LCDa_FUNCTION);   //功能、模式设定,具体的设定功能可以看C:\icc\include\AVR_PQ1A.H里面的常量定义          while (LCD1602_readBF());                 //等待不忙为止         LCD1602_sendbyte(iCmd, LCDa_ON);         //打开显示          while (LCD1602_readBF());                 //等待不忙为止         LCD1602_clear();                         //清屏          while (LCD1602_readBF());                 //等待不忙为止         LCD1602_sendbyte(iCmd, LCDa_ENTRY);      //输入模式设定             }        /*******************************************   函数名称: clear_gprmc   功    能: 清空gprmc显示缓冲区   参    数: 无   返回值  : 无   ********************************************/     void  clear_gprmc( void )    {        uchar i;         for (i=0; i<6; i++)        {            Time[i] =  '0' ;            Date[i] =  '0' ;        }         for (i=0; i<9; i++)        {            Latitude[i] =  '0' ;        }         for (i=0; i<10; i++)        {            Longitude[i] =  '0' ;        }         for (i=0; i<4; i++)        {            Speed[i] =  '0' ;        }               Status =  '0' ;             NSIndicator =  '0' ;        EWIndicator =  '0' ;    }        /*******************************************   函数名称: Parse_gprmc   功    能: 解析GPRMC字段   参    数: 无   返回值  : 无   ********************************************/     void  Parse_gprmc( void )    {        uchar i;        uchar temp;        clear_gprmc();        Read_byte();        temp = Read_byte();         if ( ','  != temp)        {            Time[0] = temp;             for (i=0; i<5; i++)            {                Time[i+1] = Read_byte();            }            Read_byte();            Read_byte();            Read_byte();            Read_byte();        }        Status = Read_byte();        Read_byte();        temp = Read_byte();         if ( ','  != temp)        {            Latitude[0] = temp;             for (i=0; i<3; i++)            {                Latitude[i+1] = Read_byte();            }            Read_byte();             for (i=0; i<5; i++)            {                Latitude[4+i] = Read_byte();            }            Read_byte();        }        temp = Read_byte();         if ( ','  != temp)        {            NSIndicator = temp;            Read_byte();        }        temp = Read_byte();         if ( ','  != temp)        {            Longitude[0] = temp;             for (i=0; i<4; i++)            {                Longitude[i+1] = Read_byte();            }               Read_byte();             for (i=0; i<5; i++)            {                Longitude[5+i] = Read_byte();            }               Read_byte();        }        temp = Read_byte();         if ( ','  != temp)        {            EWIndicator = temp;            Read_byte();        }        temp = Read_byte();         if ( ','  != temp)        {            Speed[0] = temp;            Read_byte();             for (i=0; i<3; i++)            {                Speed[1+i] = Read_byte();            }            Read_byte();        }        Read_byte();        temp = Read_byte();         if ( ','  != temp)        {            Date[0] = temp;             for (i=0; i<5; i++)            {                Date[i+1] = Read_byte();            }           }    }        /*******************************************   函数名称: Display_gprmc   功    能: 显示GPRMC字段信息   参    数: 无   返回值  : 无   ********************************************/     void  Display_gprmc( void )    {        uchar high,low,i;        high = Time[0];        low = Time[1];        low = low+8;         if (low > 57)        {            low = low - 10;            high = high + 1;         }        LCD1602_clear();         while (LCD1602_readBF());        LCD1602_gotoXY(1,0);        LCD1602_sendbyte(iDat,high);        LCD1602_sendbyte(iDat,low);        LCD1602_sendbyte(iDat, ':' );        LCD1602_sendbyte(iDat,Time[2]);        LCD1602_sendbyte(iDat,Time[3]);        LCD1602_sendbyte(iDat, ':' );        LCD1602_sendbyte(iDat,Time[4]);        LCD1602_sendbyte(iDat,Time[5]);        LCD1602_sendbyte(iDat, ' ' );        LCD1602_sendbyte(iDat,Status);         while (LCD1602_readBF());        LCD1602_gotoXY(2,0);        LCD1602_sendbyte(iDat,Date[4]);        LCD1602_sendbyte(iDat,Date[5]);        LCD1602_sendbyte(iDat, '.' );        LCD1602_sendbyte(iDat,Date[2]);        LCD1602_sendbyte(iDat,Date[3]);        LCD1602_sendbyte(iDat, '.' );        LCD1602_sendbyte(iDat,Date[0]);        LCD1602_sendbyte(iDat,Date[1]);        Delayms(50000);        LCD1602_clear();         while (LCD1602_readBF());        LCD1602_gotoXY(1,0);        LCD1602_sendbyte(iDat,Latitude[0]);        LCD1602_sendbyte(iDat,Latitude[1]);        LCD1602_sendbyte(iDat, '.' );         for (i=0; i<7; i++)        {            LCD1602_sendbyte(iDat,Latitude[2+i]);        }        LCD1602_sendbyte(iDat, ' ' );        LCD1602_sendbyte(iDat,NSIndicator);         while (LCD1602_readBF());        LCD1602_gotoXY(2,0);        LCD1602_sendbyte(iDat,Longitude[0]);        LCD1602_sendbyte(iDat,Longitude[1]);        LCD1602_sendbyte(iDat,Longitude[2]);        LCD1602_sendbyte(iDat, '.' );          for (i=0; i<7; i++)        {            LCD1602_sendbyte(iDat,Longitude[3+i]);        }           LCD1602_sendbyte(iDat, ' ' );        LCD1602_sendbyte(iDat,EWIndicator);        Delayms(50000);    }        /*******************************************   函数名称: Read_gprmc   功    能: 读取GPRMC字段   参    数: 无   返回值  : 无   ********************************************/     void  Read_gprmc( void )    {        uchar temp = 0;        temp = Read_byte();         if (temp ==  '$' )        {            Read_byte();            Read_byte();            temp = Read_byte();             if (temp ==  'R' )            {                temp = Read_byte();                 if (temp ==  'M' )                {                    temp = Read_byte();                     if (temp ==  'C' )                    {                        Parse_gprmc();                        Display_gprmc();                    }                }            }        }    }        /*******************************************   函数名称: main   功    能:    参    数: 无   返回值  : 无   ********************************************/     int  main( void )    {     Board_init( );              //初始化开发板      Uart_init(9600);            //初始化串口,设置波特率      LCD1602_initial();       while (LCD1602_readBF());      LCD1602_gotoXY(1,0);      LCD1602_sendstr( "AVR_PQ1A BOARD" );          while (1)     {        Read_gprmc();     }    }       

转载于:https://www.cnblogs.com/slcfhr/archive/2010/07/04/1770727.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值