一、说明
agx orin模组拥有7个常规UART(通用异步接收机/发射机)控制器,分别是UART1/UARTA、UART2/UARTB、UART3/UARTC、UART4/UARTD、UART5/UARTE、UART6/UARTF、UART8/UARTH。
agx orin模组拥有3个特殊UART(SBSA),它是ARM服务器基础架构(SBSA)定义的通用UART。
1.1 普通UART和SBSA UART区别
| 类型 | SBSA UART | 普通 UART |
|---|---|---|
| 寄存器 | 使用 PL011 寄存器的子集 | 通常有完整的 UART 寄存器组,不同芯片具体寄存器可能不同,但功能相对完整 |
| 波特率调整 | 波特率由固件设置,运行时无法修改,缺乏时钟指定器 | 一般可在运行时通过相关寄存器设置波特率,只要通信双方波特率一致即可正常通信 |
| DMA 支持 | 不支持 DMA(直接内存访问) | 部分普通 UART 支持 DMA 功能,可提高数据传输效率,减轻 CPU 负担 |
| 调制解调器控制信号 | 不支持调制解调器控制信号 | 一些 UART 芯片具备调制解调器控制信号相关引脚和功能,如 RTS、CTS 等,可用于流控等 |
| 兼容性 | 兼容属性必须为 “arm,sbsa - uart” | 无此特定兼容属性要求,根据不同芯片和应用场景,有不同的驱动和配置方式 |
1.2 关于UART最大的波特率设置
普通的UART波特率在系统软件层面最大支持4Mbps,使用stty软件或termios的函数配置串口波特率会有4Mbps的限制,busybox软件中stty应用也有4Mbps的限制,在/usr/include/asm-generic/termbits.h头文件有定义。
SBSA UART最大可以支持12Mbps的波特率,参考Orin-TRM_DP10508002_v1.0p.pdf文档如下:

UART的波特率大小主要和控制器的时钟频率有关,agx orin模组每个UART控制器时钟可以通过如下命令查看:
cat /sys/kernel/debug/bpmp/debug/clk/uart<x>/max_rate
其中<x>表示a、b、c、d、f、h、i、j

每个UART控制器实际支持的最大波特率计算方式:UART时钟频率/16。例如UARTA的时钟是68MHZ,则其支持最大的波特率是68MHZ/16=4.25Mbps。而如果需要更高的波特率,需要选择UARTI,UARTI支持最大的波特率是204MHZ/16=12.75Mbps。更高的串口波特率,需要开启硬件流控。
1.3 UART和RS485区别
| 项目 | UART(通用异步收发传输器) | RS485(EIA-485) |
|---|---|---|
| 定义 | 一种串行通信协议(硬件接口标准),负责将并行数据转换为串行数据传输,或反之。 | 一种差分信号传输标准(电气规范),定义了数据传输的电气特性,用于远距离、多节点通信。 |
| 物理层 | 通常使用单端信号(如 TTL 电平:高电平表示 1,低电平表示 0),传输距离短(一般数米)。 | 采用差分信号传输(两根线 A、B,信号通过 A-B 的电压差表示,抗干扰能力强),传输距离长(可达 1200 米)。 |
| 通信方式 | 支持全双工(需 TX、RX 两根线)或半双工(单根线分时收发),一般用于点对点通信。 | 通常工作在半双工模式(需额外控制信号使能收发),支持多点通信(最多 32 个节点)。 |
| 引脚 / 线路 | 核心引脚为 TX(发送)、RX(接收),可能包含 GND(地)、CTS(清除发送)、RTS(请求发送)等。 | 至少需要 A(非反向)、B(反向)两根信号线,通常需 GND,半双工时需 DE(驱动使能)、RE(接收使能)控制引脚。 |
| 速率与距离 | 速率较高(如最高可达数 Mbps),但距离越远速率越低,典型距离<10 米。 | 速率随距离降低(如 1200 米时约 100kbps,10 米时可达 10Mbps),适合长距离传输。 |
| 抗干扰能力 | 单端信号易受电磁干扰(EMI),抗干扰能力弱。 | 差分信号抵消共模干扰,抗干扰能力强,适合工业环境。 |
| 应用场景 | 近距离设备内部通信(如单片机与传感器、模块之间,计算机与外设)。 | 工业自动化(如 PLC、传感器网络)、安防系统、智能楼宇等远距离、多节点通信场景。 |
| 协议关系 | UART 是协议 / 接口,可与 RS232、RS485 等电气标准结合使用(如 RS232-UART、RS485-UART)。 | RS485 是电气标准,需配合 UART 等协议实现数据帧的封装与解析。 |
| 典型电路 | 基于 TTL 电平,直接通过 TX/RX 连接(如 Arduino 的 UART 接口)。 | 需要 RS485 transceiver 芯片(如 MAX485)转换 TTL 与差分信号,通过 A、B 线连接。 |
二、电路图设计
通过SIT3485芯片(芯力特)完成UART转RS485电平。

