Skip to content

UART


1. Introduction

UART (Universal Asynchronous Transceiver and Transmitter) is a universal serial data bus for asynchronous communication; Full duplex transmission and reception can be realized.


2. Timing

2.1 Basic introduction

-The principle of UART is to transmit the binary bits of data bit by bit. In the UART communication protocol, the high level of the status bit on the signal line represents’ 1 ‘, and the low level represents’ 0’ -The hardware connection is relatively simple, only 3 lines are needed, TX, RX, GND -TX (sending data end, to be connected to RX of opposite equipment) -RX (receiving data end, to be connected to the TX of the opposite equipment) -Idle bit (when the bus is in idle state, the state of signal line is’ 1 ‘, that is, high level) -Start bit (a low level ‘0’ shall be sent to indicate the start of transmission characters when transmission starts) -Data bits (the starting bit is followed by the data to be transmitted, and the data is generally 8 bits. The lowest bit is sent first and the highest bit is sent last) -Parity check bit (parity check is required after data bit transmission) -Stop bit (data end flag, which can be 1-bit, 1.5 bit, 2-bit high level) -Baud rate (the time required to transmit a bit is (1/baud rate) seconds)

2.2 Sequence diagram analysis

  • (1) . Transmit 1 byte sequence diagram, start bit, 8-bit data and stop bit.

UARTę³¢å½¢å›¾

  • (2) Baud rate calculation. Find the width of 1-bit data to be sent. For example, as shown in the figure below, the time is 104 us

UARTę³¢å½¢å›¾

  • According to the calculation, 1/baud rate=104 us=1.04e-4 s (1.04 seconds to the minus fourth power), the baud rate is about 9600

3态API

Function name Description
UARTPollingConfig UART polling mode initialization configuration
UARTInterruptConfig UART interrupt mode initialization configuration
UARTDMAConfig UART DMA mode initialization configuration
UART_ IntMaskConfig UART interrupt mask setting
UART_ IntClear UART interrupt flag clear
UartPollingReceiveData Polling method receives a byte data
UartPollingSenddata The polling method sends a Byte data


4. Example

1) The following code configures UART0 polling mode, sends and receives data, and performs data comparison verification after sending and receiving;

#include "ci130x_uart.h"
void main(void)
{
//Initialize sending and receiving data array
int i;
unsigned char buf_ send[32] = {0x0};
unsigned char buf_ recv[32] = {0x0};
for(i = 0;i < 32;i++)
{
buf_ send[i] = i;
}
//Initialize UART0 (polling mode), baud rate 115200
UARTPollingConfig(UART0, UART_BaudRate115200);
//Sending data: one byte at a time
for(i=0;i<32;i++)
{
UartPollingSenddata(UART0,buf_send[i]);
}
//Receive data: receive one byte each time
for(i=0;i<32;i++)
{
buf_ recv[i] = UartPollingReceiveData(UART0);
}
//Compare whether the received and sent data are equal
for(i = 0;i < 32;i++)
{
if(buf_send[i] != buf_recv[i])
{
mprintf("Comparison of the Data Fail\n");
while(1);
}
}
mprintf("Comparison of the Data Successful\n");
while(1);
}

2) The following code configures UART0 interrupt mode and uses polling to send data, interrupts receiving data, and performs data comparison verification after receiving and transmitting;

#include "ci130x_uart.h"
unsigned char buf_ send[32] = {0x0};
unsigned char buf_ recv[32] = {0x0};

