Forum: Mikrocontroller und Digitale Elektronik If Schleife um Array Elemente zu vergleichen


von smerti (Gast)


Lesenswert?

Servus Leute,

und zwar möchte ich mit einer Laufvariable den aktuellen Wert eines 
Arrays mit dem nächsten vergleichen. Bei den Werten handelt es sich um 
einen binären Code. Mit einer If-Schleife vergleiche ich erfolgreich die 
Werte bis zum Ende des Arrays. Am Ende angekommen möchte ich aber den 
letzten Wert mit dem ersten Wert des Arrays vergleichen. Wie kann ich 
dafür meine Bedingung anpassen?
1
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
2
{
3
  if(code[i] == code[i+1])
4
  {
5
    GPIOA->ODR ^= (1<<8);
6
  }
7
  else
8
  {
9
    GPIOA->BSRR = (0<<24);
10
  }
11
  i++;
12
    
13
  if(i == 9)
14
  {
15
    i=0;
16
  }    
17
}
Mein Binärcode besteht aus 10 Werten. Sobald ich einmal durchgelaufen 
bin wird Wert [9] aber nicht mit Wert [0] verglichen sondern [0] mit 
[1]. Hat jemand einen Goldenen Tipp?

von Cyblord -. (cyblord)


Lesenswert?

smerti schrieb:
> If-Schleife

Och nö, echt?

von Frank S. (_frank_s_)


Lesenswert?

Baue das besser mit einer WHILE-Verzweigung.

von interessant (Gast)


Lesenswert?

Cyblord -. schrieb:
>> If-Schleife
>
> Och nö, echt?

das es eine Schleife ist die durch einen Interrupt getriggert wird, 
könnte man hier tatsächlich von einer if- schleife sprechen ;) (sorry 
und das wo nicht mal freitag ist)

von Dirk B. (dirkb2)


Lesenswert?

smerti schrieb:
> If-Schleife

Da schleift nix.

Je nach verwendetem Prozessor kannst du (i+1)%max oder (wenn max eine 
Zweier-Potenz ist) (i+1)&(max-1) machen.

Du kannst auch ein j einführen:
j = i+1;
j = (j>=max) ? 0: j

einbauen.

von Bastler (Gast)


Lesenswert?

Funktions-Konstruktor geht auch.

von Cyblord -. (cyblord)


Lesenswert?

interessant schrieb:

> das es eine Schleife ist die durch einen Interrupt getriggert wird,
> könnte man hier tatsächlich von einer if- schleife sprechen ;) (sorry
> und das wo nicht mal freitag ist)

Kann man nicht, sonst wäre jede If-Anweisung innerhalb einer Schleife 
eine If-Schleife. Und dem ist nicht so.

von smerti (Gast)


Lesenswert?

Cyblord -. schrieb:
> Kann man nicht, sonst wäre jede If-Anweisung innerhalb einer Schleife
> eine If-Schleife. Und dem ist nicht so.

Juckt mich absolut nicht, das muss dich ja ganz tief im Mark kratzen.
....If-Schleife....

von Cyblord -. (cyblord)


Lesenswert?

smerti schrieb:
> Juckt mich absolut nicht

Das ist ok für mich. DU hast ja Probleme bei den popeligsten 
Programmierproblemen und nicht ich.

von Stefan F. (Gast)


Lesenswert?

Dirk B. schrieb:
> Du kannst auch ein j einführen

Zum Beispiel so:
1
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
2
{
3
  // Calculate index of the next element
4
  int j=i+1;
5
  if(j == 9)
6
  {
7
    j=0;
8
  }
9
10
  if(code[i] == code[j])
11
  {
12
    GPIOA->ODR ^= (1<<8);
13
  }
14
  else
15
  {
16
    GPIOA->BSRR = (0<<24);
17
  }
18
19
  // prepare for next call.
20
  i=j;
21
}

von smerti (Gast)


Lesenswert?

Cyblord -. schrieb:
> DU hast ja Probleme bei den popeligsten
> Programmierproblemen und nicht ich.

Bist du der coolste hier im Forum?

von leo (Gast)


Lesenswert?

smerti schrieb:
> GPIOA->BSRR = (0<<24);

Und das ist falsch.

leo

von arbeitsloserArbeitsloser (Gast)


Lesenswert?

Cyblord ist der Forenclown.

