Forum: Mikrocontroller und Digitale Elektronik ATmega8 Probleme mit Vergleichen


von Artur H. (hohoho)


Angehängte Dateien:

Lesenswert?

Hallo,

ich baue mir zur Zeit einen Midi-Controller auf basis eines ATmega8.
Es funktioniert soweit, dass er die neuen Werte von mehreren AD-Wandlern 
sammelt und auch ohne Probleme ausgibt.

Nun möchte ich die Funktionalität einbauen, dass er nur bei einer 
Änderung eine neue Midi-Nachricht schickt, habe aber genau da Probleme 
mit einem Vergleich.

Nach dem Midi-Protokoll hat jeder Regler eine CC-Nummer und einen Wert, 
jeweils 7 Bit ( daher auch nur bis 128 ).
1
uint8_t buffer[128];
2
3
void update_changes(uint8_t cc, uint8_t val)
4
{
5
  //if(val != buffer[cc])
6
  {
7
    midi_send_cc(cc, val);
8
    midi_send_cc(cc, buffer[cc]);
9
    midi_send_cc(cc, val != buffer[cc]);
10
    buffer[cc] = val;
11
  }
12
}
Zum debuggen hab ich die if-Abfrage auskommentiert ( ist immer false, 
egal wie val und buffer[cc] aussehen ), und die Ergebnisse sieht man im 
Anhang ( bei den ersten paar ist die logische 0 ja richtig, aber beim 
letzten müsste da eine 1 stehen ).

Ich hab nur mal die main.c angehängt, denn spi und midi senden 
funktioneren an sich einwandfrei.

Woran könnte es liegen, dass bei dem Vergleich immer false rauskommt, 
egal ob val und buffer[cc] gleich sind oder nicht ?

Gruß,
Artur

von master.andre (Gast)


Lesenswert?

Hi,
kein Mensch kann wissen was in deinem Buffer steht. Du bist dir schon im 
klaren darüber das du den Bufferinhalt an der Position CC mit Val 
vergleichst (bezogen auf deinen Anhang)?!

Gruß Andre

von Artur H. (hohoho)


Lesenswert?

Ja, dessen bin ich mir bewusst, das soll auch so sein, aber das kommt ja 
erst nach dem Vergleich, vorher sind die Werte durchaus unterschiedlich.

von master.andre (Gast)


Lesenswert?

Hi,
das Bild im Anhang hat keinen Informationsgehalt, also hättest du es ja 
weglassen können. Was für einen Datentyp gibt den die Funktion 
spi_transmit zurück ?

von Artur H. (hohoho)


Lesenswert?

Ein uint8_t, hab 4 Eingangs-Schieberegister 74HC165 hintereinander 
geschaltet, die Werte von den 4 AD-Wandlern zurückliefern ( was auch 
einwandfrei funktioniert ).

