www.mikrocontroller.net

Forum: Compiler & IDEs reines C Problem und Denkblockade


Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hat jetzt nicht unbedingt mit dem GCC zu tun aber hier sind doch 
einige C Gurus unterwegs und ich versuche es mal hier.

Ich habe eine Denkblokade und ich hoffe das ihr eine Idee hierzu habt.

Ich empfange über die UART ein, sagen wir mal Reihenbyte und ein 
Spaltenbyte. Wenn ich z.B. den Wert 0x01 für Reihe und Spalte Empfange 
dann repräsentiert das den Wert 0x01. Also, einfach eine gedachte 
Verbindungslinie und der Treffer liegt auf 0x01.

Wenn es z.B. Reihe 0x02 und Spalte 0x02 ist dann ist der Treffer auf 10, 
oder Reihe 0x02 und Spalte 0x01 dann ist der Treffer 9.

               SpaltenByte
BIT:       7  6  5  4  3  2  1  0
          _____________________
      7|  64 63 62 61 60 59 58 57
      6|  56 55 54 53 52 51 50 49
      5|  48 47 46 45 44 43 42 41
      4|  40 39 38 37 36 35 34 33
Reihe 3|  32 31 30 29 28 27 26 25
      2|  24 23 22 21 20 19 18 17
      1|  16 15 14 13 12 11 10  9
      0|   8  7  6  5  4  3  2  1

Ich hoffe ich habe mich verständlich ausgedrückt. Ich suche nun nach 
einer einfachen Formulierung in C bei der ich an die Funktion Reihen und 
Spaltenbyte übergebe und den "Treffer" als Rückgabewert erhalte.

Ich knobel schon ne ganze Weile und komm nicht drauf. Hoffe ihr habt ne 
Idee.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
index = (Reihe-1) * 8 + (Spalte - 1);

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:
> index = (Reihe-1) * 8 + (Spalte - 1);
Das wäre wohl ein bisschen zu trivial...

So, wie ich das verstanden habe, ist in Zeilen-Byte und Spalten-Byte 
jeweils nur 1 Bit gesetzt (weshalb auch das dicke "BIT:" oben links 
steht). Dementsprechend hätte Zeilen-Byte z.B. den Wert 64 (2^6), wenn 
Zeile 6 angesprochen werden soll. Das macht es etwas komplizierter...

Abgesehen von einer switch-case-Abfrage fällt mir momentan auch nicht 
die Lösung ein...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>index = (Reihe-1) * 8 + (Spalte - 1);

Quatsch ;)

