单片机
返回首页

[单片机框架][bsp层][nrf51822][nrf51422][nrf51802][bsp_uart] UART配置和使用

2022-09-06 来源:csdn

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

#include

#include


#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

#include


/* 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


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 如何构建一个触摸传感器电路

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章