Что не так с моим кодом?

spi

Я использую мега как мастер и нано как ведомый.
Оба должны передавать тексты. Однако я получаю от мастера всегда только тот ответ, который я посылаю.
Текст от раба не приходит.

Мастер:

#include <SPI.h>
volatile boolean senden;
volatile char Paket_vom_Slave;
volatile char Paket_zum_Slave;
char buf [100];
volatile byte pos;
String Paket = "";
char x;


void setup (void)

{
  Serial.begin(9600);
  pinMode(53, OUTPUT);
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH);  //Устанавливаем вывод SS на ВЫСОКИЙ уровень
  SPI.begin ();  //Начало соединения
  SPI.setClockDivider(SPI_CLOCK_DIV8);  //Замедлить скорость
}

void loop (void)
{
  //создать_текст();

  digitalWrite(SS, LOW);    //начинаем общение с ведомым

  for (const char * p = "TxT v Master\n" ; Paket_zum_Slave = *p; p++)
  {
    //создать_текст();
    Paket_vom_Slave = SPI.transfer(Paket_zum_Slave); //отправляем текст
    Text_erstellen();
    delayMicroseconds (500);
    Serial.print("sent: ");
    Serial.print(Paket_zum_Slave);
    Serial.print("\t empfangen: ");
    //Serial.println(packet_from_slave);
    Serial.println(Paket);
    delay(200);
  }
  digitalWrite(SS, HIGH);  //завершаем связь
  delay (1000);  //короткий перерыв

}

void Text_erstellen()
{
  char c = Paket_vom_Slave;  //копируем данные из буфера SPI
  if (pos < sizeof buf)
  {
    buf [pos++] = c;  //добавим следующий символ
    if (c == '\n')
      senden = true;
  }
  if (senden)
  {
    buf[pos] = 0;
    Paket = (buf);
    x = buf;
    Paket.trim();
    Serial.println (("empfangen :--->") + (Paket));
    Serial.println (("empfangen :--->") + (Paket));
    Serial.println (("empfangen :--->") + (Paket));
    pos = 0;
    senden = false;

  }
}

Раб:

#include <SPI.h>
volatile boolean senden;
volatile boolean versandbereit;
// изменчивый байт package_master, Shipping_slave;
volatile char Paket_Master;
volatile char Sendung_Slave;
String Paket = "";
String Sendung = "";
int i = -1;
char buf[20];
char buf1[20];
volatile byte pos;
volatile byte pos1;


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


 pinMode(12, OUTPUT);
  pinMode(MISO, OUTPUT);
 SPCR |= _BV(SPE);         // включить SPI в подчиненном режиме


  //SPCR |= бит (SPE);
  senden = false;
  SPCR |= _BV(SPIE);   // включаем прерывания
  SPI.attachInterrupt();
}

void loop(void)
{

  if ((versandbereit) == false);
  {
    Paket_Text();
  }

  if (senden)
  {
    i = i + 1;

    buf[pos] = 0;
    Paket = (buf);
    buf1[pos] = 0;
    Sendung = (buf1);

    if (i == 12)
    {
      SPDR = "\n";
    }
    else
    {
      SPDR = (buf1[i]);
    }
    Paket.trim();
    Sendung.trim();
    Serial.println (("empfangen :--->") + (Paket));
    Serial.println (buf1[i]);
    Serial.println (i);
    Serial.println (("gesendet  :--->") + (Sendung));

    pos = 0;
    senden = false;
  }

  if (i == 12) i = -1;
}

ISR(SPI_STC_vect)
{

  byte c = SPDR;  //копируем данные из буфера SPI
  if (pos < sizeof buf)
  {
    buf[pos++] = c;  //добавляем следующий символ
    if (c == '\n')
      senden = true;
  }
}

void Paket_Text()
{
  if (pos1 < sizeof buf1)
    for (const char * p = "Paket--Slave\n" ; char c = *p; p++)
    {
      buf1[pos1++] = c;
                            Serial.println (buf1);
      if (c == '\n')
        versandbereit = true;
    }
}

Я обновил код выше.
Подчиненное устройство теперь отправляет побитно текст той же длины, что и должно быть, но другой текст, подобный отправленному ведущим устройством.
К сожалению, хозяин всегда получает то, что посылает, а не то, что приходит от раба.


Я продвигаюсь медленно :-)

Но сейчас у меня возникла проблема с передачей данных. Передаю при запуске: char package_to_master [50] = "Запустить с подчиненного."; и изменить содержимое процедуры прерывания SPI на «новый текст» но посылается «начиная с раба». Как мне это изменить?

// Подчиненный
char Paket_zum_Master[50] = "Starten vom Slave.";
volatile int pos;
volatile bool active;
String Send_Paket;
ISR (SPI_STC_vect)    // Процедура прерывания SPI
{
  Send_Paket = "neuer Text";
  char Sendung = ((Send_Paket + "\n").c_str());
  Paket_zum_Master[50] = Sendung;
  byte c = SPDR;
  if (c == 1)  // начинаем новую последовательность?
  {
    active = true;
    pos = 0;
    SPDR = Paket_zum_Master[pos++];   // отправляет первый байт
    return;
  }
  if (!active)
  {
    SPDR = 0;
    return;
  }
  SPDR = Paket_zum_Master[pos];
  if (Paket_zum_Master[pos] == 0 || ++pos >= sizeof(Paket_zum_Master))
    //если pos=0 или больше 1
    active = false;
}  // конец

