Forum: Mikrocontroller und Digitale Elektronik STM32 Zeichen filtern


von Flo (Gast)


Lesenswert?

Holla,

ich versuche gerade NMEA Daten zu filtern,
und das scheint schwieriger als man denkt -__-

so empfange ich per funktionierendem Interrupt
die Daten

Interrupt:
1
void USART1_IRQHandler(void)
2
{
3
4
  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
5
  {  data[Ucounter++] = USART_ReceiveData(USART1) & 0x7F;
6
    //USART_SendData(USART1, data[Ucounter-1]);
7
    GPIO_ResetBits(GPIOE,GPIO_Pin_7);
8
9
  //
10
11
    if (USART_ReceiveData(USART1) == 0x0A )
12
    {
13
    
14
    GPIO_SetBits(GPIOE,GPIO_Pin_7);
15
    USART_ClearITPendingBit(USART1, USART_FLAG_RXNE) ;
16
    Ucounter =0;
17
    GPS_Messung(data);
18
    }
19
20
  }
21
22
}



nun versuche ich die Daten sauber zu seperieren!
als bedingung suche ich V und T für $GPVTG Datensatz!

Ich weiß dass nach dem 7ten kommata
die Zahl anfängt, durch ein Punkt getrennt wird, und dannach die 
Nachkommastellen bis zum nächsten Komma da sind.

Beispiel
GPVTG,309.62,T, ,M,0.13,N,0.2,K,A*23

0.2 brauch ich!

