Sari la conținut
ELFORUM - Forumul electronistilor

PIC18F si gps u-blox neo6-m


moro

Postări Recomandate

Va salut, am luat recent un modul receiver gps via serial pe care vreau sa-l leg la un PIC18F2550 si apoi afisez pe display.

 

Datele pe serial vin asa  $GPGXL,3,4,5,6rn$GPGGA,4,3,2,1xxxxxrn$GPGLL,2,3,4xxxxxrn

 

Am intreruperea pe serial RX

 

 

 

 

char buffer[768];

 

void interrupt() {
if (RCIF_bit == 1) { // daca prind ceva...
buffer = UART1_Read(); // baga datele in txt
  i++;
  if (i == 768) {   // daca buferu e full
  i = 0; // reset
  ready = 1;  
  }
  RCIF_bit = 0;   // curata flagu`
  }
}

 

Iar in main am

 

char *zuzu;

char *zizi;

 

if(ready=1){

 

zuzu=strstr(txt,"GPGGA" );// imi returneaza "GPGGA,4,3,2,1xxxxxrn$GPGLL,2,3,4xxxxxrn"

 

zizi=strchr(zuzu,'$'); // imi returneaza $GPGLL,2,3,4xxxxxrn

 

 

int len1 = strlen(zuzu);

int len2 =strlen(zizi);

 

int length=len1-len2;

 

char myGPS[length+1];

}

 

Problema apare cand vreau sa bag fiecare caracter din *zuzu in array-ul myGPS

 

De exemplu vruiam ceva de genu myGPS[0] = zuzu[0]; myGPS[1]=zuzu[1]..... s.a.m.d, asa avand toate datele intr-un array char mi se pare mai usor de sortat/afisat

Se poate baga un pointer string intr-un charr array?

 

 

 

 

 

 

 

 

Link spre comentariu

Joaca-te cu uniuni in care sa ai structuri + vectori. Ceva in genul:

void main (void){   int i = 0;   typedef union {      struct {	unsigned short contorA;	unsigned short contorB;        unsigned char timpA;	unsigned char timpB;      };             unsigned char byteArr[6];   } __testStruct;   __testStruct testStruct;      testStruct.contorA = 0x1234;   testStruct.timpA = 0x56;   testStruct.contorB = 0x789a;   testStruct.timpB = 0xbc;      for(i=0; i<6; i++){      printf("%xn", testStruct.byteArr[i]);    }}

Din testele mele (gcc), functioneaza bine daca grupezi tipurile de date (unsigned char impreuna, unsigned short/int impreuna). Altfel, transforma unsigned char in unsigned short.

Editat de Liviu M
Link spre comentariu

Nu cred, dupa parerea mea Timeint = 0x01. Compilerul face cast implicit de la char la integer (de fapt o "promotie").

Ca doua variabile sa foloseasca aceeasi zona de memorie, trebuie sa folosesti sau pointeri sau uniuni. Am incercat varianta cu pointeri si, desi functioneaza cum trebuie, genereaza mesaje de avertizare la compilare. Cum nu sunt prea bun la folosit pointeri, nu exclud greseli in cod.

Mai jos e codul cu care am testat. Primul printf tipareste varianta ta, al doilea varianta cu pointer:

#include <stdio.h>#include <stdint.h>void main(void) {   char arr[] = {0x01, 0x02, 0x03, 0x04};   int intreg;   int *pointer;         intreg = arr[0];  //aloci lui intreg valoare de la indexul 0      pointer = &arr[0]; //aloci lui pointer adresa primului element din arr;                       //pentru ca adresa lui arr[0] este de fapt adresa lui arr,                      //pointer = &arr[0]; si pointer = &arr; sunt echivalente   printf("0x%xn", intreg);   printf("0x%xn", *pointer);}

Si rezltatele compilarii/rularii:

liviu@g510l:~/teste> gcc -o arr.o array.carray.c: In function ‘main’:array.c:11:12: warning: assignment from incompatible pointer type [enabled by default]    pointer = &arr[0];            ^liviu@g510l:~/teste> ./arr.o 0x10x4030201liviu@g510l:~/teste> 

PS Ca sa functioneze trebuie ca pointerul sa fie catre o variabila reprezentata pe 4 char. La programul pentru PC a mers pentru ca int e pe 4 byte, la picuri trebuie sa vezi cum sunt definite tipurile de date la compilatorul tau (la xc8 int e pe 16 biti).

 

LE Am comentat putin codul

