两台Jetson Nano设备间SPI主从通信异常问题求助
解决Jetson Nano SPI从机模式通信问题
首先得明确一个关键问题:Jetson Nano的SPI默认配置是主机模式,你不能仅通过拉低CS引脚就把它变成从机。你之前看到的随机数据,本质是因为从机端的SPI控制器仍在主机模式下自行产生时钟,没有和主机同步,所以读取到的是无意义的噪声。下面一步步帮你解决:
1. 纠正硬件连接
先放弃直接把从机CS拉到GND的做法,正确的点对点(后续扩展到菊花链)连接应该是这样:
- 主机 & 从机的 SPI1_SCK(引脚23) 互相连接
- 主机 & 从机的 SPI1_MOSI(引脚19) 互相连接
- 主机 & 从机的 SPI1_MISO(引脚21) 互相连接
- 主机的 SPI1_CS0(引脚24) 连接到从机的 SPI1_CS0(引脚24)
如果后续要扩展到菊花链(多台从机),连接逻辑调整为:
- 主机 SCK → 所有从机 SCK
- 主机 MOSI → 第一台从机 MOSI;第一台从机 MISO → 第二台从机 MOSI;第二台从机 MISO → 主机 MISO
- 主机 CS → 所有从机 CS(或者用独立CS控制,取决于你的需求)
2. 配置从机的设备树(关键步骤)
Jetson Nano默认的SPI节点是为主机模式设计的,必须修改设备树启用从机模式:
- 备份原设备树:
sudo cp /boot/tegra210-p3448-0000-p3449-0000-a02.dtb /boot/tegra210-p3448-0000-p3449-0000-a02.dtb.bak - 反编译设备树为可编辑的DTS文件:
dtc -I dtb -O dts /boot/tegra210-p3448-0000-p3449-0000-a02.dtb -o tegra210-p3448.dts - 编辑
tegra210-p3448.dts,找到SPI1对应的节点(通常是spi@7000d400),添加spi-slave;属性,修改后类似:spi@7000d400 { status = "okay"; spi-slave; nvidia,clk-rate = <25000000>; ... // 保留原有其他属性 }; - 重新编译设备树并替换原文件:
dtc -I dts -O dtb tegra210-p3448.dts -o /boot/tegra210-p3448-0000-p3449-0000-a02.dtb - 重启Jetson Nano使配置生效。
3. 更换适合的代码(spidev不支持从机模式)
你之前用的spidev库是专门为主机模式设计的,从机无法通过它正常接收数据。推荐使用pigpio库,它支持SPI从机模式:
先安装pigpio(主机和从机都要装)
sudo apt-get update && sudo apt-get install pigpio -y sudo systemctl enable pigpiod sudo systemctl start pigpiod
主机代码(发送数据)
import pigpio import time # 配置SPI参数 SPI_CHANNEL = 0 SPI_SPEED = 250000 SPI_MODE = 0 # CPOL=0, CPHA=0,和从机保持一致 pi = pigpio.pi() if not pi.connected: print("无法连接pigpio服务") exit() # 打开SPI主机模式 pi.spi_open(SPI_CHANNEL, SPI_SPEED, SPI_MODE) try: while True: # 发送测试数据 send_data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] # xfer2会同时发送和接收数据(SPI是全双工) count, recv_data = pi.spi_xfer(SPI_CHANNEL, send_data) print(f"主机发送: {send_data} | 接收从机数据: {list(recv_data)}") time.sleep(0.1) except KeyboardInterrupt: pi.spi_close(SPI_CHANNEL) pi.stop() print("\n通信结束")
从机代码(接收数据)
import pigpio import time # 配置SPI参数,必须和主机完全一致 SPI_CHANNEL = 0 SPI_SPEED = 250000 SPI_MODE = 0 pi = pigpio.pi() if not pi.connected: print("无法连接pigpio服务") exit() # 打开SPI从机模式 pi.spi_open(SPI_CHANNEL, SPI_SPEED, SPI_MODE) try: while True: # 读取主机发送的数据,指定读取8字节 count, recv_data = pi.spi_read(SPI_CHANNEL, 8) if count > 0: print(f"从机接收: {list(recv_data)}") # 短时间休眠避免占用过多CPU time.sleep(0.01) except KeyboardInterrupt: pi.spi_close(SPI_CHANNEL) pi.stop() print("\n通信结束")
4. 验证步骤
- 先启动从机代码
- 再启动主机代码
- 此时从机应该能稳定接收到主机发送的
[1,2,3,4,5,6,7,8]数据,而不是随机噪声
内容的提问来源于stack exchange,提问作者Çağlar Yıldız
相关产品推荐
相关产品推荐