Ich habe folgende Funktion
1
void GPS_Messung(char *GPS1)
2
{    
3
4
if ((GPS1[3] == 'V') && (GPS1[4] == 'T'))       
5
       
6
    {
7
      
8
      
9
      for (i=0; counter == 8; i++)
10
      { USART_SendData(USART1, GPS1[i]);  
11
      
12
       
13
          
14
  
15
      GPIO_SetBits(GPIOE,GPIO_Pin_4);
16
      
17
        if ((counter == 7) && (start1 != 0) && (GPS1[i] != '.' ) && (GPS1[i] != ','))
18
          {            
19
            gesucht2[z++] = GPS1[i];        
20
          }
21
22
        if ((counter == 7) && (start1 != 1) && (data[i] != '.' ) && (GPS1[i] != ','))
23
          {                      
24
            gesucht1[p++] = GPS1[i]; 
25
          }
26
      
27
        if (GPS1[i] == ',')
28
          {
29
            counter++; GPIO_ResetBits(GPIOE,GPIO_Pin_4);
30
          }
31
32
        if (GPS1[i] == '.')
33
           {   
34
            start1 = 1;          
35
           }
36
        //USART_SendData(USART1, data[i]);
37
        
38
        if (counter == 8)
39
          {
40
            i = 0;
41
            gesucht1[p++] = '0';
42
            gesucht2[z++] = '0';
43
            p=0;
44
            z=0;
45
              
46
          }
47
        }
48
      }
49
50
  v = atoi(gesucht1);
51
  n = atoi(gesucht2);

mit dieser Funktion sendet mir die Uartschnittstelle nichts!

nehme ich USART_SendData(USART1, GPS1[i]
vor die schleife und setze für i einen beliebigen wert ein,
dann sehe ich zwar die stelle,
aber bringt mich nicht wirklich weiter


also wie kann ich GPS1 über Uart anzeigen lassen?
oder gibs eine bessere möglichkeit der Filterung?

von SNR (Gast)


Lesenswert?

Müsste das nicht so heißen:
1
if ((GPS1[2] == 'V') && (GPS1[3] == 'T'))
Strings fangen bei [0] an!

von Flo (Gast)


Lesenswert?

jepp -_-

und dabei zähle ich schon die ganze zeit an meiner hand
wann wo die richtige stelle ist :P

aber abgesehen von diesem missgeschick,
müsste der mikrocontroller mir doch
GPS1 bis der counter halt 8 ist anzeigen, oder nicht?

von SNR (Gast)


Lesenswert?

Achja, Du könntest auch schauen ob es zu STM eine String.h gibt wo 
solche Dinge wie
1
char * strtok(char *string, char *delimiters);
bereits für Dich implementiert worden sind.

Dann kannst Du die fertigen Token seperat abspeichern, in Zahlen wandeln 
und feddisch.

Hier noch ein Link dazu:
http://www.c-howto.de/tutorial-strings-zeichenketten-stringfunktionen-zerteilen-strtok.html

Oder eben nur stur nach dem Trennzeichen suchen und zwischen den 
Trennzeichen in einen seperaten String speichern. Dann brauchst Du nur 
noch das richtige Token auswählen (Nebenbei hast Du auch noch die 
anderen).

Grüße

von Flo (Gast)


Lesenswert?

ja gibt es, werde es mir mal anschauen...

danke dir für den tipp

aber sagt mal, habt ihr vielleicht einen tipp,
warum ich zum beispiel nicht

char GPS1[] = [a,b,c,d,e,f,g,h];
int i = 0;
for (i=0; i > 7; i++)
{
 USART_SendData(USART1, GPS1[i]);
}

machen kann?

von Grml .. (grml)


Lesenswert?

du solltest dir mal bei beiden for-Schleifen deine Abbruchbedingungen 
anschauen.

von Jim M. (turboj)


Lesenswert?

Dein Interrupt ist ausbaufähig. USART_ReceiveData() sollte man nur 
einmal aufrufen, und sich das Ergebnis merken - der 2. Aufruf könnte 
u.U. ein anderes Ergebnis liefern.

USART_ClearITPendingBit() wird nur am Stringende aufgerufen. Wenn man 
das wirklich bräuchte, würde sich dein IRQ Handler bei allen anderen 
Zeichen ständig selbst wieder aufrufen. Aber das Lesen aus dem "Receive" 
Register hat normalerweise denselben Effekt - Rücksetzen des 
Empfängerflags - daher ist auch dieser Aufruf unnötig.

1
void USART1_IRQHandler(void)
2
{
3
4
  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
5
  { unsigned char uartVal = USART_ReceiveData(USART1); 
6
    data[Ucounter++] = uartVal & 0x7F;
7
    //USART_SendData(USART1, data[Ucounter-1]);
8
    GPIO_ResetBits(GPIOE,GPIO_Pin_7);
9
10
    if (uartVal == 0x0A )
11
    {
12
    
13
    GPIO_SetBits(GPIOE,GPIO_Pin_7);
14
    // Wieso nur am Ende des Strings? Sicherlich unnötig
15
    // USART_ClearITPendingBit(USART1, USART_FLAG_RXNE) ;
16
    Ucounter =0;
17
    GPS_Messung(data);
18
    }
19
20
  }
21
22
}


Bei den 4800 Baud des GPS sind diese Sachen aber allesamt kosmetisch.

von SNR (Gast)


Lesenswert?

Nebenbei auch noch:
1
char GPS1[] = ['a','b','c','d','e','f','g','h'];

von SNR (Gast)


Lesenswert?

Natürlich in geschweiften Klammern...

von Flo (Gast)


Lesenswert?

Guten morgen,

den Fehler in meinem zweiten Beispiel,
mit '' und geschweifter klammer ist mir auch aufgefallen

Also die Idee war folgende,

da die NMEA Datensätze Blockweise schön geordnet kommen,
lese ich jede Zeile ein, und vergleiche diese mit meiner Bedingung
(Stellen für V un T)

(Zur Veranschaulichung: NMEA allgemein
http://murlowsky.homedns.org/cmsimple/images/Bastelei/SiRFDemo/nmea.jpg)

Jede Zeile endet mit <cr><lf>,
deswegen das beenden mit 0x0A



Aber was Uart angeht bin ich ziehmlich frisch,
also die Fehler die man machen kann,
werde ich auch wohl machen -_-

jim, was meinst du mit der Frage in deinem Code "wieso nur am Ende"
meinst du das Anschalten der LED?

Danke schonmal bis dato

von Flo (Gast)


Lesenswert?

Jim Meba schrieb:
> Bei den 4800 Baud des GPS sind diese Sachen aber allesamt kosmetisch.

bei mir sind es 38400 ;)
also aufpassen ;)

von Flo (Gast)


Lesenswert?

Sooo nochmal, ich glaube hier sind zuviele Fehler die mich wahnsinnig 
machen.
Lösen wir sie Step by Step

Problem 1:

einzelne Char (oder so ein selfmade string)
kann ich über den Befehl USART_SendData(USART1, "Test")
senden,

aber sobald in einer schleife integriert, egal wo,
passiert nichts.

z.B.
1
char GPS1[] = ['a','b','c','d','e','f','g','h'];
2
int i = 0;
3
for (i=0; i !8; i++)
4
{
5
 USART_SendData(USART1, GPS1[i]);
6
}
es passiert nichts!

Liegt es am USART Interrupt,
da ich nur für RXNE konfiguriert habe?
1
void USART1_IRQHandler(void)
2
{
3
4
  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
5
  { unsigned char uartVal = USART_ReceiveData(USART1); 
6
    data[Ucounter++] = uartVal & 0x7F;
7
   
8
    GPIO_ResetBits(GPIOE,GPIO_Pin_7);
9
10
    if (uartVal == 0x0A )
11
    {
12
    
13
    GPIO_SetBits(GPIOE,GPIO_Pin_7);
14
    // USART_ClearITPendingBit(USART1, USART_FLAG_RXNE) ;
15
    Ucounter =0;
16
    //GPS_Messung(data);
17
    }
18
19
  }
20
21
}

von Uwe (Gast)


Lesenswert?

Wo ist die Null Terminierung

char GPS1[] = ['a','b','c','d','e','f','g','h',0];

Bitte unterscheide zwischen chars und strings
Du solltest dir noch mal die Kapitel Felder (Arrays) und Pointer sowie 
Strings durchlesen ( in deinem C Buch )

von Flo (Gast)


Lesenswert?

das mit der Nullterminierung ist richtig!

denke ich habe ein anderes Problem:

dadurch das das Nmea Protokoll so lang ist,
schaffe ich es nicht einen Teilstring zu entnehmen,
und bearbeiten zu lassen, ohne das es überschrieben wird

Beispiel (mit nur 3 NMEA Datensätzen):

Pause
$GPGPA(Daten...)<LF><CR>$GPRMC(Daten...)<LF><CR>$GPGP(Daten...)<LF><CR>
Pause
$GPGPA(Daten...)<LF><CR>$GPRMC(Daten...)<LF><CR>$GPGP(Daten...)<LF><CR>
Pause
$GPGPA(Daten...)<LF><CR>$GPRMC(Daten...)<LF><CR>$GPGP(Daten...)<LF><CR>
Pause
(...)

Während USART
$GPGPA(Daten...)<LF><CR> ausliest, und ins Array schreibt,
bei <cr> den Counter auf 0 setzt, und weiterhin ausliest

fängt meine Funktion an das Array auszulesen,
aber durch das Counter auf 0 setzen,
wird das Array schneller überschrieben als die Funktion es auslesen kann

ist meine Befürchtung richtig und wie würde man am besten vor gehen?

Ganzes NMEA in String erstellen,
Teilstring durch <cr><lf> separieren,
nach bestimmten Charreihenfolge suchen,
und dann wieder separieren,
um die zwei zahlenwerte die ich brauche zu suchen?

von spess53 (Gast)


Lesenswert?

Hi

>wird das Array schneller überschrieben als die Funktion es auslesen kann

Welche Update-Rate hat denn dein GPS?

MfG Spess

von Flo (Gast)


Lesenswert?

Position UP-DATE Rate: 5 Hz

TTL Level 3.3 Volt
 Baud rate: 38,400 bps
 0 to 0.6 Volt TTL Low Level
 2.31 to 3.3 Volt TTL High Level
 3.3 Volt +/- 2% TTL Level Tolerance
 Output protocol: NMEA 0183 GGA, GSA, GSV, RMC, VTG

von Uwe (Gast)


Lesenswert?

38400 Baud sind doch nur ca. 3800 Zeichen pro Sekunde. Das muß der C 
schon schaffen. Da stimmt doch was nicht !

von spess53 (Gast)


Lesenswert?

Hi

>Position UP-DATE Rate: 5 Hz

Und da soll ein 32-Bit-Controller so einen läppischen NMEA-String nicht 
zerpflücken können bevor der nächste rein kommt? Kann ich nicht glauben. 
Das habe ich schon mit einem AVR geschafft, nebenbei noch ein 
Grafikdisplay mit Karte bedient, und der hat sich gelangweilt.
Dein Fehler liegt mit großer Sicherheit wo anders.

MfG Spess

von Flo (Gast)


Lesenswert?

Vielleicht blöde ausgedrückt,

ich mache ja aus dem

Pause
$GPGPA(Daten...)<LF><CR>$GPRMC(Daten...)<LF><CR>$GPGPS(Daten...)<LF><CR>
Pause

das hier

Pause
$GPGPA(Daten...)<LF><CR>
$GPRMC(Daten...)<LF><CR>
$GPGPS(Daten...)<LF><CR>
Pause

und gedanklich,
während ich
$GPGPA(Daten...)<LF><CR> nutzen möchte wirds mir durch
$GPRMC(Daten...)<LF><CR> und $GPGPS(Daten...)<LF><CR>

ich vermute es nur, ich weiß es nicht wirklich,
weil ich ein Zahlen, Punkt und Buchstaben wirrwar herausbekomme

von Flo (Gast)


Lesenswert?

sowas z.B.

                                           2,0802,273.12,0401,2AP3P*2P0,08,32,23
12,0,63,,2,,3032V0767,273.2,006S,12,733200416,L20031,210,1,0234312,0,1,2 
,N38,2*0
,1,,,2E,3,3250701,G2A,3.724071,,2,351420,21,20307420332,A25301440,0P,020 
3M.51041
,L2,,3,,5S0*70,720303520,47
                          ,A2,,3NA5G0148,32A*30F5,0A52,22131540,5,524,30,5V0149,
6,0,3,,2,3,,600,2,12,A3036V0757,429,30,6001B3,72,73336104C1,G2,3.96204D1 
,22,3016
40,AP,02,3,26003A,12135,6101AV,2,G3G36,0*A0,72,536S6203A1,,233E07,001,92 
03
                                                                          0710,1
3,12P,3737,0P1*,P2193,,7G0825,124313850129,27T3.8,0,20,12034081002,,2
                                                                     *373830
                                                                            2,,2
R373810P2*,,2,231,8,0,2,,L243A3850121,.273A3810129,.2,331,820S21,,2
                                                                   3373830
                                                                          2,,
                                                                             2,3
0A800,DP,320,32,9003D6,621G3G19303D4,27,30,910$D9,721139S9$0322,020,3809
                                                                        0022,02
                                                                               V
2.,3N,8,0,33,32531P8,013,,2,A30,8V0737,273.830237,2.T3G8402C,$2,031S820,

von Uwe (Gast)


Lesenswert?

Double buffer (oder mehr)
Du schreibst in einen Puffer und wenn CR/LF kommt wechselst du zum 
anderen Empfangpuffer wärend du den ersten auswertest.
z.B. könntest du auch nach GPGPA suchen und alles was dahinter kommt bis 
zum CR/LF in Puffer 1 schreiben alles was hinter GPRMC bis zum CR/LF in 
puffer 2 usw. Eine andere Routine wertet diese dann im Hintergrund aus. 
Dazu muß aber zu jedem Puffer ein Flag gesetzt und abgefragt werden ob 
der Puffer gültige Daten enthält.

von Flo (Gast)


Lesenswert?

Hello again,

also ich habe versucht ein buffersystem mit flags hinzubekommen

so sieht es aus
1
void USART1_IRQHandler(void)
2
{
3
int NbrSend =0;
4
unsigned char Val;
5
6
7
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
8
    {        
9
     if (USART_ReceiveData(USART1) == '$')
10
       {
11
      *pflag++;
12
        if(*pflag == 4)
13
          {
14
            *pflag =0;
15
          }
16
        Ucounter = 0;
17
        *pflag = 1;
18
      }
19
      
20
      if (*pflag == 0)
21
        {
22
          if (USART_ReceiveData(USART1) != '$')
23
            {
24
             Val = USART_ReceiveData(USART1);
25
              data1[Ucounter++] = Val; 
26
              //USART_SendData(USART1, data1[Ucounter -1]);
27
            }
28
         
29
          /*else 
30
            {
31
             //data1[Ucounter++] = '/0';
32
             //NbrSend = Ucounter;
33
             
34
            }*/
35
        }
36
37
      if (*pflag == 1)
38
        {
39
            if (USART_ReceiveData(USART1) != '$')
40
             {
41
              Val = USART_ReceiveData(USART1);
42
              data2[Ucounter++] = Val;
43
              //USART_SendData(USART1, data2[Ucounter -1]);
44
             }
45
           /*
46
          else
47
            {
48
                NbrSend = Ucounter;
49
             Ucounter = 0;
50
             *pflag= 2;
51
            }*/    
52
        }
53
        
54
      if (*pflag == 2)
55
        {
56
            if (USART_ReceiveData(USART1) != '$')
57
             {
58
              Val = USART_ReceiveData(USART1);
59
              data3[Ucounter++] = Val;
60
              USART_SendData(USART1, data3[Ucounter -1]);
61
             }
62
            /*
63
          else
64
            {
65
                NbrSend = Ucounter;
66
             Ucounter = 0;
67
             *pflag= 0;
68
            }  */   
69
        }
70
    }
71
}

Dieser schafft es nicht ins nächste feld zu springen (*pflag == 1)


sowas für sich alleine geht ohne probleme
1
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
2
    {        
3
    /* if (USART_ReceiveData(USART1) == '$')
4
       {
5
      *pflag++;
6
        if(*pflag == 4)
7
          {
8
            *pflag =0;
9
          }
10
        Ucounter = 0;
11
        *pflag = 1;
12
      }
13
    */  
14
      if (*pflag == 0)
15
        {
16
          if (USART_ReceiveData(USART1) != '$')
17
            {
18
             Val = USART_ReceiveData(USART1);
19
              data1[Ucounter++] = Val; 
20
              USART_SendData(USART1, data1[Ucounter -1]);
21
            }
22
         
23
          else 
24
            {
25
             Ucounter =0;
26
             
27
            }
28
        }


Die Idee war folgende, es wird geschaut ob '$' empfangen wurde,
wenn ja, wird der zähler für die buffer inkremetiert,
sollte allerdings der zähler bei 4 sein, setze diesen wieder auf 0.
derCounter für die Arrays (Ucounter) wird auf 0 gesetzt.

wird jetzt kein '$' empfangen,
weiß das system anhand des letzten gesetzten flags,
welchen buffer er nutzen soll.
dieser buffer wir aufgefühlt,
und zur kontrolle über uart rausgeschickt,
bis wieder ein '$'empfangen worden ist.

da ein '$' wieder empfangen wurde... fängt das spielchen von vorne an

für mich ist es logisch und richtig was ich da hingeschrieben habe,
aber wieso funktioniert das nicht?
wieso schafft er es nicht ins nächste bufferfeld zu springen und dort 
seine arbeit zu verrichten? das muss irgendwas mit *pflag zu tun haben, 
aber was?

von Flo (Gast)


Lesenswert?

Flo schrieb:
> if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
     if (USART_ReceiveData(USART1) == '$')
       {
      *pflag++;
        if(*pflag == 4)
          {
            *pflag =0;
          }
        Ucounter = 0;
        //*pflag = 1; <- vergessen auszukommentieren, dennoch keinen 
unterschied
      }

von Flo (Gast)


Lesenswert?

So alter Falter,
mein mehrfach Buffer funktioniert jetzt,
nur komme ich mit den blöden versenden nicht zurecht!

Das ist mein UartInterrupt:
1
void USART1_IRQHandler(void)
2
{
3
int NbrSend =0;
4
unsigned char Val;
5
6
7
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
8
    {        
9
     if (USART_ReceiveData(USART1) == '$')
10
       {
11
12
      flag++;
13
      NbrSend = Ucounter;
14
15
      //data1[NbrSend] = '0';
16
      //data2[NbrSend] = '0';
17
      //data3[NbrSend] = '0';
18
      Ucounter = 0;
19
      
20
21
        if(flag == 6)
22
          {
23
            flag =0;
24
            
25
          }
26
      
27
      
28
      }
29
      
30
      
31
        
32
    if (USART_ReceiveData(USART1) != '$')
33
      {
34
      if(flag == 0)
35
        {
36
           Val = USART_ReceiveData(USART1);
37
           data1[Ucounter++] = Val;
38
           //USART_SendData(USART1, data6[Ucounter -1]);
39
        
40
  
41
          if (i1 == 0)
42
            {
43
              test(data6, NbrSend);
44
              i2 = 0;
45
              i1 = 1;
46
              //USART_SendData(USART1, '1');
47
            } 
48
        }
49
      
50
51
      if (flag == 1)
52
        {
53
          
54
           Val = USART_ReceiveData(USART1);
55
           data2[Ucounter++] = Val;
56
           //USART_SendData(USART1, data1[Ucounter -1]);
57
          //USART_SendData(USART1, '1');
58
          //sendstring_usart(data1);
59
           
60
61
          if (i2 == 0)
62
            {
63
              test(data1, NbrSend);
64
               i3 = 0;
65
               i2 = 1;
66
               //USART_SendData(USART1, '2');
67
            }
68
        }
69
      
70
71
      if (flag == 2)
72
        {
73
            Val = USART_ReceiveData(USART1);
74
            data3[Ucounter++] = Val;
75
            //USART_SendData(USART1, data2[Ucounter -1]);
76
           //USART_SendData(USART1, '1');
77
           //sendstring_usart(data1);
78
79
         
80
            
81
          if (i3 == 0)
82
            {
83
               test(data2, NbrSend);
84
               i4 = 0;
85
               i3 = 1;
86
               //USART_SendData(USART1, '3');
87
            }  
88
          }
89
        
90
91
      if (flag == 3)
92
        {
93
            Val = USART_ReceiveData(USART1);
94
            data4[Ucounter++] = Val;
95
            //USART_SendData(USART1, data3[Ucounter -1]);
96
           //USART_SendData(USART1, '1');
97
           //sendstring_usart(data1);
98
          
99
100
          if (i4 == 0)
101
            {
102
               test(data3, NbrSend);
103
               i5 = 0;
104
               i4 = 1;
105
               //USART_SendData(USART1, '4');
106
            }
107
        }
108
        
109
110
      if (flag == 4)
111
        {
112
            Val = USART_ReceiveData(USART1);
113
            data5[Ucounter++] = Val;
114
            //USART_SendData(USART1, data4[Ucounter -1]);
115
           //USART_SendData(USART1, '1');
116
           //sendstring_usart(data1);
117
         
118
  
119
          if (i5 == 0)
120
            {
121
               test(data4, NbrSend);
122
               i6 = 0;
123
               i5 = 1;
124
               //USART_SendData(USART1, '5');
125
            } 
126
127
        }
128
        
129
      if (flag == 5)
130
        {
131
           Val = USART_ReceiveData(USART1);
132
           data6[Ucounter++] = Val;
133
           //USART_SendData(USART1, data5[Ucounter -1]);
134
          //USART_SendData(USART1, '2');
135
           
136
             
137
          if (i6 == 0)
138
            {
139
             test(data5, NbrSend);
140
             i1 = 0;
141
             i6 = 1;
142
             //USART_SendData(USART1, '6');
143
            }
144
145
 
146
        }
147
      
148
        }
149
   }
150
}


Jetzt hab ich eine Verständnisfrage,
wenn ich in meinem Interrupt eine Funktionaufrufe,
diese fängt an was zu bearbeiten,
und das selbe Interrupt wird wieder angesprochen

wird die ursprünglich angesprochene Funktion weiterbearbeitet,
oder wird wiederholt die Funktion durch das zweite Interrupt gestartet,
und die alte wird abgebrochen?

Ich komme auf diese Frage,
weil
1
void test(char *GPS1, int Anzahl)
2
{
3
int mp;
4
Anzahl += 1;
5
GPS1[Anzahl +1]= '0';
6
7
8
for (mp=0; mp<6; )
9
{
10
USART_SendData(USART1, GPS1[mp++]);
11
}

kommt nur Müll raus, obwohl ich eigentlich
die ersten 7char Zeichen des Arrays erwartet hätte!


Mache ich eine einfache Char sendung
1
void test(char *GPS1, int Anzahl)
2
{
3
4
Anzahl += 1;
5
GPS1[Anzahl +1]= '0';
6
USART_SendData(USART1, GPS1[3]);
7
}

Kommt wie erwartet die 4 Stelle der jeweiligen Strings raus!
TGSSSSLM
für GPV'T'G, GPG'G'A, GPG'S'A, GPG'S'V, GPG'S'V, GPG'S'V, GPG'L'L, 
GPR'M'C...

Ist nun die Funktion zu langsam um 5Char Zeichen zu senden???

Das senden dient erstmal nur zur Kontrolle,
diese Strings sollen noch Teilen abgesucht werden -_-

von Uwe (Gast)


Lesenswert?

Als omit den Interupts macht man das so :
Man versucht so wenig Zeit wie möglich im Handler zu verbringen.
Du solltest im Interupthandler nur EIN EINZELNES Zeichen in einen Puffer 
schreiben und einen der vier Zähler hochzählen und sich um die start und 
Stop bzw. Daten Gültig Bedingung kümmern.
Also z.B. ne Statemachine (auch FSM) im Interupt die immer nur durch 
einen State läuft und dann aus dem Handler zurückspringt.

im Handler der aufgerufen wird wenn EIN Zeichen im RX Register steht 
wird geguckt in welchem State wir uns befinden

die Variable State machst du dir nen eigenen type mit enum oder einfach 
per define der einzelnen States damit Sie im Switch benutzt werden 
können.
und du brauchst noch i, x, und char puffer[2][32] usw.

state=next_state;
switch(state)
{
 case WartenaufDollar:
 if(RX=='$')
  {
  puffer[x][i++]=RX;
  next_state=DatenSammelnbis<LF><CR>Kommt;
  }
  break;
case DatenSammelnbis<LF><CR>Kommt:
  puffer[x][i++]=RX;
  if(RX==0x0A && Puffer[x][i-1]==0x0D)
   {
   if(x==1)
    {
     x=0;
    }
    else
    {
     x=1;
    }
   next_state=WartenaufDollar;
   }
  break;
}

von Flo (Gast)


Lesenswert?

Danke Dir Uwe,

das mit dem Umfang der Anweisungen im Interrupt war mir schon bewußt,
nur als Programmierneuling,
sind mir nicht alle Verfahren so bekannt.

So hänge ich seit Tagen an diesem Problem,
und du zauberst mal kurz was dahin ;)
1
Global:
2
#define Warte 0
3
#define Sammel 1
4
int x=0;
5
int Ucounter
6
char data [][];
7
8
.
9
.
10
.
11
12
void USART1_IRQHandler(void)
13
{
14
15
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
16
{
17
state=next_state;
18
switch(state)
19
{
20
 case Warte:
21
 if(USART_ReceiveData(USART1) =='$')
22
  {
23
  data[x][Ucounter++]=USART_ReceiveData(USART1);
24
  next_state=Sammel;
25
  }
26
  break;
27
case Sammel:
28
  data[x][Ucounter++]=USART_ReceiveData(USART1);
29
  if(USART_ReceiveData(USART1) ==0x0A && data[x][Ucounter-1]==0x0D)
30
   {
31
   if(x==1)
32
    {
33
     x=0;
34
    }
35
    else
36
    {
37
     x=1;
38
    }
39
   next_state=Warte;
40
   }
41
  break;
42
}  
43
}
44
}

so siehts jetzt bei mir aus,
und der compiler hatte auch nichts zu meckern...

jetzt muss ich mich mit übergaben und nutzen von mehrdimensionalen 
arrays beschäftigen...

Danke nochmal

von Flo (Gast)


Lesenswert?

Ich brauche noch ne Hilfe von fähigen Programmierer,
denn ich bekomme trotz langens suchen im Netz nicht weiter raus.

Also ich habe ein zweidimensionales Array,
und da ich nur die "hälfte" brauche,
würde ich gerne das in ein einfaches Array kopieren.

Dannach würde ich das normale Array nehmen und mit strtok
aufteilen. Indem ich nun auf den Teil des Strings zeige was ich brauche,
würde ich es wieder nehmen und in ein richtiges Array kopieren da es 
wieder geteilt wird. Wieder zeige ich auf beide Teile und kopiere sie 
jeweils wieder in ein Array. Nun kann ich die Werte mit Atoi zu Integer 
machen und berechnen.

Bei dem anderen Part sind die Werte immer an selber stelle, deswegen ist 
eine einfache Verschiebung...

Nun habe ich mit meinem jämmerlichen Wissenstand was versucht,
kann bitte mir erklären wie man es besser macht?

Ich habe wirklich keine vernünftigen Beispiele gefunden.
1
void GPSFilter(void)
2
{
3
int o=0;
4
char *pToken;
5
char *pToken2;
6
7
8
if (state == Warte)
9
  {
10
  if (data[x][3] == 'V')
11
  {
12
    strcpy(data1,data[x][]);    // <-  Meckert
13
    *pToken = strtok(data1,",");
14
    if(pToken)
15
      {
16
      o++;
17
      while((pToken=strtok(NULL, ",")))
18
        {  
19
        o++;
20
        }
21
      strcpy(GPSdata, data1[7]);   // <-  Meckert
22
      o=0;
23
      }
24
    pToken2 = strok(GPSdata, GPSdata1);     // <-  Meckert
25
    if (pToken2)
26
      {
27
       o++;
28
       while((pToken2=strtok(NULL, ".")))
29
         {
30
         o++;
31
         }
32
      strcpy(GPSdata1, GPSdata);
33
      strcpy(GPSdata2, GPSdata[1]);       // <-  Meckert
34
      }
35
    }
36
  }
37
  else if(data[x][4]=='G' && data[x][5]=='A')
38
  {
39
    gesuchtstd[0]= data[x][7];
40
    gesuchtstd[1]= data[x][8];
41
    gesuchtmin[0]= data[x][9];
42
    gesuchtmin[1]= data[x][10];
43
    gesuchts[0]= data[x][11];
44
    gesuchts[1]= data[x][12];
45
    gesuchtms[0]= data[x][14];
46
    gesuchtms[1]= data[x][15];
47
    gesuchtms[2]= data[x][16];  
48
  
49
    v = atoi(gesucht1);
50
    n = atoi(gesucht2);
51
    std = atoi(gesuchtstd);
52
    min = atoi(gesuchtmin);
53
    s = atoi(gesuchts);
54
    ms = atoi(gesuchtms);
55
  }  
56
   
57
  
58
59
60
   
61
  *GPSGeschwGerade = (( v *(10 *(360)/1000)) + n);
62
  *GPSZeitNeu = ((std * 360 + min * 60 + s) * 1000 + ms);
63
  *GPSZeit =  (*GPSZeitNeu)-(*GPSZeitAlt);  
64
  *GPSZeitAlt = *GPSZeitNeu;
65
  *GPSStrGerade = (*GPSGeschwGerade) * (*GPSZeit);  
66
  GPS_Kurve();
67
}

von Flo (Gast)


Lesenswert?

so das problem steht immernoch,
und ich wäre zumindest für hinweise sehr dankbar.
auch links zur möglichen lösung wären
eine bereicherung

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.