This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430F5529: send and receive chars via UART implementing interrupts

Part Number: MSP430F5529

Tool/software: Code Composer Studio

Hi everyone, I've been trying for many hours to modify an already working code that allows me to send/receive characters and strings via UART. The modification I'm trying to add is that this time I want to implement interrupts to do the same task. I've looked many related posts but still can't do it. 

My code is as follows: it has a UART_init function that setup the proper configuration for the UART, including the configuration and enable of interrupts. I also have 4 functions to send/receive a single char and a string (recepcion of strings is done with a Ring buffer).

So my doubt is how should I modify this functions in order to implement the interrupts, and also, how do I have to implement a ISR for this. I've been told that I shouldn't have a while(wait for flag) in these functions. I also want to implement a ISR to detect if a button has been pushed/released, clearly this can be solved easily if the previous problem is solved. In the main function I just initialize the UART by calling UART_init and then play with the transmission and recepcion of chars and string.

CODE can be found in file example_code.c

#include <msp430.h>
#include <string.h>

// Have a look at both the .h and the .c file, there is code missing.
#include "USART_implement_me.h"

#define BufferSize 16 //for the ring buffer


/* The main function */
int main(void){

WDTCTL = WDTPW + WDTHOLD;

// You already lerned how to configure that button, remember?
P1DIR = 0x01; // Set P1.0 (led) as output and P1.1 as intput (botón en cero)
P1REN |= 0x02; // Enable pull-up resistor on P1.1 (evita que la entrada flote)
P1OUT = 0x02; //fijamos P1.1 como HIGH (en 1).

struct USART_configuration config_57600_8N1 = {57600, 8, 0, 1};
// This time you should also configure and enable(!) some interrupts.
USART_Init(config_57600_8N1);

// Print a welcome message
USART_Transmit_char("G");
USART_Transmit_String("Please send some characters from your terminal.\r\n");


//TEST

char c = USART_Receive_char();
USART_Transmit_String("I received an ");
USART_Transmit_char(c);
USART_Transmit_String(".\r\n\r\n");

//END TESTEO

//
// while(1){

// // Your program will only ask *if* a string was received. If yes, it will display this string.
// // If not, it will just skip and do other stuff until it is time to ask again.
// // Here you could do all kinds of other cool things. Remember, the step above
// // will be skipped in most iterations, so you have plenty of processing time here....
// }
}


// Add a ISR for a button here! NOT WORKING

#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void){

volatile unsigned int t;
static const int DelaySum = 15000;

if( !(P1IN & 0x02)){ //if the button is pushed

USART_Transmit_String("The button was pushed.\r\n");
for(t = DelaySum; t>0; t--);

if ((P1IN & 0x02)){ //if the button is released

USART_Transmit_String("The button was released.\r\n");
for(t = DelaySum; t>0; t--);
}
}
}

volatile unsigned int i;
int retardo = 10000;

#include "USART_implement_me.h"