void pad_ config_ for_ uart(UART_TypeDef *UARTx)
{
if (UARTx == UART0)
{
dpmu_ set_ io_ reuse(PB5,SECOND_FUNCTION);
dpmu_ set_ io_ reuse(PB6,SECOND_FUNCTION);
#if 1
//If the external pull-up resistance reaches 5V
dpmu_ set_ io_ open_ drain(PB5,ENABLE);      // Configure pin leakage opening function, support external pull-up 5V
dpmu_ set_ io_ open_ drain(PB6,ENABLE);      // Configure pin leakage opening function, support external pull-up 5V
dpmu_ set_ io_ pull(PB5,DPMU_IO_PULL_DISABLE);   // Close pull-up
dpmu_ set_ io_ pull(PB6,DPMU_IO_PULL_DISABLE);   // Close pull-up
#else
//If there is no pull-up outside
dpmu_ set_ io_ pull(PB5,DPMU_IO_PULL_UP);   // Open pull-up
dpmu_ set_ io_ pull(PB6,DPMU_IO_PULL_UP);   // Open pull-up
#endif
}
else if (UARTx == UART1)
{
dpmu_ set_ io_ reuse(PB7,SECOND_FUNCTION);
dpmu_ set_ io_ reuse(PC0,SECOND_FUNCTION);
dpmu_ set_ io_ pull(PC0,DPMU_IO_PULL_UP);  // RX needs to open pull-up
}
else if (UARTx == UART2)
{
dpmu_ set_ io_ reuse(PB1,THIRD_FUNCTION);
dpmu_ set_ io_ reuse(PB2,THIRD_FUNCTION);
dpmu_ set_ io_ pull(PB2,DPMU_IO_PULL_UP);  // RX needs to open pull-up
}
}

void main(void)
{
int i = 0;
pad_ config_ for_ uart(UART0);
//Initialize UART0 (interrupt mode)
UARTInterruptConfig(UART0,UART_BaudRate115200);
//Initialize sending and receiving data array
for(i = 0;i < 32;i++)
{
buf_ send[i] = i;
}
//Sending data: one byte at a time
for(i=0;i<32;i++)
{
UartPollingSenddata(UART0,buf_send[i]);
}
//Compare whether the received and sent data are equal
for(i = 0;i < 32;i++)
{
if(buf_send[i] != buf_recv[i])
{
mprintf("Comparison of the Data Fail\n");
while(1);
}
}
mprintf("Comparison of the Data Successful\n");

while(1);
}
#include "ci130x_uart.h"
extern unsigned char buf_ recv[32];
int length = 0;
void UART0_ IRQHandler(void)
{
/*Sending data*/
if (UART0->UARTMIS & (1UL << UART_TXInt))
{
;
}
/*Accept Data*/
if (UART0->UARTMIS & (1UL << UART_RXInt))
{
//here FIFO DATA must be read out
buf_ recv[length] = UartPollingReceiveData(UART0);
length ++;
}
UART_ IntClear(UART0,UART_AllInt);
}

3) The following code configures UART0 DMA mode and uses DMA mode to send and receive data. After receiving and transmitting, perform data comparison verification;

#include "ci130x_uart.h"
#include "ci130x_dma.h"
unsigned char buf_ send[2048] = {0};
unsigned char buf_ recv[2048] = {0};

void pad_ config_ for_ uart(UART_TypeDef *UARTx)
{
if (UARTx == UART0)
{
dpmu_ set_ io_ reuse(PB5,SECOND_FUNCTION);
dpmu_ set_ io_ reuse(PB6,SECOND_FUNCTION);
#if UART_ PAD_ OPENDRAIN_ MODE_ EN
dpmu_ set_ io_ pull(PB5,DPMU_IO_PULL_DISABLE);  // RX close pull-up, use external pull-up
dpmu_ set_ io_ pull(PB6,DPMU_IO_PULL_DISABLE);  // RX close pull-up, use external pull-up
dpmu_ set_ io_ open_ drain(PB5);
#else
dpmu_ set_ io_ pull(PB6,DPMU_IO_PULL_UP);  // RX needs to open pull-up
#endif
}
else if (UARTx == UART1)
{
dpmu_ set_ io_ reuse(PB7,SECOND_FUNCTION);
dpmu_ set_ io_ reuse(PC0,SECOND_FUNCTION);
#if UART_ PAD_ OPENDRAIN_ MODE_ EN
dpmu_ set_ io_ pull(PB7,DPMU_IO_PULL_DISABLE);  // RX close pull-up, use external pull-up
dpmu_ set_ io_ pull(PC0,DPMU_IO_PULL_DISABLE);  // RX close pull-up, use external pull-up
dpmu_ set_ io_ open_ drain(PB7);
#else
dpmu_ set_ io_ pull(PC0,DPMU_IO_PULL_UP);  // RX needs to open pull-up
#endif
}
else if (UARTx == UART2)
{
dpmu_ set_ io_ reuse(PB1,THIRD_FUNCTION);
dpmu_ set_ io_ reuse(PB2,THIRD_FUNCTION);
#if UART_ PAD_ OPENDRAIN_ MODE_ EN
dpmu_ set_ io_ pull(PB1,DPMU_IO_PULL_DISABLE);  // RX close pull-up, use external pull-up
dpmu_ set_ io_ pull(PB2,DPMU_IO_PULL_DISABLE);  // RX close pull-up, use external pull-up
dpmu_ set_ io_ open_ drain(PB1);
#else
dpmu_ set_ io_ pull(PB2,DPMU_IO_PULL_UP);  // RX needs to open pull-up
#endif
}
}

