CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

GPS and software RTC

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dynamitron



Joined: 18 Mar 2009
Posts: 38

View user's profile Send private message

GPS and software RTC
PostPosted: Thu Apr 29, 2010 11:42 pm     Reply with quote

Hello,

I wrote the following code to read the stream from a gps module. It works great except that sometime, the display is jamming and the time and date are wrong. They looks more like shifted by a nibble than really wrong from the GPS.

I use a picdem2+ board and my compiler version is 4.065

Have somebody any idea of what is going wrong ?

Code:

//////////////////////////////////////////////////////////////////////////
//               GPS DECODER                                             
//                                                                       
//  Writen by Dynamitron  08 march 2010           
//                                                                       
//  This software is written in order to decode the nmea stream out of   
//  gps leadtek lr9552lp and setup a software RTC                         
//                                                       
//  The primary goal is to get the UTC time and date                 
//  It search for the nmea sentence starting with $GPRMC                 
//  At the time it is found the time is transferd to the RTC             
//
//  $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68
//
//  225446 = Heure du Fix 22:54:46 UTC
//  A = Alerte du logigiel de navigation ( A = OK, V = warning (alerte)
//  4916.45,N = Latitude 49°16.45' North
//  12311.12,W = Longitude 123°11.12' West
//  000.5 = vitesse sol, Knots
//  054.7 = cap (vrai)
//  191194 = Date du fix 19 Novembre 1994
//  020.3,E = Déclinaison Magnetique 20.3 deg Est
//  *68 = checksum obligatoire
//  Non représentés CR et LF


#include <16f877a.h>
#device *=16            // This enables use of all RAM.
#define FOSC 4000000  // increase if the autonomous clock is too slow

#fuses noWDT, NOPROTECT, BROWNOUT, PUT, NOLVP, DEBUG, hs//,h4// NOFCMEN//, hs, NOMCLR
#use delay(clock=FOSC)   
#include "flex_lcd_pidem.c"
#include "stdlib.h"

//------------------- rs232 dialog buffer and others------------------------
#use rs232(baud=4800,xmit=PIN_C6, rcv=PIN_C7,errors)
#define BUFFER_SIZE 80

//------------------- FOR EASY ZERO DRIFT TIMER -------------------
#define TimerDepth      65536      // for 16 bit timer
#define TimerPrescaler  2          // for prescaler div by 2 if fosc = 32 MHz
#define IS_LEAP(year) (year%4 == 0)
#define InteruptTime    0.01   // sec
#define SetTimer   (int16)( TimerDepth ) - (int16)( InteruptTime * (FOSC / 4) / TimerPrescaler )

// --------- GLOBAL DECLARATION --------------
short      SecondeFlag = 0;
short      ReadSerial = 0;
short      startok = 0;
BYTE       buffer[BUFFER_SIZE];
int8       index,x;                       
int8       heure = 0, Minute = 0, Seconde = 0 ;
int8       day = 0, month = 0, year = 0 ;
char      valid =' ';
char      dump[2];
int8       Sec100 = 0 ;

#int_timer1
void timer1_isr()
 {
  //------------------- DRIFT TIMER -------------------
  set_Timer1( get_timer1() + SetTimer ); // for exactly 100 mSec
  // -- autonomous clock  --
  if (++Sec100 == 100 )
   {
    Sec100 = 0 ;
    SecondeFlag = 1 ;
    if (++Seconde == 60)
     {         
      Seconde = 0;
      if (++Minute == 60)                // hours
       {           
        Minute = 0 ;
        if (++heure == 24)
         {
           heure = 0 ;                  // days

           Day++;
           if ((Day == 29 && Month==2 && !IS_LEAP(Year)) ||
              (Day == 30 && Month==2) ||
              (Day == 31 && (Month==4 || Month==6 || Month==9 || Month==11 )) ||(Day == 32))
            {
             Month++;
             Day=1;
            }
           if(Month == 13)
            {
             Year++;
             Month = 1;
            }
         }
       }
     }
   }
 }

