UART —通用异步接收/发送器
功能描述
这里列出了UART的主要特性。
UART实现了对以下特性的支持:
全双工操作
自动流量控制
第9位数据位校验和生成
如图160所示:第531页的UART配置,UART直接使用TXD和RXD寄存器来发送和接收数据。 UART使用一个停止位。
引脚的配置
不同的信号RXD, CTS (Clear To Send, active low), RTS (Request To Send, active low)和TXD与UART相关联,分别根据PSELRXD, PSELCTS, PSELRTS和PSELTXD寄存器中指定的配置映射到物理引脚。
如果在这些寄存器中指定了0xFFFFFFFF值,则关联的UART信号将不会连接到任何物理引脚。 PSELRXD、PSELCTS、PSELRTS和PSELTXD寄存器及其配置仅在UART启用时使用,并且仅在设备处于ON模式时保留。 PSELRXD、PSELCTS、PSELRTS和PSELTXD只能在禁用UART的情况下配置。
当系统处于OFF模式时,为了确保UART在引脚上的正确信号电平,必须按照第531页引脚配置中的描述在GPIO外围设备中配置引脚。
一次只能指定一个外设来驱动特定的GPIO管脚。 不这样做可能会导致不可预测的行为。
表128:GPIO配置
共享资源
UART与与UART具有相同ID的其他外围设备共享寄存器和其他资源。 因此,在配置和使用UART之前,必须禁用与UART ID相同的所有外围设备。 禁用与UART具有相同ID的外设将不会重置与UART共享的任何寄存器。 因此,显式配置所有相关的UART寄存器以确保其正确操作非常重要。
有关外围设备及其id的详细信息,请参阅第24页Instantiation中的Instantiation表。
接收
通过触发STARTRX任务来启动UART接收序列。
UART接收器链实现了一个FIFO,能够在数据出现之前存储6个传入RXD字节覆盖。 字节是通过读取RXD寄存器从这个FIFO中提取的。 当一个字节被提取在FIFO中一个新的字节将被移动到RXD寄存器。 UART将生成每当一个新字节移动到RXD寄存器时,RXDRDY事件。
当流量控制启用时,UART将在只有4个空间时停用RTS信号更多的字节在接收器先进先出。 对应的发射机因此能够发送最多四个字节后在数据被覆盖之前,RTS信号被停用。 为了防止在FIFO中覆盖数据,对等的UART发送器必须因此确保停止传输数据在四个字节后RTS线路失效。
暂停UART
可以通过触发SUSPEND任务来挂起UART。 暂停会影响UART接收端和UART发送端,即发送端停止发送,接收端停止接收。 UART的发送和接收在暂停后可以通过触发STARTTX和STARTRX来恢复。
在SUSPEND任务之后,正在进行的TXD字节传输将在UART挂起之前完成。
当SUSPEND任务被触发时,UART接收器的行为与STOPRX任务被触发时的行为相同。
错误条件
如果在帧中没有检测到有效的停止位,将生成一个以帧错误形式出现的ERROR事件。 如果RXD线保持低电平的时间超过数据帧的长度,将生成另一个以中断条件形式出现的ERROR事件。 实际上,总是在中断条件发生之前生成帧错误。
使用没有流控制的UART
如果没有启用流量控制,接口将表现为CTS和RTS线路一直处于活动状态。
奇偶校验配置
当使能奇偶校验时,TXD和RXD的奇偶校验将自动生成用于发送和接收的奇偶校验。
/********************************************************************************
* @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" /* Private Define ------------------------------------------------------------*/ #include "business_gpio.h" #include "business_function.h" /* 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_460800 }; #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 BS_UART0_EN if (baud == 19200) { uart0_comm_params.baud_rate = NRF_UART_BAUDRATE_19200; } else if (baud == 115200) { uart0_comm_params.baud_rate = NRF_UART_BAUDRATE_115200; } else if (baud == 460800) { uart0_comm_params.baud_rate = NRF_UART_BAUDRATE_460800; } #endif } return; } /** * @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;
上一篇:[bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_rng] RNG随机数生成器配置和使用
下一篇:[nrf52832][nrf52840][nrf52810][nrf52820][bsp_pwm] PWM配置和使用
推荐阅读最新更新时间:2024-11-05 12:06
设计资源 培训 开发板 精华推荐
- LT4275BHDD IEEE 802.3at (Type 2) 25.5W 受电设备的典型应用电路
- 51单片机简易心形灯-3版
- 假颗粒,满足你的贴满梦想
- DC1017A,LT5558EUF 演示板,600 - 1100 MHz I-Q 调制器,具有 Hi-Z BB Rin,Vcm = 2.1V
- LT3091IR 低压差工作在非常低的输出电压下的典型应用
- 使用 Analog Devices 的 ADP3336 的参考设计
- LT8607IMSE 3.3V、2MHz 降压型稳压器的典型应用电路
- 【征集令】智慧加湿器
- DC2337A,基于 LT8315EFE 隔离式离线反激式的演示板,90VAC = VIN = 265VAC,VOUT = 12V @ 0.55A
- 太极创客arduboy迷你游戏机