// Returns zero in case of success, non-zero for errors.
void USART_Init(struct USART_configuration config){

// Expected values
const unsigned int BR = 57600;
const int DL = 8;
const int Par = 0;
const int SB = 1;


// Given Values
unsigned int BaudR = config.BaudRate;
unsigned int DataL = config.DataLength;
unsigned int Parity = config.Parity;
unsigned int StopB = (config.StopBit -1);

// Basic config
UCA1CTL0 = UCMODE_0; // USCI mode: UART. By default.
P4SEL |= BIT4 + BIT5; // Set P4.4 as UCA1TXD, P4.5 as UCA1RXD
UCA1CTL1 |= UCSWRST; // Put eUSCI in reset. Allows to modify UCAxTL0.
UCA1CTL1 |= UCSSEL_2; // SMCLK (1048576MHz) (_0 es ACLK = 32768)
UCA1BR1 = 0;

//Specific config
if (BaudR == 57600){
if (DataL == 8){ // Only 8 bits accepted for USART mode. 7 bits reserved for SPI communication mode.
if (StopB == 0){ // 0 for 1 SP, 1 for 2 SP.
if (Parity == 0){

UCA1MCTL |= UCBRS_2; // From DataSheet: modulation and over sampling for this clk y BaudRate.
UCA1BR0 = 18;

UCA1CTL0 = !UC7BIT | !UCSPB | !UCPEN; // 8bit + 0 stop bits + parity disabled. purely ornament. These are the default values.
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**

// UCA1CTL1 = ~UCRXEIE;
/*NTERRUPTIONS*/
UCA1IE |= UCRXIE + UCTXIE; // Enable USCI_A1 RX interrupt
__bis_SR_register(GIE); // Interrupts enabled. LPM0_bits: para modo LPM0
for(i = retardo; i>0; i--);
}

else{
printf( "This communication channel is exclusively configured for no parity. Please enter a %d on the third argument \r\n", Par);
}
}
else{
printf( "This communication channel is exclusively configured for one stop bit. Please enter a %d on the fourth argument \r\n", SB);
}
}
else{
printf( "This communication channel is exclusively configured for eight bits length. Please enter an %d on the second argument \r\n", DL);
}
}
else{
printf( "This communication channel is exclusively configured for %d baud rate. Please enter %d on the first argument \r\n", BR, BR);
}

}


// Receives a single character.
char USART_Receive_char(void){

char singleC;

if(UCA1IFG & UCRXIFG){
/* Receive data */
singleC = UCA1RXBUF;
}
return singleC;

// A nice hint: With interrupts, your microcontroller can inform you whenever
// a character comes in. There is an interrupt called UCRXIFG for that.
// If such an interrupt would fill a buffer with the received data, this
// function here could return you one character from this buffer. You would no
// longer need to 'wait for the byte to arrive', but could just fetch it out
// of this buffer at any later point. And of course you've got a buffer,
// right?
// If the buffer is actually empty, you could maybe return a 0 or so to
// indicate that to the user?
}


// Transmits a single character
void USART_Transmit_char(uint8_t dato){

if(UCA1IFG & UCTXIFG ){
UCA1TXBUF = dato;
/* Clear the interrupt flag */
UCA1IFG &= ~UCTXIFG;


}
// A nice hint: With interrupts, you can send bytes whenever the register UCA1TXBUF
// is free. And there is an interrupt called UCTXIFG that *tells you*
// whenever UCA1TXBUF is free.
// This requires you to have some bytes in the buffer that you would like to
// send, of course. You have a buffer, don't you?
}


//Transmits a given string
void USART_Transmit_String(char *string){

if (string != NULL ) {

int length = strlen(string);
int i;
for(i=0;i<length;i++,string++){

USART_Transmit_char(*string);
}
}
}

//build for strings ending with \n.
char USART_Receive_StringRING(void){


unsigned int j = 0, p = 0, BufSiz = BufferSize;
char *string;

/*Case 1: the buffer is not full*/
while (j < BufSiz){

char caracterr = USART_Receive_char();
if (caracterr != '\n'){
string[j] = caracterr;
}

else if(caracterr == '\n'){ //If we receive a \n the master wants to end
string[j] = '\0'; //Overwrites the \n with \0
return string;
}
j++;
}

/*Case 2: the buffer is full*/
if ( j == BufSiz){
while(p < BufSiz){

char caracter = USART_Receive_char();

if (caracter != '\n'){
string[ p ] = caracter;
}

else if (caracter == '\n'){
*(string+BufSiz) = '\0';
rotleftmem(string, BufSiz, p);
break;
}

j++, p++;
if (p == BufSiz){
p = 0;
}
}
}


return string;
}

