Мастер не получает правильные значения в канале SPI мастер/подчиненный
Я уже 3 недели пытаюсь найти решение своей проблемы, связанной с коммуникацией SPI.
Итак, мне нужно установить связь SPI между двумя устройствами Arduino: например, ведущее устройство отправляет букву «a» ведомому устройству; ведомое устройство получает ее и выполняет некоторую обработку. В моем случае оно должно установить один из своих 8 выводов на высокий уровень, затем считать все выводы и отправить отчет обратно ведущему устройству.
Та часть, где мастер отправляет 'a', а подчиненный его обрабатывает, работает нормально, но мастер, похоже, не получает правильные значения. Вместо этого он всегда получает 0.
Вот код:
Раб:
#include <SPI.h>;
volatile byte command = 0;
byte ett =8; //кол-во тестовых точек
byte motif= 0b000000000 ; //инициация моей переменной, которая будет содержать состояния моих пинов
byte end[8] = { 2,3,4,5,6,7,8,9}; //массив, содержащий контакты
void setup (void) {
Serial.begin (9600);
// нужно отправить на главный вход, *подчиненный выход*
pinMode(MISO, OUTPUT);
// включаем SPI в подчиненном режиме
SPCR |= _BV(SPE);
// включаем прерывания
SPCR |= _BV(SPIE);
} // конец настройки
// Процедура прерывания SPI
ISR (SPI_STC_vect) {
byte c = SPDR;
switch (command) {
/////////////Предательство раба/////////////
// нет команды? тогда это команда
case 0:
command = c;
SPDR = 0;
break;
case 'z': ////case 'z", установите все контакты на ВХОД
for (int i=0; i<8; i++){
pinMode (end[i], INPUT);
}
break;
case 'a': // //if 'a' : Установить один вывод на высокий уровень, затем считать состояние всех выводов, чтобы проверить, нет ли обрыва цепи или короткого замыкания
for (int j = 0; j < ett; j++) {
pinMode(end[j], INPUT); // установить все контакты как INPUT
}
motif = 0;
pinMode(end[0], OUTPUT); // Установить один вывод как ВЫХОД
digitalWrite(end[0], HIGH); // Устанавливаем выходной контакт в положение HIGH
Serial.println();
Serial.print(" ");
for (int k = 0; k < ett ; k++) { // сканирование
if (digitalRead(end[k]) == HIGH) {
// если вывод == HIGH, добавляем '1' к моему вектору
Serial.print("| ");
motif = motif + 1; // +1
} else { // если вывод == НИЗКИЙ
Serial.print(". ");
}
motif = motif << 1; // сдвиг влево
}
Serial.print(" -MOTIF LU= ");
Serial.print(motif, BIN);
SPDR = byte (motif); //SPDR — это регистр данных SPI: он содержит данные, которые будут отправлены ведущему устройству
Serial.print(" ");
break;
}
}
void loop (void) {
// если SPI не активен, очистить текущую команду
if (digitalRead (SS) == HIGH)
command = 0;
}
Мастер:
#include <SPI.h>
byte CS0=10;
byte CS1=9;
void setup (void) {
Serial.begin (9600);
Serial.println ();
digitalWrite(SS, HIGH); // убедитесь, что SS пока остается высоким
// Перевести выводы SCK, MOSI, SS в режим вывода
// также перевести SCK, MOSI в состояние LOW, а SS в состояние HIGH.
// Затем переведите оборудование SPI в режим Master и включите SPI
SPI.begin ();
// Немного замедлим мастера
SPI.setClockDivider(SPI_CLOCK_DIV8);
} // конец настройки
byte transferAndWait (const byte what) {
byte a = SPI.transfer (what);
delayMicroseconds (1000);
return a;
} // конец transferAndWait
///traitement au niveau du maitre
void loop (void) {
byte esclave0_testpin0;
/////////////Установите вывод первого ведомого устройства на Высокий, затем считайте все выводы
digitalWrite (CS0,LOW); //активируем ведомое устройство
transferAndWait ('a'); // устанавливаем вывод первого ведомого устройства на высокий уровень
esclave0_testpin0 = transferAndWait ('z'); //считываем все пины ведомого устройства и сообщаем об этом в переменной esclave0_testpin0
digitalWrite (CS0,HIGH); //отключить ведомое устройство
Serial.println ("test_0");
Serial.println (esclave0_testpin0, BIN);
delay (1000); // задержка 1 секунда
} // конец цикла
@Saha222, 👍2
1 ответ
В подчиненном команда всегда равна 0. Вы, вероятно, имели в виду:
void loop(void) {
command = (digitalRead(SS) == HIGH ? 0 : 1);
}
и в ISR:
ISR (SPI_STC_vect) {
byte input = SPDR;
byte output = 0;
if (command) {
switch (input) {
case 'a':
//...
break;
case 'z':
//...
break;
}
}
// send data back
SPDR = output;
}
В качестве лучшей практики избегайте реализации логики в ISR и используйте глобальные volatile переменные для передачи изменений состояния в код в основном цикле. Вероятно, вам придется реализовать кольцевой буфер для приема и отправки на шину SPI...
- ADS1262 и 2,2 SPI TFT (два ведомых SPI) с Arduino
- Библиотека AD7768-1 "Ардуино"
- Моя настройка двух ведомых SPI на arduino не работает правильно
- Как использовать SPI на Arduino?
- Как заставить Arduino взаимодействовать с тремя другими Ардуино?
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
- Отправка значения с одного Arduino на другой
- OVF в последовательном мониторе вместо данных