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

Mbed平台SPI从机spi.receive()始终返回0问题求助

关于Mbed SPISlave receive()返回0的问题分析

我刚仔细看了你的代码和问题描述,这其实是对Mbed的SPISlave::receive()函数的用途理解偏差导致的,咱们一步步拆解清楚:

核心误解:receive()的返回值不是"是否有数据"的标志

Mbed的SPISlave::receive()函数不是用来检测数据是否到达的状态判断函数——它的实际作用是:

  • 阻塞等待主机发起SPI传输
  • 完成一次完整的SPI收发操作(你提前用reply()设置的字节会发给主机,同时接收主机发来的字节)
  • 返回的是主机本次发来的字节数据,而非表示"有/无数据"的布尔值

为什么你的if判断会导致通信失败

看你写的这段代码:

if (!spislave.receive()) { 
    receive_value = spislave.read(); 
}

这个逻辑的意思是:只有当receive()返回0的时候,才去读取数据。但实际场景中:

  1. 如果主机发送的是非0的有效数据(比如你要传输的控制值),receive()会直接返回这个非0值,!取反后条件为假,代码就不会执行read(),导致有效数据被留在缓冲区里,你自然拿不到正确值,看起来通信失败
  2. 当主机还没发起传输时,receive()可能会阻塞或者返回0,这时候你去read(),拿到的也是无效的0值

而当你去掉这个if判断后,不管receive()返回什么,你都会执行read()——其实这时候receive()已经完成了接收操作,read()只是从缓冲区里取出本次接收的真实数据,所以通信就恢复了。

修正后的正确写法

你完全不需要额外的if判断,直接用receive()的返回值作为接收数据即可,或者配合read()使用(两者效果一致,因为receive()返回的就是缓冲区里的值):

while (1) { 
    transmit_value = 100 * voltage; 
    spislave.reply(transmit_value); 
    // 直接接收主机发来的数据,赋值给receive_value
    receive_value = spislave.receive(); 
    // 或者分开写也可以:
    // spislave.receive(); // 等待并完成传输
    // receive_value = spislave.read(); // 读取接收缓冲区
    
    led.write(receive_value / 100.0); 
    // 后面的显示代码保持不变...
}

补充说明

如果你确实需要主动检测是否有主机发起传输,Mbed的SPISlave提供了is_receive()函数(不同版本可能有细微差异),这个函数才是用来判断是否有数据等待接收的状态位。但在你的循环场景里,receive()本身会阻塞等待主机传输,所以完全不需要额外判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:37:12