You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用spi_transfer从SPI从设备读取字节时接收值无变化问题求助

问题原因及修复方案

代码存在的核心错误

  • 错误1:spi_transfer.tx_buf 赋值错误:txbuf 本身就是指向发送缓冲区的指针,代码中传入的&txbuf是指针变量自身的地址,而非实际发送数据的缓冲区地址
  • 错误2:spi_sync_transfer 参数传递错误:该函数第三个参数是要传输的spi_transfer结构体的数量,而非单条传输的长度,你传入read.len(值为3)会导致内核访问非法地址,传输根本未正确执行,所以rx值没有变化
  • 错误3:发送缓冲区长度不足:你设置单条传输长度len=3(对应2字节发送+1字节接收的全双工时钟),但传入的txbuf只有2字节,传输第三字节时会读取缓冲区外的非法内容

修复后的代码

修改m_read函数即可:

int m_read(uint8_t txbuf[]) {
    int ret = -1;
    // 构造3字节发送缓冲区:前2字节是传入的指令,第三字节补0(用于提供接收响应的时钟)
    uint8_t tx[3] = {txbuf[0], txbuf[1], 0x00};
    uint8_t rx = 0x01;
    struct spi_transfer xfer = {
        .tx_buf = tx,       // 直接传发送缓冲区首地址
        .rx_buf = &rx,      // 此处rx_buf用法本身是正确的,之前未生效是其他调用错误导致                       
        .len = 3,           // 单条传输总长度3字节                                    
        .speed_hz = MAX_HZ,
    };

    // 第三个参数传1:只有1个spi_transfer结构体
    ret = spi_sync_transfer(slave_device, &xfer, 1);
    if (ret < 0) {
        printk("SPI transfer failed, ret=%d\n", ret);
        return ret;
    }
    printk("Bytes read: 0x%02x\n", rx);
    return ret;
}

原有调用逻辑和mRead的定义不需要修改。

额外说明

  • SPI是全双工通信,每发送1位数据的同时会接收1位数据,你需要接收1字节响应,就需要多提供1字节的发送时钟,所以总传输长度设为3字节是正确的
  • spi_transfer.rx_buf只要传入用来存放接收数据的缓冲区首地址即可,类型是void *无需强制转换

内容的提问来源于stack exchange,提问作者user16627306

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:00:01