Тактовая частота 2,4 МГц для 3-проводного SPI с использованием Arduino Mega 2560

Я пытаюсь разработать скетч Arduino для микросхемы АЦП ADS8320, которая является 3-проводным SPI. Мне нужен последовательный тактовый сигнал 2,4 МГц для интерфейса SPI. Я попробовал приведенный ниже код, но не знаю, как генерировать тактовые импульсы с тактовой частотой 2,4 МГц.

#define CLK 22
#define DBIT 24 // итак
#define CS 26

#include <SoftwareSerial.h>

int v = 0;
float Ctemp, Ftemp;

void setup()   {
  Serial.begin(9600);
  pinMode(CLK, OUTPUT);
  pinMode(DBIT, INPUT);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  digitalWrite(CLK, LOW);
}

void loop()   {
  v = spiRead();
  if (v == -1)   {
    Serial.print("No sensor \n");
  } else   {
    Serial.println(Ftemp);
  }
  delay(100);
}

int spiRead() {
  int value = 0;
  digitalWrite(CS, LOW);
  delay(2);
  digitalWrite(CS, HIGH);
  delay(220);
  /* Bring CS pin low to allow us to read the data from
    the conversion process */
  digitalWrite(CS, LOW);
  /* 1st 5 clock cycles  */
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  /*
    Read bits 16-0 from ads8320 for the adc. Loop for each bit reading
    the value and storing the final value in 'adc'
  */
  for (int i = 16; i >= 0; i--) {
    digitalWrite(CLK, HIGH);
    value += digitalRead(DBIT) << i;
    digitalWrite(CLK, LOW);
  }
  // проверяем бит D2, если HIGH нет датчика
  if ((value & 0x04) == 0x04) return -1;
  // сдвиг вправо на три позиции
  return value >> 3;
}