void rotleftmem(char *p, size_t len, size_t lshift){ //rotate a string

unsigned char *d;
size_t start;
size_t dx, sx;
size_t todo;
unsigned char x;

if (!len)
return;
lshift %= len;
if (!lshift)
return;

d = p;
todo = len;
for (start = 0; todo; start++) {
x = d[start];
dx = start;
while (1) {
todo--;
sx = dx + lshift;
if (sx >= len || sx < dx /*overflow*/)
sx -= len;
if (sx == start) {
d[dx] = x;
break;
}
d[dx] = d[sx];
dx = sx;
}
}
}

  • Hi Enzo,

    Let me see if I can pull together a simple example of using TX and RX interrupts.

  • Enzo,

    Here is a example showing how you can configure the UCA0 TX and RX interrupt vector to automatically handle the reception and transmission of bytes (chars).  When a byte is received, it will automatically copy byte to a buffer.  You must setup buffer and pointer elsewhere in your code (see full example I attached).  Likewise, when you want to transmit a string, create a buffer somewhere in your code and assign a pointer to it.  When ready to transmit the string, enable the UCTXIE and the ISR will automatically handle the rest.


    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    {
        switch(__even_in_range(UCA0IV,4))
        {
            case 0: break;
            case 2:
                  UCA0IFG &=~ UCRXIFG;              // Clear interrupt
                  *pRXBuffer = UCA0RXBUF;             // Clear buffer
                  break;
            case 4:
                UCA0TXBUF = *pTXBuffer++;
                if(--bytesToSend == 0)
                    UCA0IE &= ~UCTXIE;            // Disable USCI_A0 TX interrupt after string has been transmitted.
                break;
            default:
                break;

        }
        __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
    }

    Full example here.

    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    
    //******************************************************************************
    // UART Initialization *********************************************************
    //******************************************************************************
    
    #define LED_OUT     P1OUT
    #define LED_DIR     P1DIR
    #define LED_PIN     BIT0
    
    #define SMCLK_115200    0
    #define SMCLK_9600      1
    
    #define UART_MODE       SMCLK_115200//SMCLK_9600//
    
    unsigned char RXDataBuffer[64];
    unsigned char TXDataBuffer[64] = "Hello world\r\n\0";
    unsigned char* pTXBuffer = &TXDataBuffer[0];
    unsigned char* pRXBuffer = &RXDataBuffer[0];
    unsigned int bytesToSend;
    unsigned int bytesReceived;
    
    /*
     * UART timing based on 8MHz SMCLK
     */
    void initUART()
    {
        // Configure USCI_A0 for UART mode
        UCA0CTLW0 |= UCSWRST;                      // Put eUSCI in reset
    #if UART_MODE == SMCLK_115200
    
        UCA0CTLW0 |= UCSSEL__SMCLK;               // CLK = SMCLK
        // Baud Rate Setting
        // Use Table 21-5
        UCA0BRW = 4;
        UCA0MCTL |= UCOS16 | UCBRF_3 | UCBRS_5;
    
    #elif UART_MODE == SMCLK_9600
    
        UCA0CTLW |= UCSSEL__SMCLK;               // CLK = SMCLK
        // Baud Rate Setting
        // Use Table 21-5
        UCA0BRW = 52;
        UCA0MCTL |= UCOS16 | UCBRF_1 | UCBRS_0;
    #else
        # error "Please specify baud rate to 115200 or 9600"
    #endif
    
        UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
        UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
    }
    
    //******************************************************************************
    // Device Initialization *******************************************************
    //******************************************************************************
    
    void initGPIO()
    {
        // Configure GPIO
        P3SEL &= ~(BIT3 | BIT4);                 // USCI_A0 UART operation on FF5529LP
        P3SEL |= (BIT3 | BIT4);
    }
    
    void initClockTo16MHz()
    {
    
        UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
        UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
        UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
    
        // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
        do
        {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
        }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
        __bis_SR_register(SCG0);                  // Disable the FLL control loop
        UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
        UCSCTL2 |= 249;                           // Set DCO Multiplier for 8MHz
                                                  // (N + 1) * FLLRef = Fdco
                                                  // (249 + 1) * 32768 = 8MHz
        __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
        // Worst-case settling time for the DCO when the DCO range bits have been
        // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
        // UG for optimization.
        // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
        __delay_cycles(250000);
    }
    
    void TransmitData(unsigned char* string, unsigned int length)
    {
        pTXBuffer = string;
        bytesToSend = strlen((const char*) string);
        UCA0IE |= UCTXIE;                         // Enable USCI_A0 TX interrupt
    
    }
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                               // Stop watchdog timer
        initGPIO();
        initClockTo16MHz();
        initUART();
    
        /*
        * Use timer to demonstrate automatic tranmission.
        * Configure timer to periodically transmit a string.
        */
        TA0CCTL0 |= CCIE;                                      // TACCR0 interrupt enabled
        TA0CCR0 = 50000;
        TA0CTL |= TASSEL__SMCLK | MC__CONTINUOUS | ID__8;     // SMCLK, continuous mode
    
        __bis_SR_register(GIE);
    
        while (1)
        {
            __bis_SR_register(LPM0_bits | GIE);               // Enter LPM0
            __no_operation();                                   // For debugger
        }
    }
    
    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    {
        switch(__even_in_range(UCA0IV,4))
        {
            case 0: break;
            case 2:
                  UCA0IFG &=~ UCRXIFG;              // Clear interrupt
                  *pRXBuffer = UCA0RXBUF;             // Clear buffer
                  break;
            case 4:
                UCA0TXBUF = *pTXBuffer++;
                if(--bytesToSend == 0)
                    UCA0IE &= ~UCTXIE;            // Disable USCI_A0 TX interrupt after string has been transmitted.
                break;
            default:
                break;
    
        }
        __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
    }
    
    // Timer A0 interrupt service routine
    
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void Timer_A (void)
    {
        static int count = 10;
        if(--count == 0)
        {
            count = 10;
            TransmitData(&TXDataBuffer[0], sizeof(TXDataBuffer));
            _no_operation();
    
        }
    }
    

  • Thanks for your answer Dennis. I finally managed to figure it out. For any interested, I'll post the code below. 

    #include <msp430.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdio.h>
    
    
    
    // Have a look at both the .h and the .c file, there is code missing.
    #include "USART_implement_me.h"
    
    
    
    char *RBrx = NULL;
    char *RBtx = NULL;
    
    char recibido;
    char envio;
    
    volatile unsigned int time;
    int delay = 10000; //100 ms.
    
    /* The main function */
    int main(void){
    
        WDTCTL = WDTPW + WDTHOLD;         // Detener WDT
        // You already lerned how to configure that button, remember?
    
        // Initialise the serial communication interface. Note that this now also sets up the interrupts!
        /* struct USART_configuration config_57600_8N1 = {57600, 8, 0, 1}; */ // You can use it
    
        struct USART_configuration config_57600_8N1 = {57600, 8, 0, 1};
        USART_Init(config_57600_8N1);
    
        P1DIR |= BIT0;                            // Set P1.0 to output direction
        P1OUT &= ~BIT0;
    
        P1REN |= BIT1;                            // Resistencia activa en P1.1 (S2)
        P1OUT |= BIT1;                            // Configurada como pull-up
        P1IES |= BIT1;                            // Interrupcion por flanco de bajada
    //  P1IES &= ~BIT1;                         // P1.1 Lo/Hi edge
        P1IFG &= ~BIT1;                           // Baja flag de interrupcion de P1.1
        P1IE |= BIT1;                             // Habilita la interrupcion de P1.1
    
    
        __bis_SR_register(GIE);
    
    
        // Print a welcome message
        USART_Transmit_String("Please send some characters from your terminal.\r\n");
    
    
        while(1)
        {
            // Your program will only ask *if* a string was received. If yes, it will display this string.
            // If not, it will just skip and do other stuff until it is time to ask again.
            // Here you could do all kinds of other cool things. Remember, the step above
            // will be skipped in most iterations, so you have plenty of processing time here....
        }
    }
    
    
    
    // The initialisation function. Call it once from your main() program before
    // issuing any USART commands with the functions below!
    
    uint8_t USART_Init(struct USART_configuration config){
    
    
    //           // SMCLK = 12MHz
    //           UCSCTL3 |= SELREF_2;                      // Set DCO FLL reference = REFO
    //           UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
    
               __bis_SR_register(SCG0);                  // Disable the FLL control loop
               UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
               UCSCTL1 = DCORSEL_5;                      // Select DCO range 24MHz operation
               UCSCTL2 = FLLD_1 + 374;                   // Set DCO Multiplier for 12MHz
                                                          // (N + 1) * FLLRef = Fdco
                                                          // (374 + 1) * 32768 = 12MHz
                                                          // Set FLL Div = fDCOCLK/2
               __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
               // Worst-case settling time for the DCO when the DCO range bits have been
               // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
               // UG for optimization.
               // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle
               __delay_cycles(375000);
    
    
               P4SEL = BIT5 + BIT4;              // P4.5,4 = USCI_A1 TXD/RXD
               UCA1CTL1 |= UCSWRST;              // **Put state machine in reset**
               UCA1CTL1 |= UCSSEL_2;             // CLK = SMCLK
    
               UCA1BR1 = 0x00;
               switch (config.baudrate) {
                           case 9600:
                               UCA1BR0 = 226;                   // 12MHz/9600=1250 (see User's Guide)
                               UCA1BR1 = 4;
                               UCA1MCTL = UCBRS_0 + UCBRF_0;    // Modulation UCBRSx=1, UCBRFx=0
                               break;
    
                           case 19200:
                               UCA1BR0 = 113;                   // 12MHz/19200=625 (see User's Guide)
                               UCA1BR1 = 2;
                               UCA1MCTL = UCBRS_0 + UCBRF_0;    // Modulation UCBRSx=0, UCBRFx=0
                               break;
    
                           case 38400:
                               UCA1BR0 = 56;                   // 12MHz/38400=312.4 (see User's Guide)
                               UCA1BR1 = 1;
                               UCA1MCTL = UCBRS_4 + UCBRF_0;    // Modulation UCBRSx=0, UCBRFx=0
                               break;
    
                           case 57600:
                               UCA1BR0 = 208;                   // 12MHz/57600=208.2 (see User's Guide)
                               UCA1MCTL = UCBRS_2 + UCBRF_0;    // Modulation UCBRSx=3, UCBRFx=0
                               break;
    
                           default:
                               UCA1BR0 = 208;                   // 12MHz/57600=208.2 (see User's Guide)
                               UCA1MCTL = UCBRS_2 + UCBRF_0;    // Modulation UCBRSx=3, UCBRFx=0
                               break;
                       }
    
                       switch (config.parity) {
                           case 1:
                               UCA1CTL0 |= UCPEN;
                               UCA1CTL0 |= UCPAR;
                               break;
                           case 2:
                               UCA1CTL0 |= UCPEN;
                               UCA1CTL0 &= ~UCPAR;
                               break;
                           default:
                               UCA1CTL0 &= ~UCPEN;
                               break;
                       }
    
                       if (config.databits== 7) {
                           UCA1CTL0 |= UC7BIT;
                       }
                       else {
                           UCA1CTL0 &= ~UC7BIT;
                       }
    
                       if (config.stopbits== 1) {
                           UCA1CTL0 &= ~UCSPB;
                       }
                       else {
                           UCA1CTL0 |= UCSPB;
                       }
    
                       UCA1CTL1 &= ~UCSWRST;                  // **Initialize USCI state machine**
                       UCA1IE |= UCRXIE;                      // Enable USCI_A1 RX interrupt
    }
    
    
    // Transmits a given string
    void USART_Transmit_String(char* str)
    {
        while(*str !=0x00){
                 while(UCA1STAT&UCBUSY);
                 UCA1TXBUF = *str;
                 str++;
             }
    }
    
    
    void rotleftmem(char *p, size_t len, size_t lshift){
    
        unsigned char *d;
        size_t start;
        size_t dx, sx;
        size_t todo;
        unsigned char x;
    
        if (!len)
            return;
        lshift %= len;
        if (!lshift)
            return;
    
        d = p;
        todo = len;
        for (start = 0; todo; start++) {
            x = d[start];
            dx = start;
            while (1) {
                todo--;
                sx = dx + lshift;
                if (sx >= len || sx < dx /*overflow*/)
                    sx -= len;
                if (sx == start) {
                    d[dx] = x;
                    break;
                }
                d[dx] = d[sx];
                dx = sx;
            }
        }
    }
    
    
    
    
    //build for strings ending with \n.
    void RingBuffRX(char *string, char caracter){
    
        //Caso 1: No supero el tamaño de buffer.
        if (i < BufferSizeRX){
    
            if(caracter == '\n'){
                string[i] = '\0';
            }
            else if(caracter != '\n'){
                string[i] = caracter;
            }
            i++;
        }
    
    
        //Caso 2: Se supera el buffer.
        else if (i >= BufferSizeRX){
    
            if (j < BufferSizeRX){
                if (caracter != '\n'){
                    string[j] = caracter;
                }
                else if(caracter == '\n'){
                    *(string+BufferSizeRX) = '\0';
                    rotleftmem(string, BufferSizeRX, j);
                }
                j++;
    
                if (j == BufferSizeRX){
                    j = 0;
                }
            }
        }
    }
    
    // Get char from string
    char USART_GetChar(char *string){
    
        char caracter;
    
        if (i < BufferSizeTX){
            caracter = string[i];
            }
    
        else if (i == BufferSizeTX){
            caracter = '\0';
        }
        i++;
    
        return caracter;
    }
    
    
    void RingBuffTX(char *rxbuf,char *txbuf){
    
        if (BufferSizeRX > BufferSizeTX){
            rotleftmem(rxbuf, BufferSizeRX, BufferSizeRX-BufferSizeTX);
        }
        memcpy(*txbuf, *rxbuf, BufferSizeTX+1);
    }
    
    
    void __attribute__((interrupt(USCI_A1_VECTOR))) USCI_A1_ISR(void) {
          switch(__even_in_range(UCA1IV,4)) {
          case 0:break;                                        // Vector 0 - no interrupt
          case 2:                                              // Vector 2 - RXIFG
    
              recibido = UCA1RXBUF;
              RingBuffRX(*RBrx,recibido);
    
              if (recibido == '\n'){
                    USART_Transmit_String("Se recibio en el microc: \n\r");
                    USART_Transmit_String(*RBrx);
                    USART_Transmit_String("\n\r");
    
                   //Limpiamos los indices tras el envío.
                   i = 0, j = 0;
    
                   UCA1IE |= UCTXIE;
              }
    
            break;
          case 4:                                             // Vector 4 - TXIFG
    
              USART_Transmit_String("Se envio a la terminal: \n\r");
    
              RingBuffTX(*RBrx, *RBtx);
              char enviar = USART_GetChar(*RBtx);
              while (enviar != '\0'){
                  while(UCA1STAT&UCBUSY);
                  UCA1TXBUF = enviar;
                  enviar = USART_GetChar(*RBtx);
              }
    
              while(UCA1STAT&UCBUSY);
              UCA1TXBUF = '\r';
              UCA1TXBUF = '\n';
    
              //Limpiamos los indices y el buffer tras el envío.
              i = 0, j = 0;
              memset(*RBrx,0, sizeof RBrx);
              memset(*RBtx,0, sizeof RBtx);
    
            UCA1IE &= ~UCTXIE;
            break;
          default: break;
          }
    }
    
    
    // Add a ISR for a button here!
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void){
    
        switch( __even_in_range( P1IV, P1IV_P1IFG7 )) {
        case P1IV_P1IFG1: // Pin 1 (button 2)
    
            if( !(P1IN & 0x02)){
                USART_Transmit_String("The button was pushed.\r\n");
                for(time = delay; time>0; time--);
                while(!(P1IN & 0x02));
                if((P1IN & 0x02)){
                USART_Transmit_String("The button was released.\r\n");
                }
            }
            break;
        default:   _never_executed();
    
        }
    
    }
    

**Attention** This is a public forum