Несколько периферийных устройств, использующих SPI с Мега
Я использую программируемые генераторы сигналов Mega 2560 и 2 x AD9833.
AD9833 использует протокол SPI, и я использовал код vwlowen в качестве отправной точки (я не использую дисплей, а только генераторы). Я добавил переменную канала для выбора ведомого устройства.
Все это работает нормально, пока я не попытаюсь добавить второй AD9833. Я видел этот пост о более чем 1 периферийном устройстве, использующем SPI & a Mega, в котором говорится, что я могу использовать любой контакт для выбора ведомого устройства (SS), но следующий код работает только в том случае, если я использую вывод 53. В результате я могу отправить одни и те же данные обоим, т.Е. Оба используют один и тот же вывод SS, если этот pin равен 53. Любой другой выбор контакта SS игнорируется устройствами. Я попробовал пин 49 для обоих и без изменений, я пробовал 53 и 49, но изменилось только устройство на 53.
Так что же здесь происходит? Что такого особенного в выводе 53, что он не может быть воспроизведен другим выходным выводом?
/*
Измененный код для модуля формы волны AD9833 первоначально из vwlowen.co.uk
Общая терминология SPI и распиновка на AD9833
MOSI - ДАННЫЕ
SCLK - CLK
SS - FSYNC
MISO - не реализовано, т.е. на AS9833 нет контакта MISO
*/
#include <SPI.h>
const int SINE = 0x2000; // Определить значение регистра формы сигнала AD9833.
const int SQUARE = 0x2028; // Когда мы обновляем частоту, нам нужно
const int TRIANGLE = 0x2002; // определить форму волны, когда мы закончим запись.
const float refFreq = 25000000.0; // Опорная частота бортового кристалла
const int FSYNCA = 53; // Стандартные контакты SPI для генератора сигналов AD9833.
//const int FSYNCB = 49;
const int CLK = 52; // CLK и контакты ДАННЫХ.
const int DATA = 51;
unsigned long freq = 1000; // Установить начальную частоту.
void setup() {
pinMode(FSYNCA, OUTPUT);
// pinMode (FSYNCB, ВЫХОД);
SPI.begin();
SPI.setDataMode(SPI_MODE2);
delay(50);
AD9833reset(); // Сброс модуля AD9833 после включения питания.
delay(50);
AD9833setFrequency(freq, SQUARE, FSYNCA); // Установить частоту и выход синусоидальной волны
// AD9833setFrequency (частота, СИНУС, FSYNCB);
}
void loop() {
// TODO: Управление ПК через USB
}
// Документация AD9833 рекомендует "Сброс" при первом подаче питания.
void AD9833reset() {
WriteRegister(0x100, FSYNCA); // Записать '1' в бит D8 управляющего регистра AD9833.
delay(10);
// WriteRegister(0x100, FSYNCB);
// задержка (10);
}
// Установите регистры частоты и формы сигнала в AD9833.
void AD9833setFrequency(long frequency, int Waveform, int channel) {
long FreqWord = (frequency * pow(2, 28)) / refFreq;
int MSB = (int)((FreqWord & 0xFFFC000) >> 14); //Для данных используются только младшие 14 бит
int LSB = (int)(FreqWord & 0x3FFF);
//Установить управляющие биты 15 и 14 в 0 и 1 соответственно для частотного регистра 0
LSB |= 0x4000;
MSB |= 0x4000;
WriteRegister(0x2100, channel);
WriteRegister(LSB, channel); // Запись младших 16 бит в регистры AD9833
WriteRegister(MSB, channel); // Запись верхних 16 бит в регистры AD9833.
WriteRegister(0xC000, channel); // Фазовый регистр
WriteRegister(Waveform, channel); // Выход и сброс к СИНУСУ, КВАДРАТУ или ТРЕУГОЛЬНИКУ
}
void WriteRegister(int dat, int channel) {
digitalWrite(channel, LOW); // Установите FSYNC low перед записью в регистры AD9833
delayMicroseconds(10); // Дайте AD9833 время подготовиться к приему данных.
SPI.transfer(highByte(dat)); // Каждый регистр AD9833 имеет ширину 32 бита и каждый 16 бит.
SPI.transfer(lowByte(dat)); // биты должны быть переданы в виде 2 x 8-битных байтов.
digitalWrite(channel, HIGH); //Запись завершена. Установите высокий уровень FSYNC
}
@DrBwts, 👍0
1 ответ
Лучший ответ:
Что такого особенного в контакте 53
Вывод 53 - это вывод выбора ведомого устройства периферийного устройства SPI. Таким образом, это имеет отношение к тому, как работает периферийное устройство SPI.
Он тесно связан с операцией master / slave тем, что когда это вход SPI, он работает в подчиненном режиме, а когда это выход, он работает в главном режиме.
Таким образом, чтобы использовать SPI в режиме master, независимо от того, используете ли вы вывод 53 или нет, он должен быть на выходе, чтобы SPI вообще работал.
В вашей методологии нет ничего плохого, но не хватает одного: начального состояния микросхемы выбора контактов.
Вы всегда должны начинать с того, что все контакты chip select отключены (т. Е. Высоки), а не в неизвестном (вероятно, низком - мне придется проверить таблицу данных) состоянии - исключением может быть pin 53, который SPI сам может установить для вас ВЫСОКИЙ уровень.
Поэтому, если вы добавите:
digitalWrite(FSYNCA, HIGH);
digitalWrite(FSYNCB, HIGH);
сразу после установки pinMode
для ваших контактов и по-прежнему использовать оба контакта 53 и 49, то он должен работать.
- Как использовать SPI на Arduino?
- Путаница между SPI и I2C для SSD1306 OLED
- Неправильная документация для выводов Mega2560 SPI?
- Взаимодействие с датчиком SSI?
- Ответ нескольких ведомых устройств (Arduino Mega 2560) через SPI
- SPI с преобразователем уровня на другом конце соединения
- Проблема с выводом MISO в SPI
- Можно ли подключить много (20+) датчиков SPI к Arduino Mega?
SPI.begin()
устанавливает вывод SS (53) в качестве выходного и ВЫСОКОГО, @Juraj