2016-11-21 2 views
0

J'ai des interruptions RX fonctionnant correctement, mais je voulais ajouter des interruptions TX. Je réponds à de longues commandes sur l'UART et je ne veux pas gaspiller de cycles en attendant que le TX se termine avant d'envoyer le prochain octet. J'essaie d'activer les interruptions, de transmettre les données qui doivent être transmises, puis de désactiver les interruptions jusqu'à ce que le prochain paquet TX arrive.MSP430 Activation/désactivation de l'interruption UART TX

Cela fonctionne très bien pour la première charge utile que j'envoie. Je le vois sortir très bien. Cependant, dès que je désactive une fois les interruptions TX, je ne peux plus jamais entrer dans l'ISR. Comment sur le MSP430 permet-on d'activer les interruptions TX sur l'UART et de l'envoyer de nouveau dans l'ISR? Ci-dessous, où vous voyez l'appel EUSCI_A_UART_enableInterrupt, cette ligne ne devrait-elle pas déclencher mon ISR chaque fois que l'interruption est activée? Si non, COMMENT PUIS-JE RETOURNER DANS LE ISR?

est ici le code de transmission:

void UartSendChar(uint8_t tx_char) 
{ 
    ring_buffer_put(_rbdTx, &tx_char); 
    EUSCI_A_UART_enableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT); // Enable interrupt 
} 

Voici mon ISR:

void EUSCI_A1_ISR(void) 
{ 
    int c=-1; 
    switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG)) 
    { 
    case USCI_NONE: break; 
    case USCI_UART_UCRXIFG: 
     ... 
    case USCI_UART_UCTXIFG: 
     // If there's something in the Ring Buffer, transmit it 
     // If not, then disable TX interrupts until new data gets written. 
     if (ring_buffer_get(_rbdTx, &c) == 0) 
     { 
      EUSCI_A_UART_transmitData(EUSCI_A1_BASE, (uint8_t)c); 
     } 
     else 
     { 
      EUSCI_A_UART_disableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT); 
     } 
+0

est-bord d'interruption TX ou niveau déclenché? Dans le premier cas, vous devez pousser un caractère du code de la ligne principale. – user58697

Répondre

2

Je compris le problème. Dans ce MSP430 particulier, lorsque le vecteur d'interruption est lu et qu'il montre une interruption TX, le bit TXIFG est automatiquement effacé par le micro.

Afin de redémarrer cet ISR après avoir réactivé les interruptions TX, le bit TXIFG doit être manuellement à nouveau à 1, ce qui indique une interruption en attente. De cette façon, lorsque les interruptions sont activées après que les données ont été placées dans la file d'attente, le bit TXIFG est défini, de sorte que l'ISR s'exécute et expédie les données.

Maintenant, mon ISR ressemble à ceci:

void EUSCI_A1_ISR(void) 
{ 
    int c=-1; 
    switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG)) 
    { 
    case USCI_NONE: break; 
    case USCI_UART_UCRXIFG: 
     ... 
    case USCI_UART_UCTXIFG: 
     // If there's something in the Ring Buffer, transmit it 
     // If not, then disable TX interrupts until new data gets written. 
     if (ring_buffer_get(_rbdTx, &c) == 0) 
     { 
      EUSCI_A_UART_transmitData(EUSCI_A1_BASE, (uint8_t)c); 
     } 
     else 
     { 
      EUSCI_A_UART_disableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT); 

      // Set TXIFG manually back to 1 for next time. 
      HWREG16(EUSCI_A1_BASE + OFS_UCAxIFG) |= EUSCI_A_UART_TRANSMIT_INTERRUPT; 

     }