Несколько периферийных устройств, использующих 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
}

, 👍0


1 ответ


Лучший ответ:

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.begin() устанавливает вывод SS (53) в качестве выходного и ВЫСОКОГО, @Juraj