Natürlich so weil deine Tabelle nicht bei 0 beginnt:
index = (Reihe-1) * 8 + (Spalte - 1) + 1;

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>(weshalb auch das dicke "BIT:" oben links

Ohh, das hatte ich nicht gesehen :(

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> So, wie ich das verstanden habe, ist in Zeilen-Byte und Spalten-Byte
>> jeweils nur 1 Bit gesetzt

Ja, so in etwa. Das Protokoll sieht vor das dass Zeilen (Reihenbyte) 
jeden Wert annehmen kann (0-255), aber das Spaltenbyte wird, sobald eben 
in Reihe mehr als ein BIT gesetzt wird, explizit für jede 
Stellenwertigkeit eindeutig gesendet. Somit stimmt die Aussage von 
Johannes.

Anders formuliert, hat das ReihenByte den Wert 00000101B dann empfange 
ich auch 2 Spaltenbytes in der Reihenfolge der Wertigkeit.

Holger, deinen Ansatz verstehe ich nicht so ganz.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Anders formuliert, hat das ReihenByte den Wert 00000101B dann empfange
>ich auch 2 Spaltenbytes in der Reihenfolge der Wertigkeit.

Das sollte doch mit Bitmasken irgendwie zu machen sein.

>Holger, deinen Ansatz verstehe ich nicht so ganz.

Siehe 2 Posts weiter oben.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Das sollte doch mit Bitmasken irgendwie zu machen sein.

Naja, ich knobel, wie gesagt, schon ne ganze Weile. Das Protokoll hat 
sich sicherlich jemand ausgedacht um auf der Empfängerseite mit einem 
cleveren Algorithmus nicht allzu viel Arbeit zu haben. Allerdings gebe 
ich zu, ich komme nicht dahinter.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Spaltenbyte ist immer nur ein Bit gesetzt ?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das Protokoll sieht vor das dass Zeilen (Reihenbyte) jeden Wert
> annehmen kann (0-255), aber das Spaltenbyte wird, sobald eben in
> Reihe mehr als ein BIT gesetzt wird, explizit für jede
> Stellenwertigkeit eindeutig gesendet.

Und im Spaltenbyte ist immer genau 1 Bit gesetzt?

Wie liegen die Spaltenbytes vor? In einem Array von maximal 8 Werten?
Oder ruft man jedesmal eine Funktion auf, um das nächste Byte zu
lesen?

> Anders formuliert, hat das ReihenByte den Wert 00000101B dann
> empfange ich auch 2 Spaltenbytes in der Reihenfolge der Wertigkeit.

Was bedeutet "Reihenfolge der Wertigkeit"? Erst das Spaltenbyte, dass
zu Bit 2 des Reihenbytes gehört und dann das Spaltenbyte zu Bit 0?
Oder genau umgekehrt?

Das Ergebnis besteht, wenn ich das richtig verstanden habe, aus so
vielen Zahlenwerten wie Bits im Reihenbyte gesetzt sind. Richtig?
Wenn ja, wie sollen diese Ergebniswerte ausgegeben werden? In einem
Array? Oder soll für jeden Ergebniswert eine Funktion aufgerufen
werden, die den Wert weiterverarbeitet?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muss bei S=0x08 und R=0x04 als Ergebnis 20 herauskommen? Habe ich da die 
Aufgabe richtig verstanden?

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Im Spaltenbyte ist immer nur ein Bit gesetzt ?

Ja, so ist es.

>> Was bedeutet "Reihenfolge der Wertigkeit"? Erst das Spaltenbyte, dass
>> zu Bit 2 des Reihenbytes gehört und dann das Spaltenbyte zu Bit 0?

Ja, auch das stimmt.

>> Das Ergebnis besteht, wenn ich das richtig verstanden habe, aus so
>> vielen Zahlenwerten wie Bits im Reihenbyte gesetzt sind. Richtig?

Ja, auch das ist korrekt.

>> Wenn ja, wie sollen diese Ergebniswerte ausgegeben werden?

Naja, im Prinzip kann das Ergebnis in einem Array liegen oder aber, man 
kann ja mit immer dem gleichen ReihenByte und dem entsprechenden 
SpaltenByte (hier ja nur 1 BIT gesetzt), den "Treffer" ermitteln und als 
char zurückgeben.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> muss bei S=0x08 und R=0x04 als Ergebnis 20 herauskommen? Habe ich da die
>> Aufgabe richtig verstanden?

So ist es.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Wie liegen die Spaltenbytes vor? In einem Array von maximal 8 Werten?
>> Oder ruft man jedesmal eine Funktion auf, um das nächste Byte zu
>> lesen?

So, den hatte ich noch übersehen. Ja, das kann ich so machen.

Die Gesamte Information bekomme ich per Request vom Device zurück. Die 
Anzahl der Bytes die ich empfange ist natürlich abhängig von den Werten 
in der Matrix.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte klappen, oder auch nicht ;)

 unsigned char mask_reihe, mask_spalte,i,j;

 mask_spalte = 0x01;

 for(j=0; j<8; j++)
  {
   if(Spalte & mask_spalte) break;
   mask_spalte <<= 1;
  }

 mask_reihe = 0x80;

 for(i=0; i<8; i++)
  {
   if(Reihe & mask_reihe)
    {
     Wert = (7-i) * 8 + j + 1;
     //Wert speichern oder ausgeben
    }

   mask_reihe >>= 1;
  }

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder vielleicht so?
void decode(void) {
  unsigned char reihenbyte, spaltenbyte, basis, treffer;
  int i;

  reihenbyte = readByte(); // 1 Byte von Schnittstelle lesen
  basis = 57;
  for(i=0; i<8; i++) {
    if(reihenbyte & 0x80) {  // oberstes Bit gesetzt?
      spaltenbyte = readByte();
      treffer = basis;
      while(spaltenbyte >>= 1)
        treffer++;
      // Ausgabe (oder speichern)
      printf("%d\n", treffer);
    }
    basis -= 8;
    reihenbyte <<= 1;
  }
}

Liefert die Schnittstelle bspw. nacheinander die Bytes

    0x85 0x80 0x04 0x10,

gibt die Funktion die Werte
    64
    19
     5
aus.

War das so gewünscht?

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> gibt die Funktion die Werte
>>    64
>>    19
>>     5
>> aus.

Ja, sieht gut aus.

Holger, yalu, ich werde es ausprobieren und melde mich dann zurück.

Vielen Dank das ihr so hilfsbereit mitmacht. Ich werde es auf der 
Zielhardware testen und melde mich morgen.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ yalu

>> gibt die Funktion die Werte
>>    64
>>    19
>>     5

Bei einem Spaltenbyte von 0x80 können nur
folgende Werte rauskommen:

64
56
48
40
32
24
16
8

Also 19 und 5 sind falsch.

Dein Beispiel müsste 4 Werte liefern !
Happy Bughunting ;)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unsigned char z( unsigned char x, unsigned char y )
{
  if( x == 1 ){
    if( y == 1 )
      return 1;
    return 8 + z( 1, y >> 1 );
  }
  if( y == 1 )
    return 1 + z( x >> 1, 1 );
  return 9 + z( x >> 1, y >> 1 );
}


