USART

简要说明

USART(Universal Synchronous Asynchronous Receiver/Transmitter)是一种同步或者异步的串行通信总线接口。当使用同步模式时,需要提供同步时钟,当使用异步模式(UART)的时候,不需要同步时钟,发送和接收方按照严格的格式(波特率和数据帧格式)发送和接收。

USART的特点:

  • 空闲时总线保持高电平状态
  • 5~9位数据位,低位在前
  • 一个起始位
  • 可选奇偶检验位
  • 可选0.5、1、1.5、2b比特的停止位

USART的传输时序描述如下:

接口描述

csi_usart_initialize

usart_handle_t csi_usart_initialize(int32_t idx, usart_event_cb_t cb_event)
  • 功能描述:

    • 通过设备号初始化对应的usart实例,返回usart实例句柄。
  • 参数:

    • idx: 设备号
    • cb_event:
    • usart实例的事件回调函数(一般在中断上下文执行)。回调函数原型定义见usart_event_cb_t。
  • 返回值:

    • NULL: 初始化失败。
    • 其它: 初始化成功时的实例句柄。

usart_event_cb_t:

typedef void (*usart_event_cb_t)(int32_t idx, usart_event_e event);

其中idx为设备号,event 为传给回调函数的事件类型。 usart 回调事件枚举类型usart_event_e定义如下:

USART_EVENT_SEND_COMPLETE 数据发送完成事件
USART_EVENT_RECEIVE_COMPLETE 数据接收完成事件
USART_EVENT_TRANSFER_COMPLETE 数据传输完成事件
USART_EVENT_TX_COMPLETE 数据发送完成事件
USART_EVENT_TX_UNDERFLOW 数据发送溢出事件
USART_EVENT_RX_OVERFLOW 数据接收溢出事件
USART_EVENT_RX_TIMEOUT 数据接收超时事件
USART_EVENT_RX_BREAK 数据接收中断事件
USART_EVENT_RX_FRAMING_ERROR 帧数据接收错误事件
USART_EVENT_RX_PARITY_ERROR 数据接收奇偶校验错误事件
USART_EVENT_CTS CTS状态已改变
USART_EVENT_DSR DSR状态已改变
USART_EVENT_DCD DCD状态已改变
USART_EVENT_RI RI状态已改变
USART_EVENT_RECEIVED 数据接收并存在USART FIFO,可调用receive等函数去读取

csi_usart_uninitialize

int32_t csi_usart_uninitialize(usart_handle_t handle)
  • 功能描述:

    • usart实例反初始化。该接口会停止usart
    • 实例正在进行的传输(如果有),并且释放相关的软硬件资源。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 错误码。

csi_usart_get_capabilities

usart_capabilities_t csi_usart_get_capabilities(int32_t idx)
  • 功能描述:

    • 获取usart实例支持的能力。
  • 参数:

    • idx: 设备号。
  • 返回值:

    • 描述usart能力的结构体。

csi_usart_send

int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
  • 功能描述:

    • usart启动数据发送。
  • 参数:

    • handle: 实例句柄。
    • data: 待发送数据的缓冲区地址。
    • num: 待发送数据的长度。
  • 返回值:*

    • 错误码。

csi_usart_abort_send

int32_t csi_usart_abort_send(usart_handle_t handle)
  • 功能描述:

    • usart数据发送终止。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 错误码。

csi_usart_receive

int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
  • 功能描述:

    • usart启动数据接收。
  • 参数:

    • handle: 实例句柄。
    • data: 待接收数据的缓冲区地址。
    • num: 待接收数据的长度。
  • 返回值:

    • 错误码。

csi_usart_receive_query

int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
  • 功能描述:

    • 查询方式从USART读取一定量数据。
  • 参数:

    • handle: 实例句柄。
    • data: 待接收数据的缓冲区地址。
    • num: 预计接收数据的长度。
  • 返回值:

    • 错误码。

csi_usart_abort_receive

int32_t csi_usart_abort_receive(usart_handle_t handle)
  • 功能描述:

    • usart数据接收终止。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 错误码。

csi_usart_transfer

int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
  • 功能描述:

    • usart启动数据传输,注意是同步传输。
  • 参数:

    • handle: 实例句柄。
    • data_out: 待发送数据的缓冲区地址。
    • data_in: 待接收数据的缓冲区地址。
    • num: 数据的长度。
  • 返回值:

    • 错误码。

