打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Universal Asynchronous Receiver/Transmitter (UART)

The Universal Asynchronous Receiver/Transmitter offers fast, full-duplex, asynchronous serial communication with built-in flow control (CTS, RTS) support in hardware up to 1 Mbps baud. Parity checking is supported.

The GPIOs used for each UART interface line can be chosen from any GPIO on the device and are independently configurable. This enables great flexibility in device pinout and efficient use of board space and signal routing.

通用异步接收/发送器提供快速,全双工,内置流控制(CTS, RTS)的异步串行通信硬件支持高达1mbps波特率。 支持奇偶校验。

用于每个UART接口线的GPIO可以从设备上的任何GPIO中选择,并且是独立配置的。 这使得设备引脚具有很大的灵活性,并能有效地利用板空间和信号路由。

/********************************************************************************
* @file    bsp_uart.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-13
* @brief   uart驱动
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

#include "RTE_Components.h"
#include CMSIS_device_header
#include "nrf_uart.h"
#include "app_uart.h"

#include "bsp_gpio.h"
#include "bsp_uart.h"

#include "boards.h"

#include "business_gpio.h"
#include "business_function.h"
/* Private Define ------------------------------------------------------------*/
/* External Variables --------------------------------------------------------*/
/* Private Typedef -----------------------------------------------------------*/
typedef void(*bsp_uart_callback)(void);
/* Private Variables ---------------------------------------------------------*/
#if BS_UART0_EN
#define BSP_UART0_IRQ_HANDLER                    uart0_event_handle
// 定义串口缓存区
uint8_t bsp_uart0_tx_buff[BS_UART0_CACHE_SIZE] = {0};
uint8_t bsp_uart0_rx_buff[BS_UART0_CACHE_SIZE] = {0};
// 定义串口初始化标记位 0--未初始化 1--初始化完成
bool g_uart0_init                              = false;
// 定义串口发送标记位 0--free闲  1--bus忙
bool g_uart0_send_lock                         = false;
uint16_t bsp_uart0_rx_buff_position = 0;

static bsp_uart_callback uart0_irq_rx_callback;

// 定义串口信息初始化结构体
static app_uart_comm_params_t uart0_comm_params =
{
    .rx_pin_no    = BS_UART0_RX_PIN,
    .tx_pin_no    = BS_UART0_TX_PIN,
    .rts_pin_no   = RTS_PIN_NUMBER,
    .cts_pin_no   = CTS_PIN_NUMBER,
    .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
    .use_parity   = false,
    .baud_rate    = NRF_UART_BAUDRATE_115200
};
#endif

/* Private Function Prototypes -----------------------------------------------*/
/**
 * @brief  Rx Transfer completed callbacks.
 * @note   NULL
 * @param  p_event: Struct containing events from the UART module.
 * @retval None
 */
static void BSP_UART0_IRQ_HANDLER(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_DATA_READY)
    {
        app_uart_get(&bsp_uart0_rx_buff[bsp_uart0_rx_buff_position]);
        if (bsp_uart0_rx_buff_position < (BS_UART0_CACHE_SIZE - 1))
        {
            bsp_uart0_rx_buff_position++;
        }
        if (uart0_irq_rx_callback)
        {
            uart0_irq_rx_callback();
        }
    }
}

/* Public Function Prototypes ------------------------------------------------*/
/**
 * @brief  设置串口波特率
 * @note   NULL
 * @param  uart: 串口组号
 * @param  baud: 波特率
 * @retval None
 */
void biz_uart_set_baud_rate(bsp_uart_t uart, uint32_t baud)
{
    if (uart == BSP_UART_0)
    {
    	if (baud == 115200)
    	{
    		uart0_comm_params.baud_rate = NRF_UART_BAUDRATE_115200;
    	}
    	else if (baud == 19200)
    	{
    		uart0_comm_params.baud_rate = NRF_UART_BAUDRATE_19200;
    	}
    }
}

/**
 * @brief  串口初始化
 * @note   None
 * @param  uart: 串口组号
 * @retval None
 */
void bsp_uart_init(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (g_uart0_init)
        {
            return;
        }
        uint32_t err_code;
        APP_UART_FIFO_INIT(&uart0_comm_params,
                           BS_UART0_CACHE_SIZE,
                           BS_UART0_CACHE_SIZE,
                           uart0_event_handle,
                           APP_IRQ_PRIORITY_LOWEST,
                           err_code);
        APP_ERROR_CHECK(err_code);
        bsp_uart0_rx_buff_position = 0;
        g_uart0_init = true;
#endif
    }
}

/**
 * @brief  串口反注册 关闭串口时钟并复位引脚
 * @note   NULL
 * @param  uart: 串口组号
 * @retval None
 */
void bsp_uart_deinit(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (!g_uart0_init)
        {
            return;
        }
        app_uart_close();
        g_uart0_init = false;
#endif
    }
}

/**
 * @brief  注册串口接收回调函数
 * @note   NULL
 * @param  uart: 串口组号
 * @param  event: 事件回调函数
 * @retval 0--失败 1--成功
 */
bool bsp_uart_rx_irq_callback(bsp_uart_t uart, void *event)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (uart0_irq_rx_callback != NULL)
        {
            return true;
        }
        else
        {
            uart0_irq_rx_callback = (bsp_uart_callback)event;
        }
#endif
    }

    return false;
}

/************************************[uart] 使用函数************************************/
/**
 * @brief  发送一个字节
 * @note   NULL
 * @param  uart: 串口组号
 * @param  data: 字节值
 * @retval None
 */
void bsp_uart_send_byte(bsp_uart_t uart, uint8_t data)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (!g_uart0_init)
        {
            return;
        }
        app_uart_put(data);
