2016-06-29 29 views
4

Ich habe eine Schleife mit mehreren bedingten Verzweigungen darin. Die Schleife soll immer die gleiche Anzahl von Zyklen durchlaufen, egal welche Zweige genommen werden.Auswuchten von Zweigen in Bezug auf die verwendeten Zyklen

Um dies zu erreichen, füllte ich die kürzeren Äste mit NOP s (unter Verwendung von asm("nop")), bis sie die gleiche Länge zu den längeren Ästen hatten. Das hat erreicht, was ich wollte.

Jetzt habe ich viel mehr Zweige und möchte die Zweige automatisch ausgleichen. Ich kompiliere mit avr-gcc.

Gibt es eine Möglichkeit, dies zu tun?

Wie gewünscht: Ich verwende einen ATmega 1284p und avr-gcc für meine Implementierung.

+1

Was möchten Sie erreichen, indem Sie dies tun? – fuz

+0

Die Schleife fragt einen Pin eines Micocontrollers ab. Um sicherzustellen, dass der Pin in regelmäßigen Abständen abgefragt wird, sollte die Laufzeit der Schleife gleich sein, egal welche Zweige verwendet werden. – tuzojil

+0

Ich glaube nicht, dass der Compiler tun kann, was Sie wollen. Es ist möglicherweise eine bessere Idee, einen interruptgesteuerten Ansatz zu verwenden oder Ihren Code neu zu schreiben, damit er nicht verzweigt ist. Wenn Sie uns Ihren Code zeigen, kann ich Ihnen helfen, ihn so umzuschreiben, dass er nicht verzweigt. – fuz

Antwort

3

Nun, Sie haben nicht angegeben, ob Sie in asm oder in c codieren, da Sie Verzweigungen verwenden, aber Sie "asm()" aufrufen ... Wenn Sie C verwenden, können Sie millis() am Anfang von aufrufen Schleife, und nenne es auch am Ende. Sie müssen die maximale Dauer der Schleife berechnen. Also subtrahiere die beiden Millis-Werte und vergleiche die Differenz mit der maximalen Dauer der Schleife. Ja Lilbit verwirrend, hier der Code:

#define MAX_DURATION 1000 //let's say 1 second, but you should calculate it 
while(yourcondition) { 
    temp1 = millis(); 
    //do your branches 

    temp2 = millis(); 
    delay(MAX_DURATION-(temp2-temp1)); 
} 

Während, wenn Sie in asm codieren, müssen Sie zunächst Interrupts zu deaktivieren, um nicht mehr Schleifen zu haben. Dann können Sie Setup ein 16-Bit-Timer, wenn Ihr Prozessor jeder hat, mit dem größten Vorteiler und dann den Timer-Wert Überprüfung statt Millis und eine Verzögerungsfunktion machen, leicht gemacht wie:

delay: ;put the millisecond to wait in r17:r16 
    ldi r18, 200 
    ldi r19, 26 ;200*26* (3 cicles each little loop) = 1 millisecond of delay with a 16MHz oscillator 
    mov r20, r17 
    delay_loop: 
     dec r19 
     brne delay_loop 
     ldi r19, 26 
     dec r18 
     brne delay_loop 
    ldi r18, 200 
    dec r17 
    brne delay_loop 
    mov r17, r20 
    dec r16 
    brne delay_loop 
    ret 

der Hoffnung, dass Ihr INSTRUNCTION Set ist ähnlich wie meiner. Geben Sie bei der nächsten Zeit an, welchen Code Sie verwenden und auf welchen Prozessor Sie abzielen