SPI如何让从机传输回信息给主机-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 8763|回复: 4

[未解决] SPI如何让从机传输回信息给主机

[复制链接]
发表于 2019-8-28 21:24 | 显示全部楼层 |阅读模式
10金币
本帖最后由 dyn002000 于 2019-8-28 21:26 编辑

各位大大好,

测试了一下NodeMCU V3 和 Arduino UNO 之间的SPI通信测试。。代码如下:
NodeMCU Master:
[mw_shl_code=arduino,true]#include<SPI.h>

char buff[] = "Hello Slave\n";

void setup() {
  Serial.begin(9600); /* begin serial with 9600 baud */
  SPI.begin();  /* begin SPI */
}

void loop() {
  for (int i = 0; i < sizeof buff; i++) /* transfer buff data per second */
  {
    SPI.transfer(buff);
    Serial.print(buff);
  }
  delay(1000);
}[/mw_shl_code]

Arduino UNO Slave:
[mw_shl_code=arduino,true]#include <SPI.h>

char buff [100];
volatile byte index;
volatile bool receivedone;  /* use reception complete flag */

void setup (void)
{
  Serial.begin (9600);
  SPCR |= bit(SPE);         /* Enable SPI */
  pinMode(MISO, OUTPUT);    /* Make MISO pin as OUTPUT */
  index = 0;
  receivedone = false;
  SPI.attachInterrupt();    /* Attach SPI interrupt */
}

void loop (void)
{
  if (receivedone)          /* Check and print received buffer if any */
  {
    buff[index] = 0;
    Serial.println(buff);
    index = 0;
    receivedone = false;
  }
}

// SPI interrupt routine
ISR (SPI_STC_vect)
{
  uint8_t oldsrg = SREG;
  cli();
  char c = SPDR;
  if (index <sizeof buff)
  {
    buff [index++] = c;
    if (c == '\n'){     /* Check for newline character as end of msg */
     receivedone = true;
    }
  }
  SREG = oldsrg;
}[/mw_shl_code]

测试结果是没问题的  作为从机的UNO能收到“Hello Slave”。
问题就是我想让从机收到后发点信息回去给主机。。 比如:
[mw_shl_code=arduino,true] digitalWrite(SS, LOW);
  SPI.transfer(0x23);
digitalWrite(SS, HIGH);[/mw_shl_code]这样的,,是直接加在 if (receivedone) { }里面吗? 然后主机的NodeMCU又要如何读取呢??
还是说根本不能这么操作?

提前感谢各位大大的解答!

最佳答案

查看完整内容

从机当次收的数据,肯定来不及本次发出去,最快也得下次才能发出去。 看来从机 SPI.transfer 的确会卡死,不过卡完以后返回的数值,就是下一次主机发的数据啊
发表于 2019-8-28 21:24 | 显示全部楼层
dyn002000 发表于 2019-8-29 15:51
你好,
谢谢你的回复。
这样的话是不是说从机无法接受主机传送的数据处理后再传回去? 比如我主机发12 ...

从机当次收的数据,肯定来不及本次发出去,最快也得下次才能发出去。

看来从机 SPI.transfer 的确会卡死,不过卡完以后返回的数值,就是下一次主机发的数据啊
发表于 2019-8-29 00:17 | 显示全部楼层
SPI 的传输是双向同步的,每次传输主机、从机相互“交换”一个字节。
主机在发送的同时,会同步接收从机的发送。

主机 SPI.transfer( ) 的返回值,就是从机发的字节;
从机需要在主机发起通讯前,准备好待会要交换的数据,一样用 SPI.transfer( ),

对于从机,貌似 SPI.transfer 这个函数会卡住,直到主机传送完成
 楼主| 发表于 2019-8-29 15:51 | 显示全部楼层
t3486784401 发表于 2019-8-29 00:17
SPI 的传输是双向同步的,每次传输主机、从机相互“交换”一个字节。
主机在发送的同时,会同步接收从机的 ...

你好,
谢谢你的回复。
从机需要在主机发起通讯前,准备好待会要交换的数据
这样的话是不是说从机无法接受主机传送的数据处理后再传回去? 比如我主机发12给从机  从机乘以2 变成24再传回去。。。

我试了试,从机用了SPI.transfer之后接收数据的速度是明显下降了,而且接收一定次数后数据就开始不对了。。 发回给主机的话 主机接收到的只有一半是对的。。。比如应该收到的全是24, 实际上是24,12,24,12这样交替着的。。感觉SPI应该是没问题 就是不知道怎么改进 能让发送和收到的数据完全正确。
发表于 2021-6-2 21:47 | 显示全部楼层
请问函数中的
SPCR |= bit(SPE);         /* Enable SPI */
SPI.attachInterrupt();    /* Attach SPI interrupt */
ISR (SPI_STC_vect)
是他原本的SPI库中就有的还是要在哪里调用啊?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-29 05:33 , Processed in 0.154263 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表