Das Bild zeigt zu jedem CC 3 Werte: einmal den der Variable val, einmal 
den vom Buffer an der stelle und dann den logischen Wert vom Vergleich 
val != buffer, bei den ersten 3 sieht man, dass val und buffer 
übereinstimmen, der Vergleich also stimmt. Beim letzten ist der val 0x28 
und der buffer 0x3B, für den ATmega gilt jedoch 0x28 == 0x3B ist true, 
warum auch immer :(

von Stefan B. (Gast)


Lesenswert?

Du solltest die AVR-GCC Versionsnummer angeben und den erzeugten 
Assemblercode.

von master.andre (Gast)


Lesenswert?

Hi,
sorry das hab ich im ersten Moment nicht geblickt. Ich würde vermuten 
das die Funktion midi_send_cc deine Variablen verändert. Das würdest du 
nicht mitbekommen wenn du dir die Variablen nicht merkst.

Probier mal folgendes :

void update_changes(uint8_t cc, uint8_t val)
{
  uint8_t valbuf = val;
  uint8_t ccbuf = buffer[cc];

  midi_send_cc(cc, val);
  midi_send_cc(cc, buffer[cc]);
  midi_send_cc(cc, valbuf != ccbuf);
  buffer[cc] = val;

}

von Artur H. (hohoho)


Lesenswert?

@Stefan: GCC 4.3.2,

hier ist der Assembler Code ( ich gehe doch recht in der annahme, dass 
der in der .lss datei steht ? )

void update_changes(uint8_t cc, uint8_t val)
{
  5e:  ef 92         push  r14
  60:  ff 92         push  r15
  62:  0f 93         push  r16
  64:  1f 93         push  r17
  66:  cf 93         push  r28
  68:  df 93         push  r29
  6a:  f8 2e         mov  r15, r24
  6c:  e6 2e         mov  r14, r22
  //if(val != buffer[cc])
  {
    midi_send_cc(cc, val);
  6e:  8c d0         rcall  .+280      ; 0x188 <midi_send_cc>
    midi_send_cc(cc, buffer[cc]);
  70:  cf 2d         mov  r28, r15
  72:  d0 e0         ldi  r29, 0x00  ; 0
  74:  8e 01         movw  r16, r28
  76:  0d 57         subi  r16, 0x7D  ; 125
  78:  1f 4f         sbci  r17, 0xFF  ; 255
  7a:  8f 2d         mov  r24, r15
  7c:  f8 01         movw  r30, r16
  7e:  60 81         ld  r22, Z
  80:  83 d0         rcall  .+262      ; 0x188 <midi_send_cc>
    midi_send_cc(cc, val != buffer[cc]);
  82:  60 e0         ldi  r22, 0x00  ; 0
  84:  f8 01         movw  r30, r16
  86:  80 81         ld  r24, Z
  88:  e8 12         cpse  r14, r24
  8a:  61 e0         ldi  r22, 0x01  ; 1
  8c:  8f 2d         mov  r24, r15
  8e:  7c d0         rcall  .+248      ; 0x188 <midi_send_cc>
    buffer[cc] = val;
  90:  cd 57         subi  r28, 0x7D  ; 125
  92:  df 4f         sbci  r29, 0xFF  ; 255
  94:  e8 82         st  Y, r14
  }
}
  96:  df 91         pop  r29
  98:  cf 91         pop  r28
  9a:  1f 91         pop  r17
  9c:  0f 91         pop  r16
  9e:  ff 90         pop  r15
  a0:  ef 90         pop  r14
  a2:  08 95         ret



@master.andre: hat leider auch nichts gebracht, immer noch das selbe 
Problem :(

von master.andre (Gast)


Lesenswert?

Hi,
ich bin kein Assembler-Experte, daher kann ich das letzte Posting nicht 
wirklich bewerten.
Es wäre wohl hilfreich wenn du mehr von deinem Quelltext posten würdest.

Oder du brichst dein Programm soweit runter das du viele Fehler 
defenitiv ausschließen kannst.

z.B aus:
midi_send_cc(cc, val != buffer[cc]);

folgendes machen.
if (val != buffer[cc])
{
 midi_send_cc(cc, 0x01)
}
else
{
 midi_send_cc(cc, 0x00)
}

Ich persöhlich habe keine Ahnung was der Compiler aus val != buffer[cc] 
für einen Variable bastelt. Gibts beim kompilieren denn keine Warnung ?

von Stefan B. (Gast)


Lesenswert?

Der Assemblercode arbeitet im Simulator IMHO korrekt. Ich habe im Moment 
keine weitere Idee.

von Mmmh (Gast)


Lesenswert?

Naja. Genau genommen, wäre der Code mit dem nicht auskommentierten if 
noch etwas interessanter.

Aber das Ganze deutet darauf hin, das eben doch keine gleichen Bytes in 
dem Array und in der Variablen sind, auch wenn der TO davon überzeugt 
ist.

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.