Двухстороннее общение двух UNO через SPI

Daemon2017
Offline
Зарегистрирован: 08.10.2013

Здравствуйте!

Задумка такая: есть две Уны, первая Уна (Мастер) отправляет второй (Слейву) 0. Слейв это число инкрементирует и отправляет обратно Мастеру. Мастер снова инкрементирует число и отправляет Слейву. 

 

Изучил вот эти материалы, но так и не понял, как это сделать:

http://www.gammon.com.au/spi

http://arduino.stackexchange.com/questions/16348/how-do-you-use-spi-on-a...

 

Опираясь на мой опыт в I2C и UART - код у обеих плат будет почти одинаковый (только надо будет поменять местами функции отправки и приема), поэтому я попробовал просто объединить код мастера и слейва в один. Получилось вот что:

#include <SPI.h>

int data = 0;
volatile bool process_it;

void setup (void)
{
  Serial.begin (115200);

  //Чтобы слать Мастеру
  pinMode (MISO, OUTPUT);

  //Подготовка для работы с прерываниями
  process_it = false;

  //Подключаем прерывания
  SPI.attachInterrupt();

  //Занижаем скорость отправки за счет предделителя
  SPI.setClockDivider(SPI_CLOCK_DIV8);
}

void loop (void)
{
  dataSend();

  dataReceive();
}

void dataSend()
{
  //Делаем Слейв-Селект высокоуровневым
  digitalWrite(SS, HIGH);

  //Включаем СПИ (режим отправки)
  SPI.begin ();

  char c = data;

  //Делаем Слейв-Селеект низкоуровневым - даем Слейву понять, что сейчас ему будут слать что-то
  digitalWrite(SS, LOW);

  //Отсылаем пробную строку
  SPI.transfer (c);

  //Делаем Слейв-Селект высокоуровневым
  digitalWrite(SS, HIGH);

  Serial.println ("Что-то отправилось");

  //Спим
  delay (1000);
}

ISR (SPI_STC_vect)
{
  //Ловим байт из СПИ
  byte c = SPDR;

  //Увеличиваем на единицу
  data = c++;

  process_it = true;
}

void dataReceive()
{
  //Включаем СПИ (режим приема)
  SPCR |= bit (SPE);

  //Если сработало прерывание - к нам шлют что-то
  if (process_it)
  {
    Serial.println ("Что-то пришло");

    process_it = false;
  }
}

Буду очень благодарен, если поможете исправить мой код! Пример рабочего кода тоже будет очень кстати :)

teodor4ik
Offline
Зарегистрирован: 04.11.2013

 Serial.println ("Что-то пришло");

сериал штука медленная. Может лучше лампочкой помигать?

Daemon2017
Offline
Зарегистрирован: 08.10.2013

teodor4ik пишет:

 Serial.println ("Что-то пришло");

сериал штука медленная. Может лучше лампочкой помигать?

Можно и лампочкой :) Лишь бы данные доходили, инкрементировались и возвращались обратно.

teodor4ik
Offline
Зарегистрирован: 04.11.2013

Я так понял, вы его вызываете после приема каждого бита. А сериал имеет своих прерываний и работает оооочень медленно... Хотя я вообще тупень в этом деле и могу сильно ошибаться :)