SIT3485E 芯片是一款功能全面、性能优异的 RS-485 收发器,支持自动收发功能,无需控制方向使能引脚。其核心功能及特点:
(1)宽电压供电与低功耗设计
- 支持 3.0V 至 5.5V 宽电压范围供电,兼容 3.3V 和 5V 系统设计,降低电源适配难度。
- 典型工作电流仅 180μA,关断模式下电流低至 0.5μA,显著降低系统功耗,适用于电池供电或低功耗场景。
(2)高速数据传输与多节点支持
- 最高支持 12Mbps 无差错数据传输速率,满足工业自动化、汽车电子等高速通信需求。
- 采用 1/8 负载设计,允许单总线并联 256 个收发器节点,扩展性强,适用于大规模设备组网。
(3)高抗干扰性与可靠性保障
- 集成 15kV HBM(人体模型)静电防护能力,有效抵御静电冲击,提升设备稳定性。
- 总线耐压范围达 ±15V,可承受工业现场电压波动,避免因过压损坏。
- 具备失效安全保护功能,当接收器输入开路或短路时,输出逻辑高电平,防止系统误动作。
(4)多重保护机制
- 内置限流保护和过压保护,防止因短路或过压导致芯片损坏。
- 支持热关断保护,当芯片温度超过阈值时自动关闭驱动器,避免过热失效。
(5)灵活的封装与温度适应性
- 提供 SOP8、DIP8、MSOP8 等多种封装形式,满足不同 PCB 布局需求。
- 工作温度范围覆盖 -40℃ 至 125℃,适用于极端工业环境或户外设备。
(6)协议兼容性与应用场景
- 完全符合 TIA/EIA-485 标准,兼容 RS-422 协议,支持半双工通信模式。
- 广泛应用于串口服务器、工业伺服系统、汽车电子、交换机接口模块等领域,替代 MAX3485ESA 等进口芯片,实现国产化替代。
三、驱动设计
3.1 掌握UART4/UARTD寄存器地址


3.2 掌握UART4/UARTD引脚寄存器地址
通过UART4_RX、UART4_TX、UART4_CTS、UART4_RTS在Orin-TRM_DP10508002_v1.0p.pdf文档搜索,分别找到引脚寄存器偏移地址:




可以看出来4个引脚的焊盘控制器组号是G4,在“Part VII - System Components”->"Multi-Purpose I/O Pins and Pin Multiplexing (PinMux)"->"1.5 Pad Control Unit"找到G4对应的内存基地址块为PADCTL_A4,在“Part II - Memory Architecture and Memory Mapped I/O DP-10508-”->"2 System Address Map"中找到PADCTL_A4的基地址为0x02434000。


所以UARTD的四个引脚的寄存器地址分别是:
| 引脚名称 | 寄存器地址 |
| UART4_TX | 0x243d020 |
| UART4_RX | 0x243d018 |
| UART4_RTS | 0x243d010 |
| UART4_CTS | 0x243d008 |
3.3 配置UARTD的四个引脚