Editat de Liviu M
Link spre comentariu

Multumesc inca o data LiviuM

eu lucrez cu PIC pe 32bit deci varibila int este pe 4 char exact ca la PC

deci vreau sa incarc din prima variabila intreg cu cei 4 char din memorie dupa care fac un xor pe 32bit si o pun la loc tot pe 4 char

intreg = arr[0]; // aici vreau sa incarc cei 4 charintreg ^= 0xBEEFBEEF;arr[0] = intreg; // aici salvez
Link spre comentariu

Nu, asa nu merge, ca la sfarsit o sa ai modificati tot numai 8 biti.Eu raman la parerea mea ca cel mai simplu tot cu uniuni se face:

#include <stdio.h>void main(void) {   int i = 0;      typedef union {          int int32bits;     unsigned char arr4bytes[4];         } __testStruct;      __testStruct testStruct;      printf("Inainte de XORn");   for(i=0; i<4; i++){      testStruct.arr4bytes[i] = i+1;      printf("0x%xn", testStruct.arr4bytes[i]);    }   printf("0x%xn", testStruct.int32bits);      testStruct.int32bits ^= 0xFFFFFFFF;   printf("Dupa XORn");   for(i=0; i<4; i++){      printf("0x%xn", testStruct.arr4bytes[i]);    }   printf("0x%xn", testStruct.int32bits);   }
"Listingul":
liviu@g510l:~/teste> gcc -o uniune.o struct.cliviu@g510l:~/teste> ./uniune.o Inainte de XOR0x10x20x30x40x4030201Dupa XOR0xfe0xfd0xfc0xfb0xfbfcfdfeliviu@g510l:~/teste> 
LE Merge si fara uniune dar cu pointeri, nu cu intregi "normali", ca la tine. Si de data asta compilatorul meu da mesaje de avertizare. Ai mai jos varianta combinata, pentru comparatie:
#include <stdio.h>void main(void) {   int i = 0;   int *test;   unsigned char arr4BytesNoUnion[] = {0x01, 0x02, 0x03, 0x04};      typedef union {          int int32bits;     unsigned char arr4bytes[4];         } __testStruct;      __testStruct testStruct;   printf("********************n");   printf("CU UNIUNEn");   printf("Inainte de XORn");   for(i=0; i<4; i++){      testStruct.arr4bytes[i] = i+1;      printf("0x%xn", testStruct.arr4bytes[i]);    }   printf("0x%xn", testStruct.int32bits);   testStruct.int32bits ^= 0xFFFFFFFF;   printf("Dupa XORn");   for(i=0; i<4; i++){      printf("0x%xn", testStruct.arr4bytes[i]);    }   printf("0x%xn", testStruct.int32bits);   printf("********************n");   printf("CU POINTERn");   printf("Inainte de XORn");   test = &arr4BytesNoUnion;      for(i=0; i<4; i++){      printf("0x%xn", arr4BytesNoUnion[i]);    }   printf("0x%xn", *test);      *test ^= 0xFFFFFFFF;      printf("Dupa XORn");   for(i=0; i<4; i++){      printf("0x%xn", arr4BytesNoUnion[i]);    }   printf("0x%xn", *test);   }
Si "listingul" cu mesajul de avertizare de la compilare:
liviu@g510l:~/teste> gcc -o uniune.o struct.cstruct.c: In function ‘main’:struct.c:36:9: warning: assignment from incompatible pointer type [enabled by default]    test = &arr4BytesNoUnion;         ^liviu@g510l:~/teste> ./uniune.o ********************CU UNIUNEInainte de XOR0x10x20x30x40x4030201Dupa XOR0xfe0xfd0xfc0xfb0xfbfcfdfe********************CU POINTERInainte de XOR0x10x20x30x40x4030201Dupa XOR0xfe0xfd0xfc0xfb0xfbfcfdfeliviu@g510l:~/teste> gcc -o uniune.o struct.c 
LE Am corectat varianta cu pointer. Editat de Liviu M
Link spre comentariu

bufferul la care vroiam sa am acces este circular si procesorul nu stie sa cileasca din RAM decit daca este aliniat la 4 byte, asa ca am renuntat si citesc byte cu byte

 

incearca sa folosesti atributul "packed".

 

exemplu:

 

struct my1

{

  char c;

  int   i;

}

 

struct my2

{

  char c;

  int   i  __attribute__((packed));

}

 

rezulta:

 

 size my1=8

 size my2=5

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări