![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
GPS receiving problem with pic 16f877a |
Posted: Fri Feb 21, 2014 12:42 am |
|
|
hi ,
i want to interfacing GPS with pic16f877a, i have complete my code, but while i test my code in project board,i can receive data from GPS one time only..receiver interrupt routine execute one time only ..i have problem in receiv. pls help me...
i have include my program here............
#include <16f877a.h>
#use delay(clock=20000000)
#fuses HS,NOWDT
#byte porta=0x05
#byte portb=0x06
#byte portc=0x07
#byte portd=0x08
#byte porte=0x09
#byte trisa=0x85
#byte trisb=0x86
#byte trisc=0x87
#byte trisd=0x88
#byte trise=0x89
#BYTE PIR1=0X0C
#BYTE PIE1=0X8C
#BYTE RCREG=0X1A
#BYTE INTCON=0X0B
#BYTE TXSTA=0X98
#BYTE SPBRG=0X99
#BYTE RCSTA=0X18
#BIT GIE=INTCON.7
#BIT PEIE=INTCON.6
#BIT RCIF=PIR1.5
#BIT RCIE=PIE1.5
#bit rs=0X08.6
#bit en=0X08.7
void LcdCommandWrite(int8 com);
void LcdDatawrite(int8 data);
void LcdInit();
int i=0,j,flag=0,REC_FLAG=0;
int8 data[77],test[]="$GPGGA,";
#INT_RDA
void rx_data(void)
{
data[i]=RCREG; // Store data in Reception regist
i++;
}
void main() //Main entry
{
GIE=PEIE=RCIE=1;
RCSTA=0X90;
RCREG=0X00;
PIE1=0X20;
TXSTA=0X00;
SPBRG=0X1F;
trisb=0x00;
trisd=0x00;
trisc=0x80;
Lcdinit();
while(true)
{
if(i==77)
{
GIE=PEIE=RCIE=0; // disabling interrupt
for(j=0;j<7;j++)
{
if(data[j]==test[j])
flag=1;
else
flag=0;
}
if(flag==1)
{
LcdCommandWrite(0x80);
for(i=18;i<=28;i++)
{
LcdDatawrite(data[i]);
}
LcdCommandWrite(0xc0);
for(i=30;i<=41;i++)
{
LcdDatawrite(data[i]);
}
//delay_ms(1000);
for(i=0;i<=77;i++)
{
data[i]=0;
}
flag=0;
GIE=PEIE=RCIE=1; //enabling interrupt
i=0;
}
}
}
}
void LcdInit()
{
LcdCommandWrite(0x38);
LcdCommandWrite(0x0c);
LcdCommandWrite(0x06);
LcdCommandWrite(0x01);
LcdCommandWrite(0x80);
}
void LcdCommandWrite(int8 com )
{
rs=0;
portb=com;
en=1;
delay_ms(1);
en=0;
}
void LcdDatawrite(int8 data)
{
rs=1;
portb=data;
en=1;
delay_ms(1);
en=0;
} _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Fri Feb 21, 2014 2:16 am |
|
|
1) Don't duplicate post.
2) Use the CCS functions (getc, putc etc..).
3) Learn to use the code buttons.
4) The reason is that if data arrives while your interrupts are disabled, this will hang the UART, so it stops working. If you use the CCS RS232 functions with 'ERRORS' in the #use rs232 command, the compiler will automatically add code to clear this problem. Also it'll get the baud rate calculation right. You are currently running at 9765.625 baud...
Generally, 'reconsider'. Leave the interrupt enabled, and use a circular buffer. This way data that arrives in the long time needed to update the LCD, won't be lost.
As it is the code will no longer hang if you use the CCS functions, but the data will still have been lost, so the 'count' based input method will no longer be synchronised to the data....
Code: |
#include <16f877a.h>
#use delay(clock=20000000)
#fuses HS,NOWDT
#USE RS232(UART1, ERRORS, baud=9600)
//seriously look at the flex_lcd driver in the code library, rather
//than your own code here...
int i=0,j,flag=0,REC_FLAG=0;
int8 data[77],test[]="$GPGGA,";
#INT_RDA
void rx_data(void)
{
data[i++]=getc(); // Store data in Reception regist
}
void main(void) //Main entry
{
delay_ms(100);
//generally, LCD's need a bit more delay before starting. Hence pause
//before initialising.
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
Lcdinit();
while(TRUE)
{
if(i==77)
{
disable_interrupts(INT_RDA); // disabling interrupt
for(j=0;j<7;j++)
{
if(data[j]==test[j])
flag=TRUE;
else
flag=FALSE;
}
if(flag==TRUE)
{
LcdCommandWrite(0x80);
for(i=18;i<=28;i++)
{
LcdDatawrite(data[i]);
}
LcdCommandWrite(0xc0);
for(i=30;i<=41;i++)
{
LcdDatawrite(data[i]);
}
for(i=0;i<=77;i++)
{
data[i]=0;
}
flag=0;
i=0; //don't enable the interrupt till _after_ this is set to zero
enable_interrupt(INT_RDA);
}
}
}
}
|
I really would suggest rethinking the approach, since it still won't work, because the characters may have been missed during the slow LCD operations. However it may well work if you switch to using the flex_lcd driver, since this is much faster than your code.... |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Fri Feb 21, 2014 4:11 am |
|
|
THANKING YOU FOR YOUR REPLY SIR,
I changed my code what you suggest me,still no improvement in my code and one more thing is i got some warning like variable never used :rs232_error.
I referred PCW C Compiler Reference Manual.
ERRORS Used to cause the compiler to keep receive errors in the variable RS232_ERRORS and to reset errors when they occur. _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Fri Feb 21, 2014 4:20 am |
|
|
the RS232ERRORS message, is a warning, not an error. When it adds the error handler it generates a variable, so you _can_ tell what has happened. This causes a warning unless you use it. A search here will find all about it.
Have you switched to flex_lcd?.
Read this comment:
"I really would suggest rethinking the approach, since it still won't work, because the characters may have been missed during the slow LCD operations. However it may well work if you switch to using the flex_lcd driver, since this is much faster than your code...."
Note 'may well'. Not 'will'. |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Fri Feb 21, 2014 4:24 am |
|
|
sir,
i dont have any idea about flex_lcd driver ..... pls give some tips _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Feb 21, 2014 7:54 am |
|
|
pathmasugu wrote: | sir,
i dont have any idea about flex_lcd driver ..... pls give some tips |
Folow this link
http://www.ccsinfo.com/forum/viewtopic.php?t=24661
You could try dealing with slow LCD writing two ways:-
1) Have two RX buffers, which you use alternately.
2) Copy data in RX buffer to another array and process from copy.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Feb 21, 2014 8:14 am |
|
|
Pathmasugu,
You started off by posting some code that is about as far from the 'CCS-Way" as you can get, and now you 'don't have any idea' about a driver (flex_lcd) that is very ubiquitous here on the forum. Rather than parachuting in here with a million questions, may I suggest that you spend a bit of time with (1) the CCS manual, and (2) the forum archives. Do a bunch of reading to bring yourself up to speed, otherwise your reign here, like many other 'newbies' before you, will be short and sweet......
Cheers,
John |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Fri Feb 21, 2014 2:11 pm |
|
|
Thanking you for your advice sir ...I'm the beginner of CCS..... now I'm start to study those things....i will contact soon through forum... and also thanks to Mr. Mike for your information. _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Sat Feb 22, 2014 2:54 am |
|
|
One thing that is fundamentally going to cause problems is the 'count' approach.
Yes, count through an individual packet, but you are ignoring, extra characters that may be there (most packets from GPS's etc., will have extra characters - line feed, carriage return etc.), and with the missing character(s) because of your slow LCD handling. These mean you will go 'out of sync'. This is the whole 'point' of the header ($GPGGA). The 'reliable' approach, is to write the code to keep looking for the '$', and at this point reset the counter. Then check that the next set of characters are the 'GPGGA' header, and then retrieve what you want. This way, if there are extra characters, or characters are missed, the code will 're-synchronize' at the next header.
Assuming that characters will never be missed, or that there are no extra characters, is always an unreliable way to work....
A state machine, that searches for the header (search here), is the normal 'good' approach. |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
thank you to all ...... now my GPS working good........ |
Posted: Mon Mar 17, 2014 11:44 am |
|
|
![Very Happy](images/smiles/icon_biggrin.gif) _________________ ROCK RAJ |
|
![](templates/subSilver/images/spacer.gif) |
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon Mar 17, 2014 3:04 pm |
|
|
Hi,
Hmmm, since YOU came her looking for our help, why not 'pay it forward', and post your working code so that others like you might benefit from it?
John |
|
![](templates/subSilver/images/spacer.gif) |
pathmasugu
Joined: 21 Feb 2014 Posts: 25
|
|
Posted: Tue Mar 18, 2014 1:07 am |
|
|
ya sure , Code: | #include <18F452.h>
#use delay(clock=20000000)
#Fuses HS
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=GPS,errors)
#byte portb=0xf81
#byte trisb=0xf92
#BYTE TRISC=0XF94
#include "flex_lcd.c"
int i=0,j=0,flag=0;
int8 data_gps[77],count=0;
char data,lati_data[11],longi_data[12];
// int8 tepmtest[7],test[]="$GPGGA,";
#INT_RDA
void rx_data(void)
{
data_gps[i++]=getch(); // Store data in Reception regist
count++;
if(i>77||count>77)
{
count=i;
i=0;
}
}
char bgetch()
{
char c;
while(count==0);
c=data_gps[j];
if(++j > 77)
j=0;
if(count)
{
count--;
}
return c;
}
void main()
{
int i;
trisb=0;
TRISC=0x80;
DELAY_MS(100);
lcd_init();
lcd_gotoxy(0x0f,1); /// for checking LCD display
lcd_putc('A');
lcd_gotoxy(0x0f,2);
lcd_putc('B');
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
while(true)
{
data=bgetch();
if(data=='$')
{
data=bgetch();
if(data=='G')
{
data=bgetch();
if(data=='P')
{
data=bgetch();
if(data=='G')
{
data=bgetch();
if(data=='G')
{
data=bgetch();
if(data=='A')
{
data=bgetch();
if(data==',')
{
data=bgetch();
while(data!=',')
data=bgetch();
for(i=0;data!='N';i++)
{
data=bgetch();
lati_data[i]=data; // Store the Latitude data
}
data=bgetch();
if(data==',')
{
for(i=0;data!='E';i++)
{
data=bgetch();
longi_data[i]=data; // Store the Longitude data
}
}
i=0;
lcd_gotoxy(1,1);
while(i<11)
{
lcd_putc(lati_data[i]); // Print the Latitude data
i++;
}
i=0;
lcd_gotoxy(1,2);
while(i<12)
{
lcd_putc(longi_data[i]); // Print the Longitude data
i++;
}
}
}
}
}
}
}
}
for(i=0;i<12;i++)
{
data=0;
lati_data[i]=0;
longi_data[i]=0;
}
}
}
|
_________________ ROCK RAJ |
|
![](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
|