' я добавил код, который пробовал с библиотекой Arduino SPI, но не получил никакого результата

 // включаем библиотеку SPI:
 #include <SPI.h>


 // устанавливаем контакт 10 в качестве подчиненного устройства для цифрового потенциометра:
 const int slaveSelectPin = 10;

 void setup() {
 // устанавливаем подчиненныйSelectPin в качестве вывода:
 pinMode(slaveSelectPin, OUTPUT);
 // инициализируем SPI:
 SPI.beginTransaction(SPISettings(2400000, MSBFIRST, SPI_MODE0))

 void loop() {
 while(1){
 spiread(slaveSelectPin);
 }
 }

 void spiread(int slaveSelectPin) {
 // устанавливаем низкий уровень на выводе SS, чтобы выбрать микросхему:
 digitalWrite(slaveSelectPin, LOW);

 receivedVal = SPI.transfer(val);
// поднимем высокий уровень на выводе SS, чтобы отменить выбор чипа:
digitalWrite(slaveSelectPin, HIGH);
}

, 👍0

Обсуждение

На Arduino Mega при использовании ядра Arduino максимальная тактовая частота при переключении цифрового вывода составляет прибл. 70 кГц. Ядро Arduino очень медленное. См. тест библиотеки GPIO https://github.com/mikaelpatel/Arduino-GPIO/blob/master/examples/Benchmark/Benchmark.ino. Можно генерировать тактовую частоту до 4 МГц, но вам нужно ядро или библиотека, оптимизированная для производительности. Также тактовая частота SPI масштабируется до 8, 4, 2,... и т. д. МГц. 2,4 МГц заставит вас выбрать 2 МГц., @Mikael Patel


3 ответа


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

0

ADS8320 должен иметь частоту DCCLOCK от 0,024 МГц до 2,4 МГц. Использование примитивной побитовой обработки с миллисекундными задержками детализации не приблизится даже к нижней границе этого диапазона (500 Гц — это все, что вы можете получить с задержкой в 1 мс между каждым тактовым переходом, к тому же вы генерируете пульсовую волну, а не прямоугольная волна - противно).

Даже при использовании меньших микросекундных задержек хороших результатов не будет.

Вместо этого вам следует использовать аппаратный порт SPI, который генерирует стабильный тактовый сигнал для определения времени сбора данных.

Однако вы не можете получить тактовую частоту SPI 2,4 МГц на Arduino. Но нужна ли вам нужна тактовая частота SPI 2,4 МГц? Это абсолютный верхний предел частоты дискретизации. Вы можете работать намного медленнее — вплоть до 0,024 МГц (24 кГц) и при этом продолжать выборку.

На Arduino SPI работает с делением тактовой частоты системы. То есть 1/2, 1/4, 1/8 и т. д. Таким образом, при системной тактовой частоте 16 МГц вы можете запустить SPI на 1/8 этой скорости и получить тактовую частоту 2 МГц.

Вам также потребуется выполнить определенное количество сдвигов и распаковок битов, чтобы получить 16-битные данные из 24-битного потока (больше бит, чем у вас есть сейчас), поскольку SPI может работать только с 8-битными фрагментами.

Для 16-битного преобразования требуется минимум 22 такта. Показаны 24 тактовых цикла. Если CS остается НИЗКИМ в конце преобразования, новый поток данных с LSB-first снова смещается.

-- Техническая таблица: Рисунок 29. Основные временные диаграммы ADS8320

Поэтому вы можете просто игнорировать то, что получаете в последних двух битах 24-битного потока.

,

1

С помощью вашего метода вряд ли возможно получить стабильную и точную частоту.
Представьте, что у вас есть процедура прерывания, прерывающая вызов spiRead() или любую функцию, вызываемую внутри: ваши часы будут расширены средой выполнения ISR.
Помимо этого:

  • Я не уверен, что ваша фаза LOW достаточно длинная (нет задержки между переключением CLK с LOW на HIGH. Если 2,4 МГц — это максимальная частота для чипа, она должна составлять не менее 208 нс.
    Однако:
    Если вы уверены, что время выполнения digitalWrite всегда превышает 208 нс, вы можете вообще удалить delay(). Полученная частота — это максимально возможная частота, которую вы можете достичь с помощью вашего метода.
  • Наименьшее значение delay() составляет 1 мс, что приводит к максимальному результату < 1 кГц (или даже 0,5 кГц для сигнала 50:50).
    Вам следует использовать delayMicroсекунды(), чтобы получить частоту не менее 500 кГц.

Но что мне действительно интересно:
Почему вы реализуете битовую обработку вместо простого использования библиотеки SPI?

,

Я не нашел примера 3-проводного SPI для интерфейса датчика. как использовать библиотеку Arduino SPI здесь. Можете ли вы рассказать мне об основных функциях 3-проводного интерфейса? который устанавливает тактовую частоту не менее 2 МГц, @vassidefuk

@vassidefuk: Для 3-проводного SPI вы можете просто оставить MOSI неподключенным. Функции см. в документации библиотеки. Что там, возможно, не так понятно: функция «передача» ориентирована на байты. Поскольку вашему датчику требуется как минимум 22 бита для преобразования и отправки одного значения, вам придется вызвать «передачу» три раза (24 бита; не повредит) в пределах CS = LOW., @mic

я задал еще один вопрос, можете ли вы посмотреть и сказать, что не так с кодом? [https://arduinoprosto.ru/q/39047/ads8320-with-arduino-mega-2560], @vassidefuk


1

Тактовая частота Mega 2560 составляет 16 МГц. Целевая тактовая частота SPI составляет 2,4 МГц. В результате у вас остается 16/2,4 = 6,67 тактов на такт SPI, что означает, что у вас имеется доступная обработка, явно недостаточная для поставленной задачи. Ваша программа задохнется и не сможет уложиться в требуемые жесткие сроки. Это не сработает.

Вместо этого вам следует использовать другую плату с более высокой вычислительной мощностью, более медленной тактовой частотой SPI или аппаратное решение (вместо программного обеспечения) для тактовой частоты SPI.

,