Forum: Mikrocontroller und Digitale Elektronik Schneller Bit Buffer


von Spackotus (Gast)


Lesenswert?

Hallo

Ich möchte eine Funktion Schreiben um ein 564kbps schnelles Signal 
schnell in ein 2048b bzw. 256B Buffer zu schreiben. Mein Controller ist 
leider nur 16MHz schnell. Demnach habe ich nur knapp 28 Prozessor Zyklen 
um das Signal zu verarbeiten.

Eine Funktion die ich geschrieben habe ist aber zu langsam... :
1
void FSK_Put(char State, int BitCount)
2
{
3
  FSK_Bit_Count = FSK_Bit_Count + BitCount;
4
5
  while((BitCount > 0) || (done == false))
6
  {
7
    Datenbuffer[chars] = (Datenbuffer[chars] & (~(1<<bits))) | ((1&&State)<<bits);
8
    // (Datenbuffer[chars] & (~(1<<bits))) //-> in diesem Audruck wird das Bit an der Stelle 'bits' auf 0 gesetzt
9
    // | ((1&&State)<<bits)                //-> in diesem Azsdruck wird das vorher auf 0 gesetzte bit mir dem Statebit ersetzt
10
11
    bits++;
12
    if(bits > 7)
13
    {
14
      bits = 0;
15
      chars++;
16
    }
17
    if(chars > 256)
18
    {
19
      done = true;
20
    }
21
    
22
    BitCount--;
23
  }
24
}

Kennt jemand eine schnellere Möglichkeit dieses Buffer zu füllen?
Ein Assembly kommt auch in Frage, ich kenne mich damit einfach nicht 
aus.

von Karl H. (kbuchegg)


Lesenswert?

Diese Operation

  1<<bits


willst du nicht haben.
Der AVR hat keinen Barrelshifter, d.h. diese Operation muss in eine 
Schleife aufgelöst werden. Und das dauert dann.

von Karl H. (kbuchegg)


Lesenswert?

Und das hier

(1&&State)<<bits

willst du schon gleich gar nicht haben.


Überleg dir eine Lösung, wie du anstelle dieser variablen Shifts mit 
einer Maske operierst, die du bei jedem Bit um 1 Position weiterschiebst 
(und nach 8 Bit wieder zurücksetzt). Und dann verwendest du ein ganz 
banales if anstelle dieses logischen &&


Dein Code ist deswegen zu langsam, weil du ihn so geschrieben hast, dass 
er für den AVR möglichst komplex und kompliziert abzuarbeiten ist.

von Der (Gast)


Lesenswert?

Falls der Clock vorhanden ist, könntest du auch die SPI verwenden.

von Karl H. (kbuchegg)


Lesenswert?

> void FSK_Put(char State, int BitCount)

Sicher, dass du hier einen int brauchst?
Muss es wirklich sein, dass du dein AVR in 16 Bit Arithmetik 
reintreibst, wo es 8 Bit auch tun? Kannst du nicht beim Aufrufer 
sicherstellen, dass der BitCount nie größer als 255 werden kann? 
Gegebenenfalls muss der dann zb nach 255 empfangenen gleichen Bits 
zwischendurch einfach mal den State ins Array schreiben lassen und mit 
der Zählung dann wieder bei 0 beginnen. In Summe dürfte das mehr 
bringen, als wie wenn du in dieser Funktion jedesmal unnötigerweise 16 
Bit Arithmetik durchkaust.

von Spackotus (Gast)


Lesenswert?

Nun... es ist kein AVR sonder ein PIC18F87J11

von Karl H. (kbuchegg)


Lesenswert?

Spackotus schrieb:
> Nun... es ist kein AVR sonder ein PIC18F87J11

Ich mag mich irren. Aber auch der hat keinen Barrelshifter.

von Der (Gast)


Lesenswert?

Der schrieb:
> Falls der Clock vorhanden ist, könntest du auch die SPI verwenden.

Nachtrag:
Falls der Clock nicht vorhanden ist, dann kannst du trotzdem die SPI 
verwenden. Einfach den Controller als Master schalten, per Interrupt 
(oder DMA, falls vorhanden) Bytes über MOSI ausgeben. Die Daten kommen 
dann über MISO rein. Sie sind natürlich asynchron zu der Quelle, aber 
das ist deine momentane Lösung auch.

von Karl H. (kbuchegg)


Lesenswert?

1
unsigned char BitMask = 0x01;
2
3
void FSK_Put(unsigned char State, int BitCount)
4
{
5
  FSK_Bit_Count = FSK_Bit_Count + BitCount;
6
7
  while( BitCount > 0 && chars < 256 )
8
  {
9
    if (State)
10
      Datenbuffer[chars] &= ~BitMask;
11
    else
12
      Datenbuffer[chars] |= BitMask;
13
14
    BitMask <<= 1;
15
16
    if(BitMask == 0x00)
17
    {
18
      BitMask = 0x01;
19
      chars++;
20
    }
21
22
    BitCount--;
23
  }
24
}

und über die Sache mit dem int für BitCount solltest du nochmal 
nachdenken. Wenn Speed wichtig ist, dann willst du nicht wirklich deinen 
8-Bit µC sinnlos in 16 Bit Arithmetik treiben, wenn es nicht notwendig 
ist.

von Spackotus (Gast)


Lesenswert?

Danke Vielmals für die Beiden Vorschläge und auch für den Code!!!


@Karl Heinz Buchegger:
Ich habe alles mal schön durchdacht was du geschrieben hast und du hast 
mir klar gemacht, dass diese Lösung gar nicht funktionieren kann.

Wenn ich nämlich 200b Low habe und dann nur 1b High, müssten erst die 
200b in den Buffer geladen werden und es reicht dann zeitlich nicht mehr 
für 1b High.


@Der (Gast):
Diesen Lösungsvorschlag werde ich nun mal genau prüfen... Danke für 
diese kreative Zweckentfremdung des SPI =D

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.