#endif
    }
    return;
}

/**
 * @brief  发送多个字节(堵塞)
 * @note   NULL
 * @param  uart: 串口组号
 * @param  *data: 数据头指针
 * @param  len: 数据长度
 * @retval None
 */
void bsp_uart_send_nbyte(bsp_uart_t uart, uint8_t *data, uint16_t len)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (!g_uart0_init)
        {
            return;
        }
        if (g_uart0_send_lock)
        {
            return;
        }
        g_uart0_send_lock = true;
        if (data != NULL)
        {
            for (uint16_t i = 0; i < len; i++)
            {
                app_uart_put(data[i]);
            }
        }
        else
        {
            for (uint16_t i = 0; i < len; i++)
            {
                app_uart_put(bsp_uart0_tx_buff[i]);
            }
        }
        g_uart0_send_lock = false;
#endif
    }
    return;
}

/**
 * @brief  发送多个字节(非堵塞) 一般DMA方式
 * @note   NULL
 * @param  uart: 串口组号
 * @param  *data: 数据头指针
 * @param  len: 数据长度
 * @retval None
 */
void bsp_uart_send_nbyte_nowait(bsp_uart_t uart, uint8_t *data, uint16_t len)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        bsp_uart_send_nbyte(uart, data, len);
#endif
    }
    return;
}

/**
 * @brief  得到txbuff头指针
 * @note   NULL
 * @param  uart: 串口组号
 * @retval None
 */
uint8_t *bsp_uart_get_txbuff(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (g_uart0_send_lock == false)
        {
            return bsp_uart0_tx_buff;
        }
        return NULL;
#endif
    }
    return NULL;
}

/**
 * @brief  得到rxbuff头指针
 * @note   NULL
 * @param  uart: 串口组号
 * @retval None
 */
uint8_t *bsp_uart_get_rxbuff(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        return bsp_uart0_rx_buff;
#endif
    }
    return NULL;
}

/**
 * @brief  [串口信息] 返回串口缓存指针位置,即当前缓存数量(byte)
 * @note   NULL
 * @param  uart: 串口号
 * @retval 串口缓存指针位置
 */
uint16_t bsp_uart_get_rxbuff_position(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        return bsp_uart0_rx_buff_position;
#endif
    }
    return NULL;
}

/**
 * @brief  得到rxbuff大小
 * @note   NULL
 * @param  uart: 串口组号
 * @retval 字节大小
 */
uint16_t bsp_uart_get_rxbuff_size(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        return BS_UART0_CACHE_SIZE;
#endif
    }
    return 0;
}

/**
 * @brief  [串口操作] 关闭串口接收:关闭串口中断,终止接收中断回调
 * @note   由于无DMA,只能先关闭,再处理数据,防止数据错乱。然后重新读取。
 * @param  uart: 串口号
 * @retval None
 */
void bsp_uart_rx_close(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        if (!g_uart0_init)
        {
            return;
        }
        app_uart_close();
#endif
    }
    return;
}

/**
 * @brief  [串口操作] 打开串口接收:打开串口中断,设置接收中断回调
 * @note   由于无DMA,只能先关闭,再处理数据,防止数据错乱。然后重新读取。
 * @param  uart: 串口号
 * @retval None
 */
void bsp_uart_rx_open(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        bsp_uart_init(uart);
#endif
    }
    return;
}

/**
 * @brief  [串口操作] 复位接收缓存指针
 * @note   NULL
 * @param  uart: 串口号
 * @retval None
 */
void bsp_uart_reset_rxbuff(bsp_uart_t uart)
{
    if (uart == BSP_UART_0)
    {
#if BS_UART0_EN
        bsp_uart0_rx_buff_position = 0;
#endif
    }
    return;
}

/********************************************************************************
* @file    bsp_uart.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-13
* @brief   NULL
********************************************************************************/

#ifndef __BSP_UART_H
#define __BSP_UART_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

/* Public enum ---------------------------------------------------------------*/
typedef enum
{
    BSP_UART_0 = 0,
    BSP_UART_1 = 1,
    BSP_UART_2 = 2,
} bsp_uart_t;

/* Public Function Prototypes ------------------------------------------------*/

// uart基础功能

void bsp_uart_init(bsp_uart_t uart);
void bsp_uart_deinit(bsp_uart_t uart);
void biz_uart_set_baud_rate(bsp_uart_t uart, uint32_t baud);

void bsp_uart_rx_close(bsp_uart_t uart);
void bsp_uart_rx_open(bsp_uart_t uart);

bool bsp_uart_rx_irq_callback(bsp_uart_t uart, void *event);

// uart发送函数

void bsp_uart_send_byte(bsp_uart_t uart, uint8_t data);
void bsp_uart_send_nbyte(bsp_uart_t uart, uint8_t *data, uint16_t len);
void bsp_uart_send_nbyte_nowait(bsp_uart_t uart, uint8_t *data, uint16_t len);

// 获得tx/rx缓冲区首指针

uint8_t *bsp_uart_get_txbuff(bsp_uart_t uart);
uint8_t *bsp_uart_get_rxbuff(bsp_uart_t uart);

uint16_t bsp_uart_get_rxbuff_position(bsp_uart_t uart);
void bsp_uart_set_rxbuff_position(bsp_uart_t uart, uint16_t val);
void bsp_uart_add_rxbuff_position(bsp_uart_t uart);

uint16_t bsp_uart_get_rxbuff_size(bsp_uart_t uart);
void bsp_uart_reset_rxbuff(bsp_uart_t uart);

#endif

posted on 2022-08-13 11:00  xuejianqiang  阅读(50)  评论(0编辑  收藏  举报
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033