void main(void)
{
    scu_set_dma_mode(DMAINT_SEL_CHANNELALL);

int i = 0;
pad_ config_ for_ uart(UART0);
//Initialize sending and receiving data array
for(i = 0;i < 2048;i++)
{
buf_ send[i] = i;
}

//Initialize UART0 (DMA mode)
UARTDMAConfig(UART0, UART_BaudRate115200);
//Configure DMA data transmission width
TRANSFERWIDTHx trans_ width = TRANSFERWIDTH_ 8b;
//DMA transmission data length (unit: Byte)
int bytesize = 2048;
//DMA receive data
DMAC_ M2P_ P2M_ advance_ config(DMACChannel0,
DMAC_ Peripherals_ UART0_ RX,
P2M_ DMA,
UART0_ DMA_ ADDR,
(unsigned int)buf_ recv,
bytesize,
trans_ width,
BURSTSIZE1,
DMAC_ AHBMaster1);
//DMA transmission data
DMAC_ M2P_ P2M_ advance_ config(DMACChannel1,
DMAC_ Peripherals_ UART0_ TX,
M2P_ DMA,
(unsigned int)buf_ send,
UART0_ DMA_ ADDR,
bytesize,
trans_ width,
BURSTSIZE1,
DMAC_ AHBMaster1);
//Wait for DMA Channel1 transmission to complete
if(RETURN_ERR == wait_dma_translate_flag(DMACChannel1,0xffffff))
{
mprintf("send dma irq err\n");
while(1);
}
//Wait for DMA Channel0 reception to complete
if(RETURN_ERR == wait_dma_translate_flag(DMACChannel0,0xffffff))
{
mprintf("recv dma irq err\n");
while(1);
}

//Compare whether the received and sent data are equal
for(i = 0;i < 2048;i++)
{
if(buf_send[i] != buf_recv[i])
{
mprintf("Comparison of the Data Fail\n");
while(1);
}
}
mprintf("Comparison of the Data Successful\n");

while(1);
}
#include "ci130x_uart.h"
#include "ci130x_dma.h"
void DMA_ IRQHandler(void)
{
int reg = DMAC->DMACIntTCStatus;
if (reg & (1 << DMACChannel0))
{
CALL_ CALLBACK(g_dma_channel0_callback);
}
if (reg & (1 << DMACChannel1))
{
CALL_ CALLBACK(g_dma_channel1_callback);
}
DMAC->DMACIntTCClear = reg;
}

5. Others

  • Common baud rate ranges are as follows

UARTx Baud rate: Bps
UART0 2400,4800,9600,19200
38400,57600,115200
230400,380400,460800
921600,1M,2M,3M
UART1 2400,4800,9600,19200
38400,57600,115200
230400,380400,460800
921600,1M,2M,3M
UART2 2400,4800,9600,19200
38400,57600,115200
230400,380400,460800
921600,1M,2M,3M