There are 2 programs in total
Program 1 sends:
#include <msp430x42x.h>
#define TXBUF_SIZE 32 /*Maximum capacity of transmit FIFO*/
unsigned char TX_BUFF[TXBUF_SIZE]; /*Transmit FIFO buffer array*/
unsigned int UART_OutLen=0; /*Number of bytes to be sent in transmit FIFO*/
unsigned int TX_IndexR=0; /*Read pointer in transmit FIFO*/
unsigned int TX_IndexW=0; /*Write pointer in transmit FIFO*/
/*****************************************************************
* Name: UART0_PutChar()
* Function: Send 1 byte of data from the serial port (fill 1 byte of data to be sent into the buffer queue)
* Input parameter: Chr: byte to be sent
* Output parameter: Return 1 for successful transmission,
return 0 for failure.
* Description: During the sending process, the CPU operation is not blocked
******************************************************************/
char UART0_PutChar(unsigned char Chr)
{
if(UART_OutLen == TXBUF_SIZE) //If FIFO is full
{
return (0); //Do not send data, return the sending failure flag
}
if(UART_OutLen==0) //If it is the first byte
{
IFG1|=UTXIFG0; //Artificially create the first interrupt condition
}
_DINT(); //Interrupts are not allowed when FIFO operations are involved to avoid data confusionUART_OutLen
++; //The number of bytes to be sent is increased by 1
TX_BUFF[TX_IndexW] = Chr; //The data to be sent is written to FIFO through the write pointer
if (++TX_IndexW >= TXBUF_SIZE)//The write pointer is incremented, and it is determined whether the subscript is out of bounds
{
TX_IndexW = 0; // If it is out of bounds, the write pointer is reset to zero (circular queue)
}
IE1 |= UTXIE0; // Enable UART0's send interrupt, and send data in sequence in the interrupt_EINT
(); // FIFO operation is completed, restore interrupt enable
return (1); // Return the send success flag
}
#pragma vector=UART0TX_VECTOR
__interrupt void UART_TX (void) //Serial port send interrupt
{
if(UART_OutLen>0) //Is there data to be sent in the FIFO?
{
UART_OutLen--; // The number of data bytes to be sent is reduced by 1
U0TXBUF=TX_BUFF[TX_IndexR]; // Read a byte from the tail pointer and send it
if (++TX_IndexR >= TXBUF_SIZE)// The read pointer is incremented, and it is determined whether the index is out of bounds
{
TX_IndexR = 0; // If it is out of bounds, the write pointer is reset to zero (circular queue)
}
}
else IE1 &=~ UTXIE0; // If the data has been sent, turn off the UART0 send interrupt and stop sending
}
/*********************************************************************
* Name: UART0_PutChar_Legacy()
* Function: Traditional program for sending 1 byte of data from the serial port, for comparison
* Input parameter: Chr: byte to be sent
* Description: During the sending process, the CPU will be blocked
*****************************************************************/
void UART0_PutChar_Legacy(char Chr)
{
TXBUF0=Chr;
while ((IFG1 & UTXIFG0)==0); // Wait for the byte to be sent
}
void main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
FLL_CTL0 |= XCAP18PF; // Configure crystal load capacitance
U0CTL = CHAR; // Asynchronous communication mode, 8-bit data, no parity, 1 stop bit.
ME1 |= UTXE0 + URXE0; // Enable serial port 0 transceiver module
U0TCTL |= SSEL0; // Select ACLK as the serial port baud rate clock source.
U0BR1 = 0; //
U0BR0 = 13; // Integer part of the frequency division coefficient = 13
U0MCTL = 0x6B; // Modulation of the fractional part of the frequency division coefficient = 5/8. (2400bps)
P2SEL |= BIT4 + BIT5; // P2.4,5 enable the second function as the serial port transceiver pin (different for different MCUs)
_EINT(); // General interrupt enable
while(1)
{
TACTL = TASSEL_2 + MC_2 + TAIE + TACLR; // Use TA to measure the time required for the traditional sending program
UART0_PutChar_Legacy(0x01);
UART0_PutChar_Legacy(0x02);
UART0_PutChar_Legacy(0x03);
UART0_PutChar_Legacy(0x04);
UART0_PutChar_Legacy(0x05); // Test, send 8 bytes of data
UART0_PutChar_Legacy(0x06);
UART0_PutChar_Legacy(0x07);
UART0_PutChar_Legacy(0x08);
TACTL = TASSEL_2 + MC_0; // TA stops timing
_NOP(); // Set a breakpoint in this sentence to view the TAR value (29652 cycles)
__delay_cycles(1000000);
TACTL = TASSEL_2 + MC_2 + TAIE + TACLR; // Use TA to measure the time required for the sending program with FIFO
UART0_PutChar(0x01);
UART0_PutChar(0x02);
UART0_PutChar(0x03);
UART0_PutChar(0x04);
UART0_PutChar(0x05); // Test, send 8 bytes of data
UART0_PutChar(0x06);
UART0_PutChar(0x07);
UART0_PutChar(0x08);
TACTL = TASSEL_2 + MC_0; // TA stops timing
_NOP(); // Set a breakpoint in this sentence to view the TAR value (440 cycles)
__delay_cycles(1000000); // Send about once a second
}
}
Copy code
Program 2 accepts:
#include <msp430x42x.h>
#define RXBUF_SIZE 32 /*maximum capacity of receive FIFO*/
unsigned char RX_BUFF[RXBUF_SIZE]; /*receive FIFO buffer array*/
unsigned int UART_InpLen=0; /*number of bytes to be read in receive FIFO*/
unsigned int RX_IndexR=0; /*read pointer of receive FIFO*/
unsigned int RX_IndexW=0; /*write pointer of receive FIFO*/
/*****************************************************************
* Name: UART0_GetChar()
* Function: Read 1 byte of data from the serial port (read 1 byte of received data from the buffer queue)
* Input parameter: *Chr: address pointer where the read data is stored
* Output parameter: Return 1 for successful reading and return 0 for failed reading.
* Description: During the reading process, the CPU operation is not blocked
******************************************************************/
char UART0_GetChar(unsigned char *Chr)
{
if(UART_InpLen==0) return(0); // If there is no data in the FIFO, return 0
_DINT(); // Interrupts are not allowed when FIFO operations are involved to avoid pointer confusion
UART_InpLen--; // The number of bytes of data to be read is reduced by 1
*Chr=RX_BUFF[RX_IndexR]; // Read a byte from the tail pointer as the return value
if (++RX_IndexR >= RXBUF_SIZE) // The read pointer is incremented and determines whether the index is out of bounds
{
RX_IndexR = 0; // If it is out of bounds, the write pointer is reset to zero (circular queue)
}
_EINT(); // FIFO operation is completed and interrupts are restored
return (1); // Return the send success flag
}
/********************************************************************
* Name: UART0_GetCharsInRxBuf()
* Function: Get the number of data bytes received in FIFO
* Input parameter: None
* Output parameter: Number of bytes to be read
******************************************************************/
unsigned int UART0_GetCharsInRxBuf()
{
return (UART_InpLen); // Returns the number of data bytes in FIFO
}
/*********************************************************************
* Name: UART0_ClrRxBuf()
* Function: Clear the receive FIFO area
* Input parameter: None
* Output parameter: None
******************************************************************/
void UART0_ClrRxBuf()
{
_DINT(); // Interrupts are not allowed when FIFO operations are involved to avoid pointer confusion
UART_InpLen=0; // Received data clear
RX_IndexR=0;
RX_IndexW=0; // Head and tail pointer reset
_EINT();
}
#pragma vector=UART0RX_VECTOR
__interrupt void UART0_RX (void) // Serial port receive interrupt
{
UART_InpLen++; // Receive byte count plus 1
RX_BUFF[RX_IndexW] =U0RXBUF; // Serial port receive data is written to FIFO through the write pointer
if (++RX_IndexW >= RXBUF_SIZE) // Write pointer increments and determines whether the index is out of bounds
{
RX_IndexW = 0; // If out of bounds, the write pointer is reset to zero (circular queue)
}
}
void main( void )
{
unsigned char RxDataBuff[8];
unsigned char Addr;
unsigned char Func;
int i;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
FLL_CTL0 |= XCAP18PF; // Configure crystal load capacitance
U0CTL = CHAR; // Asynchronous communication mode, 8-bit data, no parity, 1 stop bit.
ME1 |= UTXE0 + URXE0; // Enable serial port 0 transceiver module
U0TCTL |= SSEL0; // Select ACLK as the serial port baud rate clock source.
U0BR1 = 0; //
U0BR0 = 13; // Integer part of the frequency division coefficient = 13
U0MCTL = 0x6B; // Fractional part of the frequency division coefficient modulation = 5/8. (2400bps)
P2SEL |= BIT4 + BIT5; // P2.4,5 turn on the second function as the serial port receiving and transmitting pins (different for different MCUs)
IE1 |= URXIE0; // Turn on the receive interrupt of UART0 and receive data in the interrupt_EINT
(); // Total interrupts allowedwhile
(1)
{
__delay_cycles(1000000);//Simulate a long and time-consuming program so that the CPU cannot read the serial port temporarilyif
(UART0_GetCharsInRxBuf()>=10) //Every time 10 bytes of data are received
{
UART0_GetChar(&Addr); //Read the first byteUART0_GetChar
(&Func); //Read the second bytefor
(i=0;i<8;i++) UART0_GetChar(RxDataBuff+i); //Read the next 8 bytes in sequence
}
}
}
|