, 👍-3

Обсуждение

Контакт 10 на nano и главный контакт 53, но обмен оборудованием в порядке, я уже проверил, @Dieter Tepe

http://www.gammon.com.au/forum/?id=10892&reply=1#reply1, @Juraj

Не по теме, но более описательное название могло бы быть хорошей идеей., @Dave Newton


2 ответа


1

У вас нет pinMode(SS, OUTPUT); в setup() мастера.

,

digitalWrite(SS, HIGH);, @Dieter Tepe

Я думаю, что это произошло с командой:, @Dieter Tepe

Я попробовал один раз, но проблема осталась :-(, @Dieter Tepe

для использования digitalWrite pinMode необходимо установить, @Juraj

не устанавливайте его на выход на ведомом устройстве. На ведомом устройстве вывод SS обрабатывается аппаратно., @Juraj

Да Мега Мастер Pin52 Nano =pin10, @Dieter Tepe

Вы добавили pinMode(SS, OUTPUT); в setup() на главном устройстве?, @Juraj

pinMode(SS, OUTPUT); digitalWrite(SS, HIGH); SPI.begin (); SPI.setClockDivider(SPI_CLOCK_DIV8); зарегистрирован, но еще не, @Dieter Tepe

если это помогло на мгновение, проверьте проводку. заземление подключено между платами?, @Juraj

Я попытаюсь еще раз объяснить ошибку, может быть, у кого-то есть идея. Я отправляю Мастеру "TxT v Master \ n" на символ "\ n" ведомый выдает мне сообщение правильно. Подчиненный отправляет обратно ____ "package - slave \ n", но мастер показывает мне только тот текст, который он отправляет сам. Когда я отправляю что-то без символа "\ n" с подчиненного устройства, главное устройство не объединяет текст void text_create () без отмены. Но поскольку подчиненный отправляет ту же длину символа, передача кажется очевидной. Однако при сочинении мастер только собирает то, что посылает. У меня где-то есть червь, @Dieter Tepe

Paket_vom_Sklave; — это, очевидно, допустимый возврат, а с "\ n" ведомый объект идет со сносом. В случае недействительного возврата, но нет. Надеюсь, мое объяснение понятно. Мастер Дитер., @Dieter Tepe

Если мне нужно изменить мод пин-кода, как мне это сделать, если я все еще тупой. Может, кто-нибудь скажет мне, куда именно мне нужно вводить., @Dieter Tepe

попробуйте примеры Ника Гэммона по ссылке, которую я добавил в комментарии к вопросу. код очень похож на ваш, но не тот же самый, @Juraj

Если мне нужно изменить мод пин-кода, как мне это сделать, если я все еще тупой. Может, кто-нибудь скажет мне, куда именно мне нужно вводить., @Dieter Tepe

Ник Гаммон seine Beispiele sind Gut die hab ich aber schon hin und her gelesen und probiert leider ist es mir nicht gelungen da ein Nutzen raus zu bekommen. Мир чувствовал, что сейчас есть Erfahrung., @Dieter Tepe

Ник Гаммон, его примеры хороши, но я уже читал и пытался, но, к сожалению, мне не удалось извлечь пользу. Мне все еще не хватает опыта. ой, извините, не английский bevor, @Dieter Tepe


0

Я попробовал это с Arduino Pro Micro в качестве ведущего устройства и Arduino Uno в качестве ведомого устройства. Это работает.

SPI микро uno

В «Примечании о выводе выбора ведомого устройства (SS) на платах на базе AVR» https://www.arduino.cc/en/Reference/SPI указано, что вывод SS всегда следует устанавливать как ВЫХОД, даже если вы используете другой для выбора устройства.

Ответ содержит текст внутри регистра данных SPI, вам нужно изменить его внутри isr https://www.avrfreaks.net/forum/how-fast-can-spi-slave-reply, иначе это тот же текст, что был получен

const char *p = "Reponse Uno\n" ;
ISR(SPI_STC_vect)
{
  byte c = SPDR;  //копирование данных из буфера SPI
  buf[pos++] = c;  //hinzufuegen des naechsten Zeichens

  if (pos < 13) 
    SPDR = p[pos-1];
  else
    SPDR = 0;

  if (c=='\n') {
    for (int i=0;i<pos;i++)
        bufi[i]=buf[i];
    posi = pos;
    pos = 0;
    senden = true;
  }
}

Результат: Один ответ

Кстати, заставить его работать с Arduino Pro Micro в качестве ведомого устройства — это уже другая проблема...

,

проблема в том, что он не устанавливает SS как выход, даже если он использует его для выбора ведомого устройства, @Juraj

Да, это работает для меня до сих пор, но в мастере с вами, подчиненный отправляет тот же синонимичный да тот же самый ответ, что он отправляет. Мастер должен фактически получить другой текст., @Dieter Tepe

Добавлен способ, которым мастер может получить другой текст к ответу., @rantan pan