Forum: Mikrocontroller und Digitale Elektronik Zeitkritische Interrupt-Routine bei XC886


von Chris (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe ein Problem mit der sich im Anhang befindlichen Interrupt 
Routine; bei einem Timer Interrupt wird einfach ein weiteres Bit (aus 
einem Array) rausgeschiftet und auf einen PortPin gelegt.
Ab einer Geschwindigkeit von 56 kBit/s dauert die Routine aber zu lange 
und eine höhere Geschwindigkeit wird nicht erreicht.

Ich wäre sehr dankbar, wenn mir jemand helfen könnte, diese Routine 
schneller zu gestalten?

LG Chris

von Peter D. (peda)


Lesenswert?

Muß die Funktion Set_CS_TDA5150(NOT_ACTIVE) unbedingt extern sein?
Damit zwingst Du den Compiler, alle 12 Register zu push/popen.
Besser also als Macro schreiben.

Was soll denn die Funktion überhaupt machen?
Wenn Du nur einen Pin setzen mußt, nimm besser Bitbefehle (Pin als 
sfr8).


Peter

von Chris (Gast)


Lesenswert?

Danke, toll!

Set_CS_TDA5150(NOT_ACTIVE) setzt tatsächlich nur einen PortPin.
Hab nun diesen Aufruf durch P1_DATA &= ~0x40;  // CS-line to NOT_ACTIVE 
erstzt. Das bringt natürlich schon einiges!



Mir macht der Ausdruck

P1_DATA =  (((TXFifo0[TXiterations] << BitsPerByte)& 0x80) >> 4) | 
(P1_DATA & 0x44);

noch Kopfzerbrechen. Könnte ich das noch irgendwie verbessern?

LG

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dein Kommentar
1
// set the data to pin 3 ...
legt eine Bitmanipulation des einen Pins nahe.
Warum beackerst du den ganzen Port?
Mach das doch im Stil des
> P1_DATA &= ~0x40;
also etwa so:
1
if( (TXFifo0[TXiterations] << BitsPerByte)& 0x80 ) 
2
   P1_DATA |=  0x8;
3
else 
4
   P1_DATA &= ~0x8;

EDIT:
Noch besser wäre es, nicht einen Zähler zu verwenden, sondern die Maske 
zu schieben, dann bleibt es bei einer Abfrage:
1
if (TXFifo0[TXiterations] & BitMask) 
2
   P1_DATA |=  0x8;
3
else 
4
   P1_DATA &= ~0x8;
5
6
if(BitMask>>=1) {   // after 1 byte is shifted out,      
7
   TXiterations++;  // increment TXiterations which is an index of an array and 
8
   BitMask = 0x80;  // reset the bit-mask which is necessary for the mask operation above
9
}

von Chris (Gast)


Lesenswert?

Ja, guter Einwand, aber beim Setzen des Pins (via P1_DATA |= 0x40;) 
benötigt man einen anderen Befehl als beim Zurücksetzen (P1_DATA &= 
~0x40;).
Zusätzlich bräuchte ich noch eine teure if-Abfrage...

Das heißt eine direkte Zuweisung in einer Zeile ist nicht mehr möglich, 
oder überseh ich da was?

von Chris (Gast)


Lesenswert?

Aah, danke Lothar. Hab's zu spät gesehn...

von Peter D. (peda)


Lesenswert?

Du solltest mal versuchen mit Bitvariablen zu arbeiten, das macht vieles 
leichter (und schneller).

Ganz aufwendig ist ein variables Shift, nimm besser ne Maske, die man 
immer nur einmal schiebt.

Definier dochmal alle Variablen, damit man den Code compilieren kann, 
dann ist es viel einfacher zu optimieren.


Peter

von Chris (Gast)


Lesenswert?

So,
ich hab's nun so gelöst, dass ich die Maske verschiebe.

Aber Peter, wie meinst du das mit den Bitvariablen?

LG Christoph

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.