GPS problem

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Christian
Inlägg: 86
Blev medlem: 3 november 2003, 22:54:49

GPS problem

Inlägg av Christian »

Jag har kämpat ett tag nu försökt att få min GPS parser att fungera. Jag försöker att vänta på en GPS mening och sedan skriva ut den. Jag har testat min kod med HyperTerminal och manuellt matat in en GPRMC mening och fått det att fungera, men när jag ansluter GPS-mottagaren istället får jag ingenting på skärmen .. Gps:en har funktionstestats mot ett terminalprogram så inget problem där.
Har någon en tanke?
Jag använder:

*pic16f690 på ett PICKIT2
*EM-406 GPS-modul, output är TTL
*interna 4Mhz klockan
*baudrate 4800

Jag tycker att det är riktigt märkligt!

Kod: Markera allt

#include <pic.h>
#include <htc.h>
#include "lcd.h"
#include "delay.h"


__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & BORDIS & IESODIS & FCMDIS);
unsigned int BUFFMAX = 80;
unsigned char gps_string[80];	//Databuffer
//char gps_string2[] = "$GPRMC,224204.000,A,5535.3985,N,01300.8159,E,6.83,258.07,040810,,*0F";

int head = 0; 


void usart(void){
	TRISB = 0XFF;
	#asm
	bcf _TRISB,7	//RB7 USART-output 	
	#endasm
	TRISC = 0X00;	//Just for debug
	PORTC = 0;		//-||-
	ANSELH = 0x00; 	//All pins digital
	SPBRG = 51;		//4800 bps
	BRGH = 1;
	TXEN = 1; 		//Allows sending
	SYNC = 0; 		//The SYNC bit should be cleared to select asynchronous operation.
	SPEN = 1; 		//SPEN bit is used to enable the entire serial port
	CREN = 0;
	CREN = 1; 		//Allows receiving
	GIE = 1;  		//*Interrupts
	PEIE = 1;
	TXIE = 0; 		//Disable transmit interrupt
	RCIE = 1; 		//Enable receive interrupt

}

void putch(unsigned char c){ 
	
	while(!TXIF) 	//Set when TXREG is empty
	continue; 		//Continue looping while TXREG is not available
	TXREG = c; 		//Put character to be sent onto TXREG 

}


enum {START_WAIT, RECEIVING, MSG_RECEIVED} state = START_WAIT;  
void interrupt pic_isr(void) {  
    unsigned char c;
	if((RCIE)&&(RCIF)){                                  // If this interrupt was generated by a receive character  
		c = RCREG;
	 	switch(state){
						
			case START_WAIT:
				if(c == '$'){
					head = 0;
					state = RECEIVING;
				}
				break;
			case RECEIVING:
					
					if(c == '*'){
						state = MSG_RECEIVED;
					}
					else{
						gps_string[head] = c;
						if(++head>=BUFFMAX){
							state = START_WAIT;
						}					
					}
					break;	
		}
	}
   	if(OERR){           // If we missed a character (Overrun Error) 
    	CREN = 0;          // Reset the error bit  
		CREN = 1;
	}
} 

void main(void){
	usart();									//Initialize USART
	while(1){								
		if(state == MSG_RECEIVED){
				for(int i = 0; i <= head; i++){
					putch(gps_string[i]);
				}	
			state = START_WAIT;		
		}
	}
}





Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Gps problem

Inlägg av Icecap »

Det jag faller över omedelbart är detta:

Kod: Markera allt

void putch(unsigned char c)
  {
  while(!TXIF)    //Set when TXREG is empty
  continue; // <-- Vad fan är detta?
  TXREG = c;       //Put character to be sent onto TXREG
  }
Om det betyder vad jag tror kollar den en gång om TXIF är noll - och kastar sedan ut c i TXREG ändå.

Jag har å andra sidan aldrig använd "continue" men nu där jag slår upp det i min "bibel" ser jag att det är precis som jag misstänker. Spola helt enkelt "continue" skiten och använd den rätt nästa gång.

Kod: Markera allt

void putch(unsigned char c)
  {
  while(!TXIF);    //Set when TXREG is empty
  TXREG = c;       //Put character to be sent onto TXREG
  }
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Gps problem

Inlägg av johano »

Nej "continue" innebär att alla efterföljande satser i loopen skippas och nästa iteration startar direkt

I det här fallet så gör "continue" ingenting då det inte finns några satser efter och resultatet blir detsamma som med while(..);


/johan
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Gps problem

Inlägg av sodjan »

Vad har du gjort för att felsöka (förrutom att köra en GPS sträng från en annan källa) ?
Har du t.ex kör GPS'en mot Hyperterminalen för att verifiera strängen ?
Har du försökt visa någonting alls från GPS'en på LCD'n ?
O.s.v.
Christian
Inlägg: 86
Blev medlem: 3 november 2003, 22:54:49

Re: Gps problem

Inlägg av Christian »

Vad har du gjort för att felsöka (förrutom att köra en GPS sträng från en annan källa) ?
Har du t.ex kör GPS'en mot Hyperterminalen för att verifiera strängen ?
Har du försökt visa någonting alls från GPS'en på LCD'n ?
Jag har kört GPS'en direkt mot en PC med en max232 emellan och det fungerar utmärkt.

Jag har provat att ta alla tecken mellan '$' och det första ',' vilket blir GPRMC, men detta går inte heller.

Just nu använder jag inte LCD:n utan skickar de sparade tecken ut via UARTEN igen till en PC.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Gps problem

Inlägg av sodjan »

OK, så för att sammanfatta :

GPS => MAX232 => PC/COMx: OK
PIC => MAX232 => PC/COMx: OK
PC/COMx: => MAX232 => PIC OK
GPS => PIC EJ OK. (Ingen MAX232 här alltså, vilket borde vara OK).

