2016-08-17 4 views
0

Hintergrund: Ich habe diesen LPC11C24 Mikrocontroller, den ich arbeite, der einen einzelnen 32-Bit-Timer verwendet, PWM-Eingang auf einem Pin zu lesen und PWM-Ausgänge auf 2 zu steuern andere Stifte. Da der Eingang und der Ausgang auf dem gleichen Timer sind, mache ich keine Rücksetzungen des Timer-Registers (TC). Vor allem für die Ausgabe versuche ich, es so einzurichten, dass das Übereinstimmungsregister kontinuierlich entweder mit der Zeit zunimmt, wenn das Signal HIGH sein sollte, oder einem Signal NIEDRIG respektvoll ist.Wie man PWM-Ausgang auf einem Mikrocontroller der LPC11CXX-Reihe ohne irgendwelche Timer setzt

Beispiel: Wenn ich eine Periode von 10000 Ticks habe und mein Tastverhältnis 50% ist, möchte ich jedes Mal, wenn ich einen Interrupt bekomme, 5000 zu MR0 hinzufügen, um mich auf den nächsten Interrupt vorzubereiten.

Initialisierung:

IOCON_R_PIO1_1_bit.FUNC = 0; 
IOCON_R_PIO1_1_bit.MODE = 0; 
GPIO1DIR_bit.P1_1 = 1; 

LPC_TMR32B1->MCR |= (1<<0); /* Interrupt when MR0 matches TC */ 
LPC_TMR32B1->MR0 = 0; /* zero the match value */ 

ISR:

/* If interrupt was from MR0 */ 
if(LPC_TMR32B1->IR & (1<<0)) 
{ 
    /* Clear the interrrupt */ 
    LPC_TMR32B1->IR = (1<<0); 

    if(GPIO1DATA_bit.P1_1 == 1) 
    { 
     LPC_TMR32B1->MR0 = LPC_TMR32B1->TC; 
     LPC_TMR32B1->MR0 += OutputChan0MatchPeriodFalling; 
     GPIO1DATA_bit.P1_1 = 0; 
    } 
    else if(GPIO1DATA_bit.P1_1 == 0) 
    { 
     LPC_TMR32B1->MR0 = LPC_TMR32B1->TC; 
     LPC_TMR32B1->MR0 += OutputChan0MatchPeriodRising; 
     GPIO1DATA_bit.P1_1 = 1; 
    } 
} 

Wenn ich sondieren diesen Pin ich überhaupt keine Ausgabe zu erhalten, so dass ich bin mir nicht sicher, was ich falsch mache. Ein anderes Problem, das ich habe, ist, dass ich keine Unterbrechungen bekomme, außer wenn ich einen neuen Arbeitszyklus von einem externen Code (der im Grunde nur MR0 = TC setzt) ​​zur Verfügung stelle. Ich denke, weil TC dem MR0 voraus ist, aber ich bin mir nicht sicher, wie ich das verhindern kann. Ich danke dir sehr! Bitte lassen Sie mich wissen, wenn ich weitere Informationen zur Verfügung stellen kann.

+0

Wie funktioniert "PWM ** Eingang **"? – Olaf

+0

@Olaf Danke. Die Frage wurde bearbeitet. – LaneL

Antwort

0

Ich fand es heraus. Hier liefen 2 Dinge schief.

Die E/A-Konfiguration war nicht korrekt. Nach dem Lesen der Dokumentation habe ich herausgefunden, dass die Funktion für GPIO auf 1 gesetzt werden muss. 0 ist eine reservierte Funktion.

Die zweite Sache, die hier schief ging, war, dass ich den Timer anhalten musste, um den ISR zu verarbeiten.

/* If interrupt was from MR0 */ 
if(LPC_TMR32B1->IR & (1<<0)) 
{ 
    /* Pause timer */ 
    LPC_TMR32B1->TCR = 0; 

    /* Clear interrupt */ 
    LPC_TMR32B1->IR = (1<<0); 

    if(GPIO1DATA_bit.P1_1 == 1) 
    { 
     LPC_TMR32B1->MR0 = LPC_TMR32B1->TC + OutputChan0MatchPeriodFalling; 
     GPIO1DATA_bit.P1_1 = 0; 
    } 
    else if(GPIO1DATA_bit.P1_1 == 0) 
    { 
     LPC_TMR32B1->MR0 = LPC_TMR32B1->TC + OutputChan0MatchPeriodRising; 
     GPIO1DATA_bit.P1_1 = 1; 
    } 

    /* Restart timer */ 
    LPC_TMR32B1->TCR = 1; 
} 
+0

Das Anhalten des Timers klingt falsch. Sollten Sie nicht lieber warten, bis die Unterbrechungsquelle gelöscht ist, bis alle Arbeit erledigt ist? – Lundin

+0

@Lundin Ich hatte auch diese Bedenken, aber für hohe Frequenzen, wird der Timer vor dem Match-Register zu bekommen und es wird nie bei der nächsten steigenden/fallenden Flanke zu unterbrechen. Ich habe versucht, den Interrupt am Ende des ISR zu löschen, aber es schien keinen Unterschied zu machen. – LaneL

Verwandte Themen