//------------------rs232 dialog-------------------------------------------------
#int_rda
void serial_isr()
  {
   char c;
   c = getc();
   putc(c);
   if (c=='$')
    {
    index = 0;
     startok = 1;
    }
   buffer[index] = c;
   index++;
   if (index>BUFFER_SIZE)
    {
     index = 0;
    }
   if ((index>62) && (startok==1) && (buffer[3]=='R') && (buffer[4]=='M') && (buffer[5]=='C'))
    {
    startok=0;
    disable_interrupts(int_rda);
    readserial = 1;
    }
  }

#separate
void reset_serial()
 {
  ReadSerial = 0;
  index = 0;
  for(x=0;x<BUFFER_SIZE;x++) buffer[x]=' ';       // reset input buffer
  enable_interrupts(int_rda);
 }

//---------------- normal mode : clock update   -------------------
#separate
void flagseconde()
 {
  if (SecondeFlag)
   {  // refresh time each seconds
        SecondeFlag = 0;
      lcd_gotoxy(9,1);
        printf(lcd_putc,"%02u:%02u:%02u",heure,minute,seconde);
      lcd_gotoxy(9,2);
        printf(lcd_putc,"%02u/%02u/%02u",day,month,year);
       lcd_gotoxy(1,1);
      if (valid == 'A')
        {
        lcd_putc("valid");
       }
      else
        {
        lcd_putc("wait ");
       }
   } //if (SecondeFlag)
 } //flagseconde()

void main()
 {
  output_high (PIN_D7);  //specific to picdem 2+
  output_low(LCD_RW);    //specific to picdem 2+
  lcd_init();
  lcd_putc("\f");
  lcd_putc("hello");
  delay_ms(1000);

  setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); // divide by two when Fosc is high i.e. 32 MHz
  enable_interrupts(GLOBAL);
  set_Timer1( SetTimer );
  enable_interrupts(INT_TIMER1);
  reset_serial();

  while (true)
   { 
    if ( readserial == 1 )
     {
      dump[1] = buffer[12];
      dump[0] = buffer[11];
      Seconde = atoi(dump);

      dump[1] = buffer[10];
      dump[0] = buffer[9];
      Minute = atoi(dump);

      dump[1] = buffer[8];
      dump[0] = buffer[7];
      Heure = atoi(dump);
      if (buffer[55]==',')
       {
        dump[1] = buffer[57];
        dump[0] = buffer[56];
        day = atoi(dump);

        dump[1] = buffer[59];
        dump[0] = buffer[58];
        Month = atoi(dump);

        dump[1] = buffer[61];
        dump[0] = buffer[60];
        year = atoi(dump);
       }

      if (buffer[56]==',')
       {
        dump[1] = buffer[58];
        dump[0] = buffer[57];
        day = atoi(dump);

        dump[1] = buffer[60];
        dump[0] = buffer[59];
        Month = atoi(dump);

        dump[1] = buffer[62];
        dump[0] = buffer[61];
        year = atoi(dump);
       }
      if (buffer[57]==',')
       {
        dump[1] = buffer[59];
        dump[0] = buffer[58];
        day = atoi(dump);

        dump[1] = buffer[61];
        dump[0] = buffer[60];
        Month = atoi(dump);

        dump[1] = buffer[63];
        dump[0] = buffer[62];
        year = atoi(dump);
       }
      valid = buffer[18];
      reset_serial();
     }
    flagseconde();   
   }
 }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 30, 2010 12:48 am     Reply with quote

Quote:

char dump[2];
int8 Sec100 = 0 ;


dump[1] = buffer[12];
dump[0] = buffer[11];
Seconde = atoi(dump);

atoi operates on a string. A string array for 2 chars requires a 3rd
element for the string terminator bytes (0x00). You need to increase
the 'dump' array size to 3 elements to allow space for the string terminator.

You also need to set the 3rd element to 0x00. If you can guarantee
that your code will never change the 3rd element, then you can just set it
to 0x00 one time. To be more safe, you could add some lines of code so
after each time you load indexes 1 and 0, to also set index 2 to 0x00.
dynamitron



Joined: 18 Mar 2009
Posts: 38

View user's profile Send private message

PostPosted: Fri Apr 30, 2010 10:01 am     Reply with quote

perfect, It works !!

thank you
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group