2016-08-17 12 views
0

Contexte: J'ai ce microcontrôleur LPC11C24 sur lequel je travaille qui utilise un seul minuteur 32 bits pour lire l'entrée PWM sur une broche et contrôler les sorties PWM sur 2 autres broches. Étant donné que l'entrée et la sortie sont sur le même temporisateur, je ne fais aucune réinitialisation du registre de temporisation (TC). Pour la sortie en particulier, j'essaie de le configurer de telle sorte que le registre de correspondance s'incrémente continuellement soit avec le moment où le signal devrait être HIGH soit avec un signal LOW respectueusement. Exemple: Si j'ai une période de 10000 ticks et mon cycle de service est de 50%, chaque fois que je reçois une interruption, je veux ajouter 5000 à MR0 pour préparer l'interruption suivante.Comment configurer la sortie PWM sur un microcontrôleur de la série LPC11CXX sans aucune réinitialisation de minuterie

Initialisation:

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; 
    } 
} 

Lorsque je sonde cette broche je reçois pas de sortie que ce soit, donc je ne suis pas sûr de ce que je fais mal. Un autre problème que j'ai est que je ne reçois pas d'interruptions, sauf lorsque je fournis un nouveau cycle de service à partir d'un code externe (qui définit simplement MR0 = TC). Je pense que c'est parce que TC prend de l'avance sur MR0, mais je ne sais pas comment éviter cela. Merci beaucoup! S'il vous plaît laissez-moi savoir si je peux fournir des informations supplémentaires.

+0

Comment "contrôle-t-on l'entrée PWM **"? – Olaf

+0

@Olaf Merci. La question a été modifiée. – LaneL

Répondre

0

Je l'ai compris. Il y avait 2 choses qui ne vont pas ici.

La configuration d'E/S était incorrecte. Après avoir lu la documentation, j'ai découvert que la fonction doit être définie sur 1 pour GPIO. 0 est une fonction réservée. La deuxième chose qui ne va pas ici était que j'avais besoin de mettre en pause la minuterie pour traiter les ISR.

/* 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

Mettre la minuterie en pause est incorrect. Ne devriez-vous pas plutôt attendre d'effacer la source d'interruption jusqu'à ce que tout le travail soit terminé? – Lundin

+0

@Lundin J'ai aussi cette inquiétude, mais pour les hautes fréquences, la minuterie devance le registre de correspondance et ne s'interrompt jamais au prochain front montant/descendant. J'ai essayé d'effacer l'interruption à la fin de l'ISR, mais cela ne semblait pas faire de différence. – LaneL