Är det korrekt uppfattat ?

En annan sak, du säger att du kör med 4 MHz (och inget i koden motsäger det)
men SPBRG = 51 hittar jag bara i tabellen under "8 MHz" för just 4800 baud. Du
verkar köra med 9600. Antingen ser jag fel eller så kör du med fel värde och jag
tänker inte kolla det... :-)
Christian
Inlägg: 86
Blev medlem: 3 november 2003, 22:54:49

Re: Gps problem

Inlägg av Christian »

GPS => MAX232 => PC/COMx: OK
PIC => MAX232 => PC/COMx: OK
PC/COMx: => MAX232 => PIC OK
GPS => PIC EJ OK. (Ingen MAX232 här alltså, vilket borde vara OK).
Ovanstående är korrekt!
En annan sak, du säger att du kör med 4 MHz (och inget i koden motsäger det)
men SPBRG = 51 hittar jag bara i tabellen under "8 MHz" för just 4800 baud. Du
verkar köra med 9600. Antingen ser jag fel eller så kör du med fel värde och jag
tänker inte kolla det...
För att komma fram till SPBRG = 51 gjorde jag följande:

Jag antar att 4MHz är standard klockfrekvens om man inte definierar den till ett annat värde, korrekt?

Sen tittade jag i baudrate tabellen i databladet och hittade inget värde i tabellen på SPBRG som motsvarade 4800bps. Så då tog jag formlerna till hjälp:

*4MHz oscillator
*4800 baud asynchront
1. För BRGH = 1
SPBRG = 4000000/(16 x 4800) - 1 = 51,083
2. För BRGH = 0
SPBRG = 4000000/(64 x 4800) - 1 = 12,0208

Jag valde då BRGH = 1 med SPBRG = 51,08 eftersom detta skulle vara (highspeed) då jag tyckte att felmarginalen var liten i båda fallen.

Är tillvägagångsättet galet?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Gps problem

Inlägg av sodjan »

Nej, det verkar stämma, jag förväxlade 2400 (som finns i tabellen)
med 4800 som du vill ha (och verkar ha).

Ja, då är det väl bara att fortsätta felsöka till du hittar det.
Får du något *alls* till PIC'en när du kör från GPS'n ?
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Gps problem

Inlägg av Icecap »

Lite knasigt som jag föll över:

Kod: Markera allt

unsigned int BUFFMAX = 80;
unsigned char gps_string[80];   //Databuffer
Där bäddar det för fel! Testa istället:

Kod: Markera allt

#define BUFFMAX 80
unsigned char gps_string[BUFFMAX];   //Databuffer
och sedan där detta används igen:

Kod: Markera allt

...
               else{
                  gps_string[head] = c;
                  if(++head >= sizeof(gps_string)){
                     state = START_WAIT;
                  }               

Rent omedelbart ser jag inte några direkta fel i mjukvaran men JAG hade testat att växla nivå på en pinne för varje byte som tas emot och kollat att det faktisk tas emot saker. Man kan testa att ha den (om man bara har 1 pinne) till att visa status på "state", sedan växla läge för varje mottagna char, kanske växla läge vid felindikering osv, fast såklart bara en av sakerna åt gången.

Finns det ett fungerande LCD är det ju hur enkelt som helst att skriva ut antal mottagna tecken, ha en position att visa "state"-läge osv.

En sak jag inte har kollat mer på men som jag är lite tveksam till är om UART'en bara kan rapportera OERR, hade för mig att det finns 1 mer. *hmmm, kolla datablad* JUPP, där var den: FERR! Ta hand om den också vetja!

Och när du initialiserar UART'en kan det vara en synnerligt bra idé att förutom att lägga TX-portpinnen till utgång att även lägga en '1' på den till att börja med, det gör att första char som sänds kommer rätt direkt.
victor_passe
Inlägg: 2436
Blev medlem: 28 januari 2007, 18:45:40
Ort: Kungsbacka

Re: Gps problem

Inlägg av victor_passe »

Jag hade satt PIC:en mellan datorn och GPS:en bara för att se så PIC:en tar emot byten korrekt.
Alltså det du läser på uart skriver du på uart.

Men har du ett oscilloskop? Det skulle underlätta felsökningen.
Nerre
Inlägg: 27257
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Gps problem

Inlägg av Nerre »

När du provade att köra terminal mot PICen (PC/COMx: => MAX232 => PIC OK), skrev du in strängarna manuellt då? Eller hade du dem i en fil och skickade?

En inte helt okvalificerad gissning är att problemet är att PICen inte hinner med flera tecken direkt följd. Skriver man för hand kommer det inte många tecken i sekunden, men GPS:en skickar väl tecknen i direkt följd (och 4800 bps ger 480 tecken i sekunden).
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: GPS problem

Inlägg av sodjan »

Ja, man måste ju naturligstvis ha rutiner som läser tecken-för-tecken
och sparar undan en buffert. Man har alltså ca 2 ms/tecken, eller ca 1500-2000
instruktioner vid 4 Mhz, på sig mellan varje tecken, annars blir det "overrun".
Så *PIC'en* hinner med, frågan är om koden gör det... :-)
Användarvisningsbild
jadler
EF Sponsor
Inlägg: 407
Blev medlem: 28 maj 2009, 12:03:43
Ort: Vidja, Huddinge, Stockholm
Kontakt:

Re: GPS problem

Inlägg av jadler »

Jag tror jag har skrivit om det någonstans här tidigare. När jag skulle läsa av en GPS-pryl (som sannolikt innehåller samma modul som du har) kom jag fram till att den använder inverterade signalnivåer, så logisk etta är 0 V, logisk nolla +5 V. Du kan testa om det fungerar med inverterad signal.
Skriv svar