csi_usart_abort_transfer

int32_t csi_usart_abort_transfer(usart_handle_t handle)
  • 功能描述:

    • usart数据传输终止。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 错误码。

csi_usart_get_status

usart_status_t csi_usart_get_status(usart_handle_t handle)
  • 功能描述:

    • 获取当前时刻usart的状态。
  • 参数:

    • handle`: 实例句柄。
  • 返回值:

    • usart状态的结构体。详见 usart_status_t定义。

usart_status_t:

名字 定义 备注
tx_busy: 1 数据发送忙
rx_busy: 1 数据接收忙
tx_underflow: 1 数据发送溢出
rx_overflow: 1 数据接收溢出
rx_break: 1 数据接收中断
rx_framing_error: 1 帧数据出错
rx_parity_error: 1 数据接收奇偶检验错误
tx_enable: 1 发送使能
rx_enable: 1 接收使能

csi_usart_flush

int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
  • 功能描述:

    • 清除usart数据缓存。
  • 参数:

    • handle: 实例句柄。
    • type: usart清除数据类型,参看
    • usart_flush_type_e 定义。
  • 返回值:

    • 错误码。

usart_flush_type_e:

名字 定义 备注
USART_FLUSH_WRITE 清除写缓存空间
USART_FLUSH_READ 清除读缓存空间

csi_usart_set_interrupt

int32_t csi_usart_set_interrupt(usart_handle_t handle, usart_intr_type_e type, int32_t flag)
  • 功能描述:

    • 开关USART的中断。
  • 参数:

    • handle: 实例句柄。
    • type: 中断类型。详见 usart_intr_type_e定义。
    • flag: 0:关;1:开。
  • 返回值:

    • 错误码。

usart_intr_type_e:

名字 定义 备注
USART_INTR_WRITE usart写中断
USART_INTR_READ usart读中断

csi_usart_config_baudrate

int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baud)
  • 功能描述:

    • 配置usart实例的波特率。
  • 参数:

    • handle: 实例句柄。
    • baud: 波特率。
  • 返回值:

    • 错误码。

csi_usart_config_mode

int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode)
  • 功能描述:

    • 配置usart实例的工作模式。
  • 参数:

    • handle: 实例句柄。
    • mode: usart的工作模式。详见 usart_mode_e 定义。
  • 返回值:

    • 错误码。

usart_mode_e:

名字 定义 备注
USART_MODE_ASYNCHRONOUS usart异步模式
USART_MODE_SYNCHRONOUS_MASTER usart同步全双工主模式
USART_MODE_SYNCHRONOUS_SLAVE usart同步全双工从模式
USART_MODE_SLAVE_WIRE usart半双工单线模式
USART_MODE_SINGLE_IRDA usart IRDA模式
USART_MODE_SINGLE_SMART_CARD usart智能卡模式

csi_usart_config_parity

int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity)
  • 功能描述:

    • 配置usart实例的奇偶校验模式。
  • 参数:

    • handle: 实例句柄。
    • parity: usart的奇偶校验,参看 usart_parity_e \
    • 的定义。
  • 返回值:

    • 错误码。

usart_parity_e:

名字 定义 备注
USART_PARITY_NONE 无奇偶检验
USART_PARITY_EVEN 偶校验
USART_PARITY_ODD 奇校验
USART_PARITY_1 校验位设置为1
USART_PARITY_0 检验位设置为0

csi_usart_config_stopbits

int32_t csi_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit)
  • 功能描述:

    • 配置usart实例的停止位模式。
  • 参数:

    • handle: 实例句柄。
    • stopbit: usart的停止位,参看
    • usart_stop_bits_e \<usart_stop_bits_e\ * 的定义。
  • 返回值:

    • 错误码。

usart_stop_bits_e:

名字 定义 备注
USART_STOP_BITS_1 1停止位
USART_STOP_BITS_2 2停止位
USART_STOP_BITS_1_5 1.5停止位
USART_STOP_BITS_0_5 0.5停止位

csi_usart_config_databits

int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits)
  • 功能描述:

  • 参数:

    • handle: 实例句柄。
    • databits: usart的数据位宽,参看
    • usart_data_bits_e \<usart_data_bits_e\ * 的定义。
  • 返回值:

    • 错误码。

usart_data_bits_e:

名字 定义 备注
USART_DATA_BITS_5 5位数据位宽
USART_DATA_BITS_6 6位数据位宽
USART_DATA_BITS_7 7位数据位宽
USART_DATA_BITS_8 8位数据位宽
USART_DATA_BITS_9 9位数据位宽

csi_usart_getchar

int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
  • 功能描述:

    • 从usart 读取一个字节。
  • 参数:

    • handle: 实例句柄。.
    • ch: 返回读取到的字节。
  • 返回值:

    • 错误码。

csi_usart_putchar

int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
  • 功能描述:

    • 从usart 发送一个字节。
  • 参数:

    • handle: 实例句柄。
    • ch: 需发送的字节内容。
  • 返回值:

    • 错误码。

csi_usart_get_tx_count

uint32_t csi_usart_get_tx_count(usart_handle_t handle)
  • 功能描述:

    • 获取设备实例上次已发送的数据个数。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 已发送的数据个数。

csi_usart_get_rx_count

uint32_t csi_usart_get_rx_count(usart_handle_t handle)
  • 功能描述:

    • 获取设备实例上一次已接收的数据个数。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 已接收的数据个数。

csi_usart_power_control

int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state)
  • 功能描述:

    • 配置设备实例的功耗模式。
  • 参数:

    • handle: 实例句柄。
    • state: 设备实例的功耗模式,参看
    • csi_power_stat_e \<csi_power_stat_e\ * 的定义。
  • 返回值:

    • 错误码。

csi_usart_config_flowctrl

int32_t csi_usart_config_flowctrl(usart_handle_t handle,
                                  usart_flowctrl_type_e flowctrl_type)
  • 功能描述:

    • 配置usart实例的流控。
  • 参数:

    • handle: 实例句柄。
    • flowctrl_type: 流控类型,参看
    • usart_flowctrl_type_e \<usart_flowctrl_type_e\ * 的定义。
  • 返回值:

    • 错误码。

usart_flowctrl_type_e:

名字 定义 备注
USART_FLOWCTRL_NONE 不带流控
USART_FLOWCTRL_CTS 支持CTS流控
USART_FLOWCTRL_RTS 支持RTS流控
USART_FLOWCTRL_CTS_RTS 同时支持CTS和RTS流控

csi_usart_config_clock

int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha)
  • 功能描述:

    • 配置usart实例的通信极性与相位。
  • 参数:

    • handle: 实例句柄。
    • cpol: usart的极性,参看 usart_cpol_e 的定义。
    • cpha: usart的相位,参看 usart_cpha_e 的定义。
  • 返回值:

    • 错误码。

usart_cpol_e:

名字 定义 备注
USART_CPOL0 数据在上升沿捕获
USART_CPOL1 数据在下降沿捕获

usart_cpha_e:

名字 定义 备注
USART_CPHA0 数据在第0个边沿采样
USART_CPHA1 数据在第1个边沿采样

csi_usart_control_tx

int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
  • 功能描述:

    • 控制usart实例的发送使能。
  • 参数:

    • handle: 实例句柄。
    • enable: 1 - 允许发送数据,0 - 不允许发送数据。
  • 返回值:

    • 错误码。

csi_usart_control_rx

int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
  • 功能描述:

    • 控制usart实例的接收使能。
  • 参数:

    • handle: 实例句柄。
    • enable: 1 - 允许接收数据,0 - 不允许接收数据。
  • 返回值:

    • 错误码。

csi_usart_control_break

int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
  • 功能描述:

    • 控制usart实例的break 帧发送。
  • 参数:

    • handle: 实例句柄。
    • enable: 1 - 开始发送break 帧, 0 - 停止发送break 帧。
  • 返回值:

    • 错误码。

使用例程

UART 可使用异步模式或同步模式进行收发数据

本示例,分别使用了异步模式和同步模式,具体如下:

#include "drv_usart.h"
#include "stdio.h"
#include "soc.h"
#include "pin.h"

#define CONFIG_TERMINAL_USART      1

static usart_handle_t g_usart_handle;
static volatile uint8_t rx_async_flag = 0;
static volatile uint8_t tx_async_flag = 0;
static volatile uint8_t rx_trigger_flag = 0;

uint8_t  data[18] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'
                    };

static int32_t usart_receive_sync(usart_handle_t usart, void *data, uint32_t num)
{
    int time_out = 0x7ffff;
    usart_status_t status;

    csi_usart_receive(usart, data, num);

    while (time_out) {
        time_out--;
        status = csi_usart_get_status(usart);

        if (!status.rx_busy) {
            break;
        }
    }

    if (0 == time_out) {
        return -1;
    }

    return 0;
}

static int32_t usart_send_sync(usart_handle_t usart, const void *data, uint32_t num)
{
    int time_out = 0x7ffff;
    usart_status_t status;

    csi_usart_send(usart, data, num);

    while (time_out) {
        time_out--;
        status = csi_usart_get_status(usart);

        if (!status.tx_busy) {
            break;
        }
    }

    if (0 == time_out) {
        return -1;
    }

    return 0;
}

static int32_t usart_receive_async(usart_handle_t usart, void *data, uint32_t num)
{
    int time_out = 0x7fffff;
    rx_async_flag = 0;

    csi_usart_receive(usart, data, num);

    while (time_out) {
        time_out--;

        if (rx_async_flag == 1) {
            break;
        }
    }

    if (0 == time_out) {
        return -1;
    }

    rx_async_flag = 0;
    return 0;
}

static int32_t usart_send_async(usart_handle_t usart, const void *data, uint32_t num)
{
    int time_out = 0x7ffff;
    tx_async_flag = 0;

    csi_usart_send(usart, data, num);

    while (time_out) {
        time_out--;

        if (tx_async_flag == 1) {
            break;
        }
    }

    if (0 == time_out) {
        return -1;
    }

    tx_async_flag = 0;
    return 0;
}

static void usart_event_cb(int32_t idx, uint32_t event)
{
    uint8_t g_data[15];

    switch (event) {
        case USART_EVENT_SEND_COMPLETE:
            tx_async_flag = 1;
            break;

        case USART_EVENT_RECEIVE_COMPLETE:
            rx_async_flag = 1;
            break;

        case USART_EVENT_RECEIVED:
            csi_usart_receive_query(g_usart_handle, g_data, 15);

        default:
            break;
    }
}

static void usart_event_cb_query(int32_t idx, uint32_t event)
{
    uint8_t g_data[15];
    uint8_t ret;

    switch (event) {
        case USART_EVENT_SEND_COMPLETE:
            tx_async_flag = 1;
            break;

        case USART_EVENT_RECEIVE_COMPLETE:
            rx_async_flag = 1;
            break;

        case USART_EVENT_RECEIVED:
            ret = csi_usart_receive_query(g_usart_handle, g_data, 15);
            csi_usart_send(g_usart_handle, g_data, ret);
            rx_trigger_flag = 1;
            break;

        default:
            break;
    }
}

static int32_t usart_wait_reply_async(usart_handle_t usart)
{
    volatile uint32_t i;
    uint8_t ch;
    char answer[20];

    for (i = 0; i < 20; i++) {
        answer[i] = '\0';
    }

    i = 0;

    while (i < 20) {
        if (0 == usart_receive_async(usart, &ch, 1)) {
            if (ch == '\n' || ch == '\r') {
                answer[i] = '\0';
                break;
            }

            if (ch == 127 || ch == '\b') {
                if (i > 0) {
                    i--;
                    usart_send_async(usart, &ch, 1);
                }
            } else {
                answer[i++] = ch;
                usart_send_async(usart, &ch, 1);
            }
        }
    }

    if ((i == 1) && (answer[0] == 'y')) {
        return 1;
    } else if ((i == 1) && (answer[0] == 'n')) {
        return 0;
    }

    return 2;
}

static int32_t usart_wait_reply(usart_handle_t usart)
{
    volatile uint32_t i;
    uint8_t ch;
    char answer[20];

    for (i = 0; i < 20; i++) {
        answer[i] = '\0';
    }

    i = 0;

    while (i < 20) {
        if (0 == usart_receive_sync(usart, &ch, 1)) {
            if (ch == '\n' || ch == '\r') {

                answer[i] = '\0';
                break;
            }

            if (ch == 127 || ch == '\b') {
                if (i > 0) {
                    i--;
                    usart_send_sync(usart, &ch, 1);
                }
            } else {
                answer[i++] = ch;
                usart_send_sync(usart, &ch, 1);
            }
        }
    }

    if ((i == 1) && (answer[0] == 'y')) {
        return 1;
    } else if ((i == 1) && (answer[0] == 'n')) {
        return 0;
    }

    return 2;
}

static int32_t usart_test_async_mode(usart_handle_t usart, int32_t uart_idx)
{
    uint32_t get;
    int32_t  ret;

    ///////////////////* async mode ///////////////////////
    /* Insure prompt information is displayed */
    /* Changes usart mode to interrupt mode */
    csi_usart_uninitialize(usart);
    usart = csi_usart_initialize(uart_idx, (usart_event_cb_t)usart_event_cb);

    if (usart == NULL) {
        return -1;
    }

    g_usart_handle = usart;
    ret = csi_usart_config(usart, 115200, USART_MODE_ASYNCHRONOUS, USART_PARITY_NONE, USART_STOP_BITS_1, USART_DATA_BITS_8);

    if (ret < 0) {
        printf("csi_usart_config error %x\n", ret);
        return -1;
    }

    printf("\r\t(async mode ): Output is---\n\t\t");
    usart_send_async(usart, data, sizeof(data));
    printf("- - - [y/n] ");

    while (1) {
        /* wait for the input*/
        get = usart_wait_reply_async(usart);

        if ((get == 1) || (get == 0)) {
            break;
        } else {
            printf("\n\tPlease enter 'y' or 'n'   ");
        }
    }

    if (get == 1) {
        printf("\t- - -PASS\n");
    } else {
        printf("\t- - -FAILURE\n");
        return -1;
    }

    return 0;
}

static int32_t usart_test_sync_mode(usart_handle_t usart)
{
    uint32_t get;

///////////////////* sync mode *//////////////////////////
    printf("\n\n\t- - - Testing usart mode...\n");
    printf("\r\t(sync mode ): Output is---\n\t\t");

    usart_send_sync(usart, data, sizeof(data));

    printf("- - - [y/n] ");

    /* wait for the input*/
    while (1) {
        get = usart_wait_reply(usart);

        if ((get == 1) || (get == 0)) {
            break;
        } else {
            printf("\n\tPlease enter 'y' or 'n'   ");
        }
    }

    if (get == 1) {
        printf("\t- - -PASS\n");
    } else {
        printf("\t- - -FAILURE\n");
        return -1;
    }

    return 0;
}

int _usart_test(usart_handle_t usart, int32_t uart_idx)
{
    uint32_t get;
    //char input_char1,input_char2;
    int32_t ret;

    ret = usart_test_sync_mode(usart);

    if (ret < 0) {
        printf("usart_test_sync_mode error %x\n", ret);
        return -1;
    }

    /* test async mode */
    ret = usart_test_async_mode(usart, uart_idx);

    if (ret < 0) {
        printf("usart_test_async_mode error %x\n", ret);
        return -1;
    }

    return 0;
}

void example_pin_usart_init(void)
{
    drv_pinmux_config(EXAMPLE_PIN_USART_TX, EXAMPLE_PIN_USART_TX_FUNC);
    drv_pinmux_config(EXAMPLE_PIN_USART_RX, EXAMPLE_PIN_USART_RX_FUNC);
}

int test_usart(int32_t uart_idx)
{
    usart_handle_t p_csi_usart;
    int32_t ret;

    /* init the USART*/
    p_csi_usart = csi_usart_initialize(uart_idx, NULL);

    if (p_csi_usart == NULL) {
        printf("csi_usart_initialize error\n");
        return -1;
    }

    example_pin_usart_init();

    /* config the USART */
    ret = csi_usart_config(p_csi_usart, 115200, USART_MODE_ASYNCHRONOUS, USART_PARITY_NONE, USART_STOP_BITS_1, USART_DATA_BITS_8);

    if (ret < 0) {
        printf("csi_usart_config error %x\n", ret);
        return -1;
    }

    ret = _usart_test(p_csi_usart, uart_idx);

    if (ret < 0) {
        printf("_usart_test error %x\n", ret);
        return -1;
    }

    printf("test_usart OK\n");

    return 0;
}


int example_usart(void)
{
    int ret;
    ret = test_usart(EXAMPLE_USART_IDX);

    if (ret < 0) {
        printf("test_usart failed\n");
        return -1;
    }

    return 0;
}

int main(void)
{
    return example_usart();
}

results matching ""

    No results matching ""