Peter

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Peter

Rekursiver Algorithmus.
Naja, warum einfach wenn es auch kompliziert geht ;)

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger schrieb:

> Bei einem Spaltenbyte von 0x80 können nur
> folgende Werte rauskommen:
>
> 64
> ...

Ja. Das erste Spaltenbyte ist 0x80 und das zugehörige Ergebnis 64.

> Also 19 und 5 sind falsch.

Nein. 19 und 5 sind die Ergebnisse für das zweite bzw. das dritte
Spaltenbyte, also 0x04 und 0x10.

> Dein Beispiel müsste 4 Werte liefern !

Nein. Die Eingabe besteht aus einem Reihenbyte mit drei gesetzten
Bits und drei Spaltenbytes, also werden drei Ergebnisse geliefert.

So habe ich jedenfalls Bernds Aufgabenstellung verstanden. Da Bernd
mit

> Ja, sieht gut aus.

geantwortet hat, glaube ich, dass ich mit meiner Interpretation
zumindest nicht komplett daneben liege. Aber sicher bin ich mir
natürlich keinesfalls, da Bernd - wie so viele hier im Forum - mit
seinen Informationen nur tröpfchenweise rausrückt. Morgen werden wir
sicher mehr erfahren.


@Peter:

Dein Code sieht sehr elegant aus und grenzt schon an esoterische
Programmierung. Ich habe nachgezählt, er enthält gerade einmal

- 3 verschiedene Operatoren (==, + und >>),
- 2 verschiedene Schlüsselwörter (if und return) und
- 1 verschiedene numerische Konstanten (1)

Ach nee, bei den Konstanten hapert's noch. Die hässliche 8 und die 9
müssen noch irgendwie eliminiert werden. Aber bitte nicht einfach
durch 1+1+1+1+1+1+1+1[+1] ersetzen, da gibt es sicher etwas intelli-
genteres ;-)

Wenn du es dann noch schaffst, die rekursiven Aufrufe als Endrekur-
sionen zu formulieren (dann wandelt sie der Compiler in eine Schleife
um), ist das sicher ein heißer Kandidat für die Verewigung in Bernds
PIC. Bis morgen hast du noch Zeit :-)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nein. 19 und 5 sind die Ergebnisse für das zweite bzw. das dritte
>Spaltenbyte, also 0x04 und 0x10.

Das ist ja noch eine offene Frage !
Wird für jedes gesetze Bit der Reihe auch ein Spaltenbyte
gesendet ? Dann hast du recht !

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wird für jedes gesetze Bit der Reihe auch ein Spaltenbyte gesendet ?

Das habe ich aus Bernds folgender Aussage geschlossen:

> Anders formuliert, hat das ReihenByte den Wert 00000101B dann
> empfange ich auch 2 Spaltenbytes in der Reihenfolge der Wertigkeit.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> da Bernd - wie so viele hier im Forum - mit seinen Informationen nur
>> tröpfchenweise rausrückt...

Sorry das ich diesen Eindruck erwecke, es liegt aber daran das ich das 
Protokoll erst selber verstehen muß. Wie dem auch sei, yalu, dein Code 
ist voll funktionsfähig und manchmal wundere ich mich warum ich an 
solchen Stellen hänge. Also vielen Dank für deine Hilfe, es 
funktioniert.

>> Wird für jedes gesetze Bit der Reihe auch ein Spaltenbyte gesendet ?

So ist es, ja, manchmal ist es nicht einfach einen Sachverhalt 
vernünftig zu beschreiben (mein Fehler). Dein Code funktioniert nicht, 
dennoch vielen Dank für deine Hilfe.

@ Peter, dein Code werde ich morgen testen aber darauf wäre ich nie 
gekommen. Immer wieder schön was man in C so fromulieren kann ;-)) aber 
den muß ich erst mal verstehen und verdauen. Auch hier ein Danke dafür.

Das Ganze ist ein ziemlich schräges Protokoll aus einem japanischen 
Gehirn. Ich denke ich werde noch ein paar "Nüsse" knacken müssen.

http://bssc.sel.sony.com/Professional/docs/brochur...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.