![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
dynamitron
Joined: 18 Mar 2009 Posts: 38
|
GPS and software RTC |
Posted: Thu Apr 29, 2010 11:42 pm |
|
|
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();
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 30, 2010 12:48 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
dynamitron
Joined: 18 Mar 2009 Posts: 38
|
|
Posted: Fri Apr 30, 2010 10:01 am |
|
|
perfect, It works !!
thank you |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|