www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitschubserei...


Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es müssen 2 CAN-Geräte gekoppelt werden, die sich erstmal nicht
verstehen. AT90CAN128/16MHz + MCP2515, also 2 getrennte Bussysteme.
Compiler CodeVision. Läuft auf beiden Seiten mit 500kbit und die Daten
und IDs müssen hübsch durcheinandergewürfelt werden. Im Prinzip
funktionierts, allerdings bekomme ich bei hoher Buslast Zeitprobleme.
Hauptverursacher ist folgende Routine:

void copy_bit_up (uchar s_botschaft, uchar s_byte, uchar s_bit, uchar
d_botschaft, uchar d_byte, uchar d_bit)
{if (CAN_Matrix1[s_botschaft].data[s_byte] & (1<<s_bit))
CAN_Matrix2[d_botschaft].data[d_byte]|= (1<<d_bit);     //Bit setzen
    else CAN_Matrix2[d_botschaft].data[d_byte]&= ~(1<<d_bit);
                                         //Bit löschen
}

copy_bit_up (6,1,4,4,1,7);     //source Botschaft, source byte_nr,
source bit_nr, dest_Botschaft, dest_byte_nr, dest_bit_nr
Generatorleuchte
Das dauert über 200 Takte...

Lösung2:
if (CAN_Matrix1[Botschaft6].data[byte1] & (0x10))
CAN_Matrix2[Botschaft4].data[byte1]|= (0x80);      //Bit setzen
    else CAN_Matrix2[Botschaft4].data[byte1]&= ~0x80;

Im Gegenzug mit absoluten Werten nur ca. 20 Takte
Und da ich ca. 150 Bits je Richtung umsortieren muss, gerät das ganze
schnell an Grenzen.
Codespeicher hätte ich genug, allerdings möchte ich mir es nicht antun,
Lösung2 300 mal zu schreiben, das ist zu fehlerträchtig.
Und nun die eigentliche Frage: Gibt es eine Möglichkeit, dieses ähnlich
guter alter Assembler-Macro-Programmierung zu lösen?

Autor: Bjoern Buettner (tishima)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Mal etwas naiv gefragt, Codespeicher hast Du genug, was spricht denn
gegen eine look up table ??

mfg,
Bjoern

Autor: thkais (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Den Ausdruck (1<<x) durch Tabellen ersetzen sollte schon einiges
bringen, ist auch noch nicht zu groß. Ich würde auch noch eine
getrennte Tabelle für die negierten Werte machen.
Arbeitet der Compiler bei den logischen Operationen mit 16 oder 8 Bit?
Ein Typcasting auf 8 Bit bringt manchmal auch noch etwas.

Autor: thkais (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmpf - doch zu spät g

Autor: Klaus H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht etwas optimieren:

Du berechnest 2 mal 1<<d_bit. Das kannst du in einer Variable
speichern. Dann der Datentyp: Welche Werte können (1<<d_bit) bzw.
(1<<s_bit) annehmen? Laut deinem Beispiel könnte das nur ein Byte sein,
der Compiler wird aber wahrscheinlich ein int daraus machen. Also
explizite typumwandlungen vornehmen:
((unsigned char)(1<<d_bit))


Macroprogrammierung kannst du mit Templates machen (wenn der compiler
das kann)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wärs, gleich beim Aufruf statt der Bitnummer die Bitmaske zu
übergeben ?

Dann entfällt die zeitraubende Schieberei.

Dem GCC ist leider in Vergleichsausdrücken das 16Bitten selbst mit cast
nicht abzugewöhnen.
Erst wenn man den Wert in einer 8Bit-Variablen ablegt, muß er
notgedrungen nur 8Bit vergleichen, z.B. wenn die Maske schon als 8Bit
vorliegt.


Peter

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, gerade mal die Funktion mit konstanter Bitadresse compiliert statt
der Schieberei

void copy_bit_up_test(uchar s_botschaft, uchar s_byte, uchar
d_botschaft, uchar d_byte)
{if (CAN_Matrix1[s_botschaft].data[s_byte] & (0x80))
CAN_Matrix2[d_botschaft].data[d_byte]|= (0x40);     //Bit setzen
    else CAN_Matrix2[d_botschaft].data[d_byte]&= ~(0x40);
                                         //Bit löschen
}
Da sind es nur noch 130 Takte, dazu käme ja noch der Tabellenzugriff +
Parameterübergabe, das wird nicht die Lösung werden.

Ich möchte schon zur Compile-Zeit die Bitadresse ausrechnen lassen.
Was sind templates? Klingt erstmal interessant.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wird denn copy_bit_up_test() aufgerufen ?

Wenn die Argumente Konstanten sind, dann ist es besser gleich beim
Aufruf die Adresse zu übergeben, statt erst umständlich ne 2-fache
Indirektion ausrechnen zu lassen.


Peter

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Logisch, direkt die Bitmaske zu übergeben, ist natürlich effektiver. Kam
wohl daher, dass im CAN-Funktionsrahmen die Bitvariablen mit Botschaft:
ByteNr:BitNr angegeben sind:-)
Aber es ist auch nicht die Lösung, braucht 140 Takte

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
copy_bit_up_test (6,1,0x10,4,1,0x80);     //source Botschaft, source
byte_nr,source_bit_mask, dest_Botschaft, dest_byte_nr, dest_bit_mask

Die Variablen selbst:
typedef struct
{
    unsigned int  id;
    unsigned char rtr;
    unsigned char length;
    unsigned char data[8];
} CANMessage;


CANMessage CAN_Matrix1[24];
CANMessage CAN_Matrix2[24];

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.