2017-06-26 6 views
-1

ich ein Problem bin vor, während ein Timer-Interrupt basiert in mikroC für die PIC-Implementierung.Timer-Interrupt basiert in PIC-Mikrocontroller mit mikroC für PIC

Ich möchte für 8 mal einen Port-Pin wechseln, wenn ein Tastendruck auf PORTC.F0 und sollte es zu einer Verzögerung von 100 ms zwischen den Knebel sagen sein.

Normalerweise wäre dies sehr einfach mit einer Verzögerungsfunktion

for (i=0;i<=8;i++) 
{ 
    PORTB.F0=~PORTB.F0; 
    Delay_ms(100); 
} 

Aber während der Zeit, alle anderen Tastenfolgen werden vom System verpasst. Also dachte ich über die Implementierung der Lösung mit Interrupts nach.

#define SW PORTC.F0 

char ttime,i; 
volatile flag; 

void Inittimer() 
{ 
T1CON   = 0x01; 
TMR1IF_bit = 0; 
TMR1H   = 0x06; 
TMR1L   = 0x00; 
TMR1IE_bit = 1; 
INTCON  = 0xC0; 
} 

void Interrupt() 
{ 
if (TMR1IF_bit) 
{ 
    TMR1IF_bit = 0; 
    TMR1H   = 0x06; 
    TMR1L   = 0x00; 
    ttime--; 
    if (ttime==0) 
    { 
    flag=1; 
    } 
} 
} 

void main() 
{ 
Inittimer1(); 
TRISB = 0; 
TRISC.F0 = 1; 
PORTB = 0x00; 
while(1) 
{ 
if (SW==0) 
{ 
    ttime=3; 
} 
    if (flag==1) 
    { 
    for (i=0;i<=8;i++) 
    { 
    PORTB=~PORTB; 
    flag=0; 
    } 
    } 
} 
} 

Nichts funktioniert. Kann mir bitte jemand helfen, den Code zu korrigieren?

+2

"Nichts funktioniert" ist keine Problembeschreibung. Was funktioniert nicht? – Lundin

+0

Im Nachhinein ist nichts in der Tat ein sehr vager Kommentar. Ich versuche, einen PORT-Umschalter alle 100ms für genau 8 Zeiten mit Timer-Interrupt zu implementieren. Ich habe versucht, viele Optionen zu arbeiten, keiner von ihnen hat für mich funktioniert. Am nächsten kam ich, um den PORT nach einer bestimmten Zeitverzögerung mit Interrupt zu aktivieren. Aber kann es nicht davon abhalten, nach n hin und her zu schalten. – Ace

Antwort

0

Wenn Sie Ihren Timer initialisieren:

void Inittimer() 
{ 
T1CON   = 0x01; 
TMR1IF_bit = 0; 
TMR1H   = 0x06; // No prescaler? I doubt your clock speed is 40-some KHz! 
TMR1L   = 0x00; 
TMR1IE_bit = 1; 
INTCON  = 0xC0; 
} 

Warum Sie nicht direkt von der ISR-LED steuern?

if (ttime) 
     PORTB.F0 = (--ttime & 1); // ttime is not decremented when led is not blinking. 
    else 
     PORTB.F0 = 0;    // ensures the LED is off. 

8 mal blinken zu starten:

if (SW==0) 
{ 
    PORTB.F0 = 1; 
    ttime = 16; 
} 

Beachten Sie, dass mit einer 100ms Uhr unterbricht, können die ersten ‚Blinzeln‘ des LED bis zu 200 ms dauern ... Das ist, warum viele wie zu arbeitet mit einem schnelleren Timer-Interrupt (dies hat in der Regel auch andere Verwendungen), würde erfordern, die LED-Steuerung einen weichen Zugabe post-Scaler

if (blinking) 
    { 
     if (--blinkTimer == 0) 
     { 
     blinkTimer = BLINK_DELAY;  // whatever number it takes for 100ms. 
     PORTB.F0 = (--blinking & 1); 
     } 
    } 
    else 
    { 
     PORTB.F0 = 0 
    } 

Um zu beginnen zu blinken:

Dies sollte Ihnen eine gleichmäßigere ersten Blinzeln erhalten
if (SW==0) 
{ 
    blinking = (2 * BLINKS) - 1; 
    blinkTimer = BLINK_DELAY; 
    PORTB.F0 = 1; 
} 

.

+0

Danke für die Hilfe Michael. Ich habe das Problem gelöst, können Sie bitte überprüfen, ob der Ansatz korrekt ist? 'while (i <8) {if (Flag == 1) {i ++; PORTB.F0 = ~ PORTB.F0; cnt = 0; Flagge = 0; }} 'Dies schaltet den Port-Pin achtmal um und die Einstellung des Wertes von cnt erlaubt es, die Verzögerung genau einzustellen, mit der der Port-Pin umgeschaltet wird. Ist dieser Ansatz richtig? – Ace

+0

Es ist richtig, aber es blockiert Ihre Hauptschleife. Was von allen anderen Operationen, die Sie möglicherweise tun müssen? –

1

Gut, das sieht nicht richtig aus:

if (flag==1) 
    { 
    for (i=0;i<=8;i++) 
    { 
    PORTB=~PORTB; 
    flag=0; 
    } 
    } 

Wenn Sie zuerst sehen, dass flag eingestellt ist, können Sie sofort Schleife und schalten Sie den Ausgang 8 mal, ohne warten auf flag wieder auf 1 zu drehen. Das ist nicht richtig, es ist übermäßig vereinfacht.

Sie müssen nach dem flag suchen, dann schalten Sie den Ausgang und löschen Sie die flag, und warten Sie, bis es erneut gesetzt wird, den Zähler parallel zu halten. Die for-Schleife ist nicht die richtige Struktur dafür, da sie den Rest des Programms "aussperrt" und dazu führen könnte, dass Tastendrücke übersehen werden.

+0

Ich habe versucht zu tun, was Sie vorgeschlagen, – Ace

+0

tat ich versuche zu tun, was Sie vorgeschlagen ... statt der for-Schleife, ich eine andere Variable i erhöht, nachdem der Port umgeschaltet wurde und das Flag gelöscht. Ich habe eine bedingte Anweisung von 'if (i> = 8) {PORTB = 0x00; i = 0;} 'Das hat nicht funktioniert.Grundsätzlich kann ich den PORT starten, um nach einer bestimmten Verzögerung umzuschalten, aber ich kann nicht verstehen, wie man das Umschalten nach n Zyklen stoppt. – Ace