Forum: Compiler & IDEs reines C Problem und Denkblockade


von Bernd (Gast)


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.

von holger (Gast)


Lesenswert?

index = (Reihe-1) * 8 + (Spalte - 1);

von Johannes M. (johnny-m)


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...

von holger (Gast)


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;

von holger (Gast)


Lesenswert?

>(weshalb auch das dicke "BIT:" oben links

Ohh, das hatte ich nicht gesehen :(

von Bernd (Gast)


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.

von holger (Gast)


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.

von Bernd (Gast)


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.

von holger (Gast)


Lesenswert?

Im Spaltenbyte ist immer nur ein Bit gesetzt ?

von yalu (Gast)


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?

von Gast (Gast)


Lesenswert?

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

von Bernd (Gast)


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.

von Bernd (Gast)


Lesenswert?

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

So ist es.

von Bernd (Gast)


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.

von holger (Gast)


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;
  }

von yalu (Gast)


Lesenswert?

Oder vielleicht so?
1
void decode(void) {
2
  unsigned char reihenbyte, spaltenbyte, basis, treffer;
3
  int i;
4
5
  reihenbyte = readByte(); // 1 Byte von Schnittstelle lesen
6
  basis = 57;
7
  for(i=0; i<8; i++) {
8
    if(reihenbyte & 0x80) {  // oberstes Bit gesetzt?
9
      spaltenbyte = readByte();
10
      treffer = basis;
11
      while(spaltenbyte >>= 1)
12
        treffer++;
13
      // Ausgabe (oder speichern)
14
      printf("%d\n", treffer);
15
    }
16
    basis -= 8;
17
    reihenbyte <<= 1;
18
  }
19
}

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?

von Bernd (Gast)


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.

von holger (Gast)


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 ;)

von Peter D. (peda)


Lesenswert?

1
unsigned char z( unsigned char x, unsigned char y )
2
{
3
  if( x == 1 ){
4
    if( y == 1 )
5
      return 1;
6
    return 8 + z( 1, y >> 1 );
7
  }
8
  if( y == 1 )
9
    return 1 + z( x >> 1, 1 );
10
  return 9 + z( x >> 1, y >> 1 );
11
}


Peter

von holger (Gast)


Lesenswert?

@ Peter

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

von yalu (Gast)


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 :-)

von holger (Gast)


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 !

von yalu (Gast)


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.

von Bernd (Gast)


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/brochures/mvs8000.pdf

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.