Project

General

Profile

MSP430USCIA UART

MSP430 devices with a USCI module can support Serial communication in the USCI_A portion of the USCI.

Initialization

First, assign the device Rx and Tx pins to the USCI module:
P1SEL |= BIT1 + BIT2;//Rx on P1.1 and Tx on P1.2
P1SEL2 |= BIT1 + BIT2;
The BITx will depend on device. Check the Pin Functions table in the device datasheet.

Next, select the clock line for the USCI_A module. Here we use SMCLK, which is configured to be at the same frequency as MCLK.
UCA0CTL1 |= UCSSEL_2;

Now, set the baud rate. The family user guide has a table of UCA0BR values for different clock frequencies and baud rates.
//The baud rate prescaler is stored in UCBR0_setting
//The desired value for UCBRS0, also in the table, is in UCBRS0_setting
UCA0BR1 = (unsigned char)(UCBR0_setting >> 8); //Upper 8 bits
UCA0BR0 = (unsigned char)UCBR0_setting; //Lower 8 bits
UCA0MCTL = UCBRS0_setting << 1;

Finally, start the UART by clearing the USCIA reset bit, and enable the Rx interrupt
UCA0CTL1 &= ~UCSWRST;
IE2 |= UCA0RXIE;

Transmitting data

To send data, simply write the data to the UCA0TXBUF.
UCA0TXBUF = data;

Ensure that you do not write data to the buffer faster than the hardware can send the data. If you are facing this problem, create a queue for the data. The program can enqueue data, and the USCIAB0TX_vector should dequeue data whenever the buffer is not full. Ring buffers are easy to implement with limited memory on microcontrollers.

Receiving data

We previously enabled the UCA0RX interrupt, so whenever a full 8-bit character is received, the USCIAB0RX_VECTOR will be requested. Inside the ISR, read the UCA0RXBUF to get the data and clear the interrupt flag. It is also recommended to check if the interrupt was requested by the USCI_A or USCI_B module since they share the same interrupt vector.
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void){
if(IFG2 & UCA0RXIFG){
foo = UCA0RXBUF;
//Do stuff with foo
}
}