von smerti (Gast)


Lesenswert?

leo schrieb:
> Und das ist falsch.

Wie kommst du da drauf? Funktioniert nämlich

von A. S. (Gast)


Lesenswert?

2 variablen, i und j, beide starten mit 0

i=j;
if(++j>9) j=0;
....

von McMix (Gast)


Lesenswert?

Versuchs doch mal mit Modulo 10.
also:
   if(code[i] == code[(i+1)%10])
und dann noch die Zeile
   if(i == 9)
in :
   if(i > 9)
ändern, damit er auch bis zum Index 9 geht, dann sollte es 
funktionieren.

von DPA (Gast)


Lesenswert?

Da gabs doch einen Link für: http://if-schleife.de/

Aber irgendwann mach ich mal ne eigene Sprache, in der "loop if(){}", 
"loop {}" und "loop {} if()" erlaubt sind, und es kein for/while gibt.

von Dirk B. (dirkb2)


Lesenswert?

smerti schrieb:
> (0<<24);

was ergibt denn der Ausdruck?

von Bastler (Gast)


Lesenswert?

Dirk B. schrieb:
> was ergibt denn der Ausdruck?

Eine ziemlich mächtige Null. Ganz feste Null eben.

von Mark B. (markbrandis)


Lesenswert?

smerti schrieb:
> Mein Binärcode besteht aus 10 Werten. Sobald ich einmal durchgelaufen
> bin wird Wert [9] aber nicht mit Wert [0] verglichen sondern [0] mit
> [1].

Das kann man mit dem Modulo Operator erreichen. Ein Code-Beispiel für 
die Ausgabe am Konsolenfenster wäre etwa das hier:
1
#include <stdio.h>
2
3
int main()
4
{
5
    unsigned int i;
6
    
7
    for (i=0; i<10; i++)
8
    {
9
        printf("%2d | %2d\n", i%10, (i+1)%10);
10
    }
11
    
12
    return 0;
13
}

Ausgabe:
1
 0 |  1
2
 1 |  2
3
 2 |  3
4
 3 |  4
5
 4 |  5
6
 5 |  6
7
 6 |  7
8
 7 |  8
9
 8 |  9
10
 9 |  0

von DPA (Gast)


Lesenswert?

Dirk B. schrieb:
> smerti schrieb:
>> (0<<24);
>
> was ergibt denn der Ausdruck?

Das selbe, wie das Symbol, das Entsteht, wenn man "0.5 < x^2+y^2/3 < 1" 
plottet: 
https://www.wolframalpha.com/input/?i=0.5+%3C+x%5E2%2By%5E2%2F3+%3C+1

von Cyblord -. (cyblord)


Lesenswert?

Bastler schrieb:
> Dirk B. schrieb:
>> was ergibt denn der Ausdruck?
>
> Eine ziemlich mächtige Null. Ganz feste Null eben.

In der Informatik sagt man ja: Ganz viel null ist fast so viel wie ein 
bisschen eins.

von Rolf M. (rmagnus)


Lesenswert?

Dirk B. schrieb:
> Du kannst auch ein j einführen:
> j = i+1;
> j = (j>=max) ? 0: j

Da von 0 bis 9 gezählt wird:
1
j = (i < 9) ? i+1 : 0;
Und am Ende kann man dann einfach ein
1
i = j;
machen, um weiter zu zählen.

smerti schrieb:
> leo schrieb:
>> Und das ist falsch.
>
> Wie kommst du da drauf? Funktioniert nämlich

Ob falsch oder nicht - es ist jedenfalls recht unsinnig, 0 um 24 Bit 
nach links zu schieben. Das Ergebnis bleibt dabei 0.
Dein
1
GPIOA->BSRR = (0<<24);
ist also genau das gleiche wie
1
GPIOA->BSRR = 0;

: Bearbeitet durch User
von leo (Gast)


Lesenswert?

smerti schrieb:
> Wie kommst du da drauf? Funktioniert nämlich

Ja, aus ganz anderen Gruenden.
Du toggelst ODR mit dem xor-Befehl davor und nicht mit diesem NOP. Lies 
das Handbuch, lerne C.

leo

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Cyblord -. schrieb:
> Ganz viel null ist fast so viel wie ein bisschen eins.

und wenn man es durch 2 teilt, wirds negativ!

von A. S. (Gast)


