Forum: Mikrocontroller und Digitale Elektronik De-Parallelisieren


von Manuel (Gast)


Lesenswert?

Hallo,

ich habe hier eine Interrupt-Routine in der ich pro Takt aus vier 
Eingängen einen Teil der Zahl erstellen möchte. Und nach vier Takten die 
gesammte Zahl (16bit).
Wird das wohl folgendermaßen funktionieren und kann man dies irgendwie 
noch optimieren?
1
void __attribute__ ((__interrupt__)) _CNInterrupt(void)
2
{
3
  static unsigned char interuptCounter;
4
  static int rcvX;
5
6
  rcvX = (rcvX<<1) + PORTBbits.RB5;    // Eingänge auslesen
7
  rcvX = (rcvX<<1) + PORTBbits.RB6;
8
  rcvX = (rcvX<<1) + PORTBbits.RB7;
9
  rcvX = (rcvX<<1) + PORTBbits.RB8;
10
11
  if (interuptCounter >= 3){            // Übertragung vollständig!
12
    x = rcvX;
13
    rcvX = 0x00;
14
    rcvReady = 1;
15
    interuptCounter = 0;
16
  } else {
17
    interuptCounter++;
18
  }
19
20
  IFS1bits.CNIF = 0;                    // CN Interrupt zurücksetzen
21
}

Vielen Grüße,
   Manuel

von Achim M. (minifloat)


Lesenswert?

Manuel schrieb:
> PORTBbits.RB5

Liefert das Teil wirklich ein 0x01 zurück oder ein 0xFF?


Ich würde PORTB in eine 8bit-Variable schreiben und mit 0xf0 
ver-&-en(quatsch wegmaskieren).

Diese 8bit-Variable dann abhängig vom Counter
0: Nibbles tauschen und auf Low-Byte der 16bit-Zahl addieren
1: belassen wie es ist und auf Low-Byte der 16bit-Zahl addieren
2: Nibbles tauschen und auf Hi-Byte der 16bit-Zahl addieren
3: belassen wie es ist und auf Hi-Byte der 16bit-Zahl addieren

Damit sparst du dir das Einzelgeschiebe oben.

mfg mf

PS: Ich habe jetzt das Least Significant Nibble zuerst drin. Wenn das 
MSN zuerst kommt, dann die Nummerierung umdrehen :)

von Manuel (Gast)


Lesenswert?

Mini Float schrieb:
> Liefert das Teil wirklich ein 0x01 zurück oder ein 0xFF?

Sehr guter Hinweis das muss ich auf jeden Fall überprüfen.


Wie groß wäre denn wohl der Speedup?

So habe ich 4 Shifts, 4 Additionen und ein If-Zweig = 9 Befehle (?) pro 
Interupttakt.

Wenn ich deinen Vorschlag richtig verstehe, hätte ich:
1. Maskieren
2. Switch mit 4 Pfaden
3. jedes zweite mal einen vierfach Shift
4. Addition
= ?? Befehle

Vielen Dank auf jeden Fall schon mal,
  Manuel

von Achim M. (minifloat)


Lesenswert?

Manuel schrieb:
> jedes zweite mal einen vierfach Shift

Nibbletausch ist vielleicht sogar als ein einzelner Befehl verfügbar. 
Ich kenn mich mit deinem Proz jetzt nicht aus, das kann man aber mit 
einem Blick auf den Befehlssatz einfach eruieren.

Der Switch mit 4 Pfaden ließe sich auch noch runterbrechen:

Mal als Überlegung: bei jeder geraden Zahl, also 0 und 2, muss der 
Nibbletausch gemacht werden, sonst nicht.

Bei Zahlen größer gleich 2 muss auf das hibyte addiert werden, sonst auf 
das lowbyte. Dazu kann man dem Compiler auf die Sprünge helfen, indem 
man sich die 16bit Variable als Union aus einer 16bit Zahl und zwei 
8bit-Zahlen macht.

Also im Code dann vllt. sowas:

einlesepuffer = Port_input_Symbol;

if(!(counter & 0x01))
{
   tausche_nibbles(&einlesepuffer);
}

if(counter & 0x02)
{ //Zweig, wenn in counter das 0x02 bit gesetzt ist, counter >= 2
   meine16bitzahl.hibyte += einlesepuffer;
}
else
{ //Zweig, wenn in counter das 0x02 bit gesetzt ist, counter < 2
   meine16bitzahl.lobyte += einlesepuffer;
}

counter++;

if(counter & ~0x03)
{  //Wenn counter größer als 3 ist
   x = meine16bitzahl.ganzezahl;
   meine16bitzahl.ganzezahl = 0;
   counter = 0;
}

Deine Variante ist natürlich weitaus übersichtlicher und 
verständlicher...
Wenn der compiler gut ist, werden ifs und/oder switches in eine 
Sprungadressberechnung übersetzt. Das ist weitaus schneller, als alle 
Switch-zweige einzeln abzuklappern:
Wenn du sowas wie

if(irgeneinezahl > 123)
   tuediesundjenes();

schreibst, wird diese Bedingung z.B. in eine Subtraktion und ein jump 
lower zero übersetzt.

Wenn jetzt in einem Switch alle cases einzeln untersucht werden müssen,
braucht das nat. Rechenzeit und Flash.
Aber man sollte es auch nicht übertreiben :D

mfg mf

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.