Schneller Bit Buffer

Gast #3236737
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.
#3236855
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.
#3236858
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.
Gast #3236861
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.
#3236884
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.
Gast #3236901
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren