Вот рабочий кусок кода (в нем используется RTOS SYS/BIOS, но идея остается той же и без RTOS)
/**
*
* @brief hwi_USCI_A0_Fxn
*
* @details Interrupt function UART 0(USCI_A0)
*
* RX - Put the char to the internal UART RX buf, if no room - overflow
* TX - Get char from the internal TX buf and put it to the UART TX register
* If TX buf is empty, disables TX interrupt and post the TX semaphore
*
* @param [in] arg The SYS/BYOS default parameter
*
* @pre May be used only like Interrupt Handler function for
* the UART 0(USCI_A0) hardware interrupt
*
*/
void hwi_USCI_A0_Fxn(UArg arg) //!< Int N 56
{
#if defined USE_UART_0
//!< UCRXIFG is automatically reset when UCAxRXBUF is read
//!< UCTXIFG is automatically reset if a character is written to UCxTXBUF
volatile int rx_val;
UART_ST * pdata = &p_uart_globals->g_uart0_data;
switch(__even_in_range(UCA0IV,4))
{
case 0:
break; //!< Vector 0 - no interrupt
case 2: //!< Vector 2 - RXIFG
rx_val = UCA0RXBUF; //!< read any case
if(UCA0STAT & (UCFE | UCOE | UCRXERR)) //!< if rx error
{
//!< do nothing here
}
else
{
//!< check 'fifo is full'
if((pdata->rx_head == pdata->rx_tail - 1) ||
(pdata->rx_head == pdata->rx_buf_size - 1 && pdata->rx_tail == 0))
{
//!< overflow
pdata->rx_buf[pdata->rx_head] = rx_val;
pdata->rx_head++;
if(pdata->rx_head >= pdata->rx_buf_size)
pdata->rx_head = 0;
pdata->rx_tail = pdata->rx_head + 1;
if(pdata->rx_tail >= pdata->rx_buf_size)
pdata->rx_tail = 0;
}
else //!< no overflow
{
pdata->rx_buf[pdata->rx_head] = rx_val;
pdata->rx_head++;
if(pdata->rx_head >= pdata->rx_buf_size)
pdata->rx_head = 0;
}
}
break;
case 4: //!< Vector 4 - TXIFG
if(pdata->tx_idx >= pdata->tx_cnt) //!< tx overall buf finished
{
UCA0IE &= ~UCTXIE;
pdata->tx_buf = NULL;
Semaphore_post(semTxUart0);
}
else
{
if(pdata->tx_buf)
UCA0TXBUF = pdata->tx_buf[pdata->tx_idx++]; //!< send char out UART transmitter
}
break;
default:
break;
}
#endif /* #if defined USE_UART_0 */
}