Lesenswert?

Rolf M. schrieb:
> ist also genau das gleiche wieGPIOA->BSRR = 0;

ja, aber die Logik ist vermutlich eine andere: Da BSRR 24 Bit ist, 
möchte er sicher sein, dass auch wirklich alle 24 Bit 0 sind, und nicht 
nur das Ergebnis ;-)

von smerti (Gast)


Lesenswert?

leo schrieb:
> Du toggelst ODR mit dem xor-Befehl davor und nicht mit diesem NOP. Lies
> das Handbuch, lerne C.

Woher willst du denn wissen das ich das Bit mit diesem NOP Befehl 
Toggeln will? Soll nämlich schon ein NOP sein.

von Stefan F. (Gast)


Lesenswert?

smerti schrieb:
> Woher willst du denn wissen das ich das Bit mit diesem NOP Befehl
> Toggeln will? Soll nämlich schon ein NOP sein.

Optimiert der Compiler das nicht komplett weg, weil der Befehl 
letztendlich nichts* bewirkt?

*) Ausser Zeit zu verbrauchen, aber das genau das will der Compiler ja 
auch minimieren.

von smerti (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Optimiert der Compiler das nicht komplett weg, weil der Befehl
> letztendlich nichts* bewirkt?
>
> *) Ausser Zeit zu verbrauchen, aber das genau das will der Compiler ja
> auch minimieren.

Funktioniert auch ohne, hatte die Operation tatsächlich drin um Zeit zu 
verbrauchen damit die Ausgangsfrequenz stimmt.

von Rolf M. (rmagnus)


Lesenswert?

smerti schrieb:
> Soll nämlich schon ein NOP sein.

Das ist allerdings eine recht kreative Art, ein NOP zu schreiben. Wer 
den Code liest, wird sich zuerst fragen, warum da eine 0 geschoben wird, 
und dann, warum ausgerechnet um 24 Bit.

Stefan ⛄ F. schrieb:
> Optimiert der Compiler das nicht komplett weg, weil der Befehl
> letztendlich nichts* bewirkt?

Die Schiebe-Operation wird mit Sicherheit wegoptimiert. Da wird einfach 
nur 0 in das Register geschrieben. Der Schreibzugriff selbst wird aber 
wohl eher nicht wegoptimiert.

von MaWin (Gast)


Lesenswert?

A. S. schrieb:
> aber die Logik ist vermutlich eine andere: Da BSRR 24 Bit ist,
> möchte er sicher sein, dass auch wirklich alle 24 Bit 0 sind, und nicht
> nur das Ergebnis ;-)

Möglicherweise wollte er auch Bit 25 (Zählweise Bit 1 ist das 
niederwertigste) löschen und die anderen beibehalten wie sie waren, was 
er mit der Anweisung natürlich verkackt.

von smerti (Gast)


Angehängte Dateien:

Lesenswert?

Rolf M. schrieb:
> warum ausgerechnet um 24 Bit

Weil es das korrespondierende Bit für mein ODR Bit ist und mit einer 0 
einfach keine Operation durchgeführt wird. Das habe ich in dem moment so 
gefunden und benötigt. Aber gut anscheinend für die Katz

von Dirk B. (dirkb2)


Lesenswert?

smerti schrieb:
> Weil es das korrespondierende Bit für mein ODR Bit ist und mit einer 0
> einfach keine Operation durchgeführt wird.

Du setzt aber auch alle anderen 31 Bit auf 0.

von A. S. (Gast)


Lesenswert?

smerti schrieb:
> und mit einer 0 einfach keine Operation durchgeführt wird.

Was meinst immer Du damit meinst, ist vermutlich ein Missverständnis der 
und sollte (für Dich) aufgeklärt werden. Irgendwann kommt der Zeitpunkt 
als Anfänger, wo man programmierzeilen nicht probieren sondern 
formulieren und nachvollziehen sollte.

Alles probierte haut der Compiler dir beim optimieren (nur ein 
Federstrich) um die Ohren.

Überlege, was Du wolltest und was Du programmiert hast. Und wenn es was 
anderes tat als erwartet, dann lies, frag oder forsche nach.

von leo (Gast)


Lesenswert?

A. S. schrieb:
> Da BSRR 24 Bit ist

Nein, das ist ein 32bit-Register und 0 hineinschreiben bewirkt genau 
nichts.

