目录
概述
本文主要介绍nRF52832 UART 寄存器操作方法,nRF52832 的 UART 外设采用 UARTE(UART with EasyDMA)架构,是传统 UART 的增强版,集成了 DMA 传输引擎和灵活的低功耗控制。
1 nRF52832 UART寄存器列表
nRF52832 的 UART 外设(UARTE: UART with EasyDMA)是其串行通信的核心,支持高效 DMA 传输和灵活配置。以下是关键寄存器及其功能的完整解析(以 UARTE0 为例,基地址 0x40002000
):
1.1 使能控制 (ENABLE
)
地址:
0x400020500
功能: 全局 UART 使能
位配置:
0: Disabled (复位状态) 4: Enabled // 必须设置为4才能工作
操作:
NRF_UARTE0->ENABLE = 4; // 启用UART
1.2 波特率设置 (BAUDRATE
)
地址:
0x40002524
常用值 (32-bit):
0x0004F000: 9600 baud 0x0009D000: 19200 baud 0x0013B000: 38400 baud 0x00275000: 57600 baud 0x004EA000: 115200 baud (默认) 0x009D5000: 230400 baud 0x01D20000: 921600 baud
示例:
NRF_UARTE0->BAUDRATE = 0x004EA000; // 115200 bps
1.3 配置寄存器 (CONFIG
)
地址:
0x4000256C
关键位域:
位域 名称 值 功能 [1:0]
HWFC
0 禁用硬件流控 1 仅使能RTS 2 仅使能CTS 3 使能RTS+CTS [4:2]
PARITY
0 无校验 1 偶校验 2 奇校验 [6:5]
STOP
0 1位停止位 1 2位停止位 - 配置示例 (8N1):
NRF_UARTE0->CONFIG = 0; // 无流控, 无校验, 1位停止位
1.4 引脚配置寄存器
引脚选择 (
PSEL
)
寄存器组:
寄存器 地址 功能 PSEL.RTS
0x40002508
RTS 引脚选择 PSEL.TXD
0x4000250C
TX 引脚选择 PSEL.CTS
0x40002510
CTS 引脚选择 PSEL.RXD
0x40002514
RX 引脚选择 - 操作 (配置 TX=P0.06, RX=P0.08):
NRF_UARTE0->PSEL.TXD = 6; NRF_UARTE0->PSEL.RXD = 8; NRF_UARTE0->PSEL.CTS = 0xFFFFFFFF; // 禁用CTS NRF_UARTE0->PSEL.RTS = 0xFFFFFFFF; // 禁用RTS
1.5 数据传输寄存器
1)发送控制 (TXD
)
PTR 寄存器 (
TXD.PTR
):
地址:
0x40002544
功能: 设置发送数据缓冲区地址 (DMA模式)
MAXCNT 寄存器 (
TXD.MAXCNT
):
地址:
0x40002548
功能: 设置发送数据长度
任务启动 (
TASKS_STARTTX
):
地址:
0x40002508
触发: 写入1启动发送
2) 接收控制 (RXD
)
PTR 寄存器 (
RXD.PTR
):
地址:
0x40002534
功能: 设置接收数据缓冲区地址
MAXCNT 寄存器 (
RXD.MAXCNT
):
地址:
0x40002538
功能: 设置接收缓冲区大小
任务启动 (
TASKS_STARTRX
):
地址:
0x40002500
触发: 写入1启动接收
1.6 状态与事件寄存器
1.6.1 事件寄存器 (EVENTS
)
事件 地址 触发条件 EVENTS_CTS
0x40002100
CTS 引脚状态变化 EVENTS_NCTS
0x40002104
CTS 引脚释放 EVENTS_RXDRDY
0x40002108
接收到数据 (每字节触发) EVENTS_ENDRX
0x40002110
完成DMA接收 (整个缓冲区) EVENTS_TXDRDY
0x4000211C
发送完成 (每字节) EVENTS_ENDTX
0x40002120
完成DMA发送 EVENTS_ERROR
0x40002124
帧/奇偶校验错误 EVENTS_RXTO
0x40002144
接收超时
事件清除:
NRF_UARTE0->EVENTS_RXDRDY = 0; // 写0清除事件
1.6.2 错误状态 (ERRORSRC
)
地址:
0x40002488
位掩码:
0x01: Overflow error // 溢出错误 0x02: Parity error // 奇偶校验错误 0x04: Framing error // 帧错误 0x08: Break error // 线路断开
错误清除:
NRF_UARTE0->ERRORSRC = NRF_UARTE0->ERRORSRC; // 读取即清除
1.7 中断控制
中断使能 (INTEN
)
地址:
0x40002300
关键中断位:
#define UARTE_INTEN_RXDRDY_Msk (1 << 2) // 接收中断 #define UARTE_INTEN_TXDRDY_Msk (1 << 7) // 发送中断 #define UARTE_INTEN_ERROR_Msk (1 << 9) // 错误中断 #define UARTE_INTEN_RXTO_Msk (1 << 17) // 超时中断
中断配置示例:
// 使能接收和错误中断 NRF_UARTE0->INTENSET = UARTE_INTEN_RXDRDY_Msk | UARTE_INTEN_ERROR_Msk;
2 数据传输范例
2.1 发送128字节数据 (DMA模式)
uint8_t tx_buffer[128] = {...};
void uart_dma_send(void) {
// 1. 配置DMA参数
NRF_UARTE0->TXD.PTR = (uint32_t)tx_buffer;
NRF_UARTE0->TXD.MAXCNT = sizeof(tx_buffer);
// 2. 启动发送
NRF_UARTE0->TASKS_STARTTX = 1;
// 3. 等待发送完成
while (NRF_UARTE0->EVENTS_ENDTX == 0);
NRF_UARTE0->EVENTS_ENDTX = 0;
}
2.2 接收数据 (带超时中断)
uint8_t rx_buffer[64];
volatile bool rx_complete = false;
void uart_init(void) {
// ... 引脚/波特率配置 ...
// 配置接收DMA
NRF_UARTE0->RXD.PTR = (uint32_t)rx_buffer;
NRF_UARTE0->RXD.MAXCNT = sizeof(rx_buffer);
// 使能中断
NRF_UARTE0->INTENSET = UARTE_INTEN_ENDRX_Msk | UARTE_INTEN_RXTO_Msk;
NVIC_EnableIRQ(UARTE0_UART0_IRQn);
// 启动接收
NRF_UARTE0->TASKS_STARTRX = 1;
}
void UARTE0_UART0_IRQHandler(void) {
if (NRF_UARTE0->EVENTS_ENDRX) {
NRF_UARTE0->EVENTS_ENDRX = 0;
rx_complete = true; // 标记接收完成
}
if (NRF_UARTE0->EVENTS_RXTO) {
// 处理接收超时
NRF_UARTE0->EVENTS_RXTO = 0;
}
}
3 低功耗优化技巧
3.1 操作方法
1)动态禁用UART
// 空闲时关闭UART
NRF_UARTE0->ENABLE = 0;
nrf_gpio_cfg_default(TX_PIN); // 避免引脚漏电
2)唤醒配置
// 配置RX引脚唤醒系统
nrf_gpio_cfg_sense_set(RX_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH);
3)DMA 代替轮询
-
使用
ENDRX/ENDTX
事件代替字节级中断 -
减少 CPU 唤醒次数
3.2 典型问题解决方案
问题现象 | 根因 | 修复方案 |
---|---|---|
DMA传输卡死 | 内存未32位对齐 | __ALIGN(4) uint8_t buffer[]; |
115200波特率偏差大 | HFCLK未启动 | nrf_clock_hfclk_request() |
休眠后功耗>10μA | 引脚未断开 | PSEL.RXD=0xFFFFFFFF |
偶发数据丢失 | 无硬件流控 + 长线缆 | 启用RTS/CTS + 串联终端电阻 |
唤醒后首字节丢失 | 时钟稳定延迟不足 | 唤醒后延迟1ms再初始化UART |
4 寄存器操作注意事项
4.1 操作方式
1)顺序依赖
// 正确顺序:
NRF_UARTE0->ENABLE = 0; // 先禁用
NRF_UARTE0->BAUDRATE = ...; // 修改配置
NRF_UARTE0->ENABLE = 4; // 重新使能
2) 状态检查
// 确保发送完成后再禁用
while (NRF_UARTE0->EVENTS_TXDRDY == 0);
3)引脚冲突解决
出现 ERRORSRC = 0x01
(溢出错误):
NRF_UARTE0->TASKS_FLUSHRX = 1; // 清空接收缓冲区
4.2 典型错误代码
错误现象 | 可能原因 | 解决方案 |
---|---|---|
无数据发送/接收 | ENABLE 寄存器未设置为4 | 检查使能状态 |
波特率不匹配 | 时钟源错误 (HFCLK未启动) | 启用高频时钟: NRF_CLOCK->TASKS_HFCLKSTART=1 |
DMA传输卡死 | 缓冲区未对齐到32位地址 | 使用 __ALIGN(4) 定义缓冲区 |
奇偶校验错误 | 配置与设备不匹配 | 检查双方 CONFIG.PARITY |
高功耗 (>1mA) | RX引脚浮空 | 配置上拉: nrf_gpio_cfg_input(RX_PIN, NRF_GPIO_PIN_PULLUP) |