设备树pinmux.dtsi配置:
uart4_tx_ph3 {
nvidia,pins = "uart4_tx_ph3";
nvidia,function = "uartd";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lpdr = <TEGRA_PIN_DISABLE>;
};
uart4_rx_ph4 {
nvidia,pins = "uart4_rx_ph4";
nvidia,function = "uartd";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lpdr = <TEGRA_PIN_DISABLE>;
};
uart4_rts_ph5 {
nvidia,pins = "uart4_rts_ph5";
nvidia,function = "uartd";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lpdr = <TEGRA_PIN_DISABLE>;
};
uart4_cts_ph6 {
nvidia,pins = "uart4_cts_ph6";
nvidia,function = "uartd";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lpdr = <TEGRA_PIN_DISABLE>;
};
3.4 确保UARD的四个引脚未复用
进入Linux_for_Tegra/source/public/hardware/nvidia目录,通过如下命令分别搜索这四个引脚是否复用,如果复用需要进行修改。
#查询UART4_RX引脚
grep "TEGRA234_MAIN_GPIO(H, 4)" -R -n
#查询UART4_TX引脚
grep "TEGRA234_MAIN_GPIO(H, 3)" -R -n
#查询UART4_RTS引脚
grep "TEGRA234_MAIN_GPIO(H, 5)" -R -n
#查询UART4_CTS引脚
grep "TEGRA234_MAIN_GPIO(H, 6)" -R -n
3.5 调试UARTD串口
输入:dmesg | grep tty
显示如下:
[ 5.197937] 3100000.serial: ttyTHS0 at MMIO 0x3100000 (irq = 26, base_baud = 0) is a TEGRA_UART
[ 5.212184] 3110000.serial: ttyTHS1 at MMIO 0x3110000 (irq = 85, base_baud = 0) is a TEGRA_UART
[ 5.226844] 3130000.serial: ttyTHS3 at MMIO 0x3130000 (irq = 86, base_baud = 0) is a TEGRA_UART
[ 5.241597] 3140000.serial: ttyTHS4 at MMIO 0x3140000 (irq = 87, base_baud = 0) is a TEGRA_UART
根据”3.1 掌握UART4/UARTD寄存器地址“得到的UARTD寄存器地址0x3130000,获得UARTD在设备中的文件句柄为/dev/ttyTHS3。
输出”3130000.serial: ttyTHS3 at MMIO 0x3130000“等信息表明UARTD已经驱动成功。
验证方法1:如果没有焊接RS485芯片可以通过如下回环方法测试串口:
stty -F /dev/ttyTHS3 115200 raw -echo
cat /dev/ttyTHS3 &
echo "test" > /dev/ttyTHS3
验证方法2:链接RS485连接器到笔记本,在agx orin上运行如下python文件进行测试
#coding=utf-8
"""
Describe: RS485测试
"""
import serial
import subprocess
import time
class SerialUse():
"""
@功能简介:串口操作类
@参数:无
@返回值:无
"""
def __init__(self):
self.portx = "/dev/ttyTHS3"
self.bps = 115200
self.timex = 5
def open(self):
try:
ser = serial.Serial(self.portx, self.bps, timeout=self.timex)
return ser
except:
print(self.portx)
def close(self, ser):
ser.close()
def send(self, ser, data):
result = ser.write(data)
def recv(self, ser):
return ser.readline()
if __name__ == '__main__':
"""
@功能简介:RS485测试
@参数:data-输入数据, length-输入数据长度
@返回值:输出数据
"""
print("RS485测试:")
send_data=[0x52, 0x53, 0x34, 0x38, 0x35, 0x20, 0x54, 0x45, 0x53, 0x54]
ins = SerialUse()
try:
ser = ins.open()
ins.send(ser, bytearray(send_data))
result = ins.recv(ser)
print(result)
except:
print("打开失败")
ins.close(ser)
408

被折叠的 条评论
为什么被折叠?