leo

von Wolfgang (Gast)


Lesenswert?

smerti schrieb:
> Hat jemand einen Goldenen Tipp?
Falls du noch Speicherplatz für ein einziges weiteres Array-Element 
erübrigen kannst, könntest du vor der Vergleichsorgie den ersten Wert 
noch einmal ganz nach hinten kopieren. Dann löst sich dein Problem quasi 
in Luft auf.

von A. S. (Gast)


Lesenswert?

Wolfgang schrieb:
> Falls du noch Speicherplatz für ein einziges weiteres Array-Element
> erübrigen kannst, könntest du vor der Vergleichsorgie den ersten Wert
> noch einmal ganz nach hinten kopieren. Dann löst sich dein Problem quasi
> in Luft auf.

Das ist oft der Pragmatische Ansatz, der das alles viel einfacher und 
lesbarer macht.

Ist halt nur selten, dass man die Daten(Strukturen) an der Stelle "in 
der Hand" hat.

von Stefan F. (Gast)


Lesenswert?

A. S. schrieb:
> Das ist oft der Pragmatische Ansatz, der das alles viel einfacher und
> lesbarer macht.

Das sehe ich anders. Denn dazu musst du zwischen dem letzten und 
vorherigen Elementen unterscheiden.

Dennoch musst du trotzdem mindestens eine Index variable bei jedem 
Durchlauf erhören und am Ende auf 0 zurück setzen.

von A. S. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das sehe ich anders. Denn dazu musst du zwischen dem letzten und
> vorherigen Elementen unterscheiden.
>
> Dennoch musst du trotzdem mindestens eine Index variable bei jedem
> Durchlauf erhören und am Ende auf 0 zurück setzen.

Äh, wieso?

Wenn Du das Element0 nochmal hinter das letzte Element setzt, dann läuft 
Deine Schleife ohne Verrenkung bis zum Ende und ist fertig.
extern Code
1
extern int code[10+1];
2
3
   code[10]=code[0];
4
5
   for(int i=0; i<10; i++) {foo(code[i], code[i+1]);}

kein Modulo, keine if, kein zweiter index, ...

von Wolfgang (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Dennoch musst du trotzdem mindestens eine Index variable bei jedem
> Durchlauf erhören und am Ende auf 0 zurück setzen.

Falscher Ansatz.
Du setzt beim Start die Indexvariable i auf des kopierte Element.
In der Schleife vergleichst immer y[i] mit y[i-1] und dekrementierst i.
Wenn i==0, hast du fertig.

von Stefan F. (Gast)


Lesenswert?

A. S. schrieb:
> dann läuft Deine Schleife ohne Verrenkung bis zum Ende und ist fertig.

Bei jedem Interrupt soll nach nächste Element aus dem Array verarbeitet 
werden. Wenn das letzte Element erreicht wurde, beginnt die Verarbeitung 
wieder von vorne.  Also braucht man immer noch einen entsprechenden 
Test, bei dessen Erfüllung i auf 0 gesetzt wird.

von zitter_ned_aso (Gast)


Lesenswert?

smerti schrieb:
> if(code[i] == code[i+1])

smerti schrieb:
> Mein Binärcode besteht aus 10 Werten. Sobald ich einmal durchgelaufen
> bin wird Wert [9] aber nicht mit Wert [0] verglichen sondern [0] mit
> [1].

Bei der Bedingung ist der letzte Vergleich gar nicht nötig. (wenn i von 
1 bis 10 läuft)

Wenn benachbarte Elemente gleich sind, dann sind auch das letze und das 
erste Element gleich.

a==b und b==c  ---> a==c

Bist du dir sicher, dass du es so vergleichen willst?

von Rolf M. (rmagnus)


Lesenswert?

zitter_ned_aso schrieb:
> Wenn benachbarte Elemente gleich sind, dann sind auch das letze und das
> erste Element gleich.
>
> a==b und b==c  ---> a==c
>
> Bist du dir sicher, dass du es so vergleichen willst?

Wenn genau zwei Elemente gleich sind, bedeutet das nicht automatisch, 
dass alle Elemente gleich sind. Bei jedem Aufruf der Funktion werden ja 
nur zwei Elemente miteinander verglichen, nicht mehr. Was zwischen den 
Aufrufen damit passiert, weiß man nicht.

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.