SPI между микроконтроллерами

Как новичок в программировании PIC, я ищу некоторые мысли о том, как реализовать SPI между ведущим и подчиненным MCU наиболее эффективным способом.

Целью этой системы является предоставление чрезвычайно гибкого способа «отображения» до 32 отдельных выходных контактов ведомого MCU на любой из 32 входных контактов ведущего MCU с использованием программно-конфигурируемой «матрицы».

Чтобы было немного понятнее, я добавил рисунок ниже:

ПОТОК СПИ

Другой MCU (не показан на рисунке) управляет настройкой сопоставления портов и передает эту информацию подчиненному MCU в виде «матрицы портов» через I2C.

В примере рисунка подчиненный выходной порт B, бит 0 (B.0) должен быть сопоставлен с главным входным контактом A, бит 0 (A.0). Кроме того, выход B.3 должен отображаться на вход A.1, а выход C .6 должен отображаться на вход B.6

Таким образом, когда главный контакт A.1 становится высоким, подчиненный контакт B.3 также должен быть высоким. С точки зрения приложения это должно быть прямолинейно.

Но каким будет наиболее эффективный способ прочитать 32 бита из 4 портов на ведущем устройстве и представить их на ведомом устройстве в виде 32-битного целого числа, чтобы приложение обеспечило сопоставление со своими выходными портами?

Тактовая частота SPI должна быть не менее 2 МГц, чтобы быть функционально приемлемой. Является ли DMA решением здесь? Может ли такое транспортное решение быть основано на прерывании/событии, чтобы ЦП не опрашивал материал? Целевыми микроконтроллерами являются PIC32MX795.

Я мог бы определенно использовать некоторые подсказки, чтобы начать это общение.

Заранее спасибо!

Что вы уже сделали и почему этого недостаточно? Мне нужно больше информации. Как вы определяете «наиболее эффективный способ»? Например, наименьшее использование пропускной способности SPI, наименьшее количество циклов ЦП на ведомом устройстве, наименьшее количество циклов ЦП на ведущем, что-то еще? Как меняются входные контакты, по одному или случайное сочетание контактов? Какова минимальная продолжительность изменения входного контакта, которая должна быть распознана и распространена? Что такое приемлемая задержка? Наименьшая задержка между изменением входа на один контакт и выводом после него, или постоянная задержка независимо от того, сколько контактов изменяется? Какова максимальная задержка для одно- и многоконтактных изменений?
Этот проект на основе MCU находится в стадии разработки. Текущая реализация аппаратная, но недостаточно гибкая. Его целью является повторное использование импульсов станка с ЧПУ. Они появляются случайным образом на всех выводах. Текущая максимальная частота импульсов составляет 400 кГц. Длительность импульса около 1 мкс. Единственная работа Мастера — пробовать входные контакты + транспорт. Функция Slave ограничена настройкой выходных портов в соответствии с конфигурационной матрицей. Задержки до 10 мкс приемлемы, если согласуются. Под наиболее эффективным я подразумевал самую быструю настройку, будь то прямой доступ к памяти или код, который все еще изучается.
В PIC32MX795 все регистры портов 32-битные, хотя реализовано не более 16 бит. Вы показываете только 8 бит для каждого порта. Хорошо, ты просто пропустишь биты 8-15. Но некоторые контакты порта не реализованы. Я буду игнорировать порт A, так как недостающие контакты находятся в старшем байте. Но контакты RC0, RC5, RC6 и RC7 недоступны. См. стр. 28 таблицы данных. Просто чтобы вы знали.
Используя ваше требование к задержке, 32 бита, передаваемые от ведущего к ведомому за 10 мкс, требуют тактовой частоты SPI не менее 3,2 МГц, и это игнорирует время, необходимое для любой обработки. Использование вашей спецификации длительности импульса 1 мкс приводит к тактовой частоте SPI 32 МГц ...
На самом деле 32 сигнала являются частью большего набора. Задержка в 10 мкс возникает из-за того, что наши сигналы синхронизируются с другими сигналами, не входящими в объем решения. Если я изменю маршрутизацию и удостоверюсь, что все критические сигналы проходят через решение, задержка станет намного менее жесткой, так как 1 мс будет нормально.
tcrosley, я знаю, порты на рисунке не настоящие порты, они просто служат для уточнения... спасибо!

Ответы (3)

Для передачи данных: проще всего это сделать с помощью сдвиговых регистров. Вам не нужно будет беспокоиться ни о медленных микроконтроллерах, ни о программировании оборудования в CPLD.

Возьмем например 74HC164 и 74HC166

Вы можете каскадировать четыре регистра 74HC166, чтобы создать 32-разрядный регистр сдвига с параллельным вводом/выводом, а затем выполнить десериализацию с использованием четырех регистров 74HC164 (32-разрядный регистр последовательного ввода/вывода). Эти чипы могут легко работать на частоте 100 МГц, практически ничего не стоят и требуют минимальной схемы.

Проблема в том, что вы хотели использовать «матрицу назначения контактов». Строить это с воротами было бы болезненно.

Если вы сами хотите изменить протокол связи, самым быстрым способом может быть использование всех 4 линий для отправки состояний выводов (8 выводов данных на линию).

Идея здесь состоит в том, чтобы использовать в основном однопроводной последовательный протокол. Поскольку у вас не будет тактовой линии, вам нужно будет использовать какой-то стартовый бит, чтобы определить начало передачи.

Допустим, линии данных удерживаются на высоком уровне в состоянии простоя, а 0 — это начальный бит. Если вы хотите передать 0x12345678 данных контакта (32 бита), вы должны передать 0x12 в первой строке, 0x34 во второй строке и так далее.

Битовый шаблон в первой строке будет выглядеть так:

0 0 0 0 1 0 0 1 0

^ — начальный бит

Во второй строке вы получите:

0 0 0 1 1 0 1 0 0

^ — начальный бит

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

Затем все, что вам нужно сделать, это сжать данные, собранные из всех 4 строк, используя некоторые битовые сдвиги, и записать их прямо в вывод.

Это не сработает - асинхронная связь. с синхронизацией на основе слов для скорости 2 МГц будет сложно, даже если она будет реализована аппаратно. Вот почему RS-232 такой медленный.
Ну, он сказал, что ему потребуется 2 МГц, если он будет использовать SPI для передачи всех 32 бит. Таким образом, вам нужно передавать только 8 бит за раз, поэтому потенциально вы можете тратить больше времени на бит. Это только побитовая синхронизация.
Это не так: битовая синхронизация требует, чтобы PLL фиксировал фазу/частоту передатчика. Синхронизация на основе слов, однако, синхронизируется по фазе фронта, генерируемого стартовым битом. Затем он производит выборку нескольких битов (8-10) через заданные интервалы позже, надеясь, что часы передатчика близки к его собственным часам. 2 МГц означает период 500 нс для бита, что слишком быстро для PIC.
Эта картинка? Его максимальная частота составляет 80 МГц, контакты могут даже переключаться на этой частоте. Это должно быть выполнимо. Опять же, нам не нужны 2 МГц, если вам нужно передать только 8 бит.
Вам нужно выполнить фазовую синхронизацию на всех этих параллельных линиях, что означает, что вам нужно сэмплировать каждый бит примерно в 10 местах. Таким образом, вместо, скажем, частоты дискретизации 500 кГц вам нужно 5 МГц. Это означает, что у вас есть окно примерно из 16 инструкций для обработки всех 4 параллельных комм. линии. Вы начинаете понимать, почему это нехорошо? Теперь вы можете сделать свою жизнь намного проще, если просто добавите 5-ю строку для синхронизации, потому что это избавит от необходимости фазовой синхронизации и стартовых битов и т. д.

Ваши требования довольно строгие (2 МГц, задержка 10 мкс), чтобы это можно было сделать на PIC с несколькими десятками MIPS. При этом, возможно, это возможно. Но это все еще не лучший инструмент для работы.

Знакомы ли вы с ПЛИС? Они слишком большие и дорогие для этого, но некоторые дешевые маленькие CPLD тоже могут это сделать. Вместо того, чтобы писать программное обеспечение, вы должны реализовать переключение битов SPI в VHDL или Verilog на главной стороне, а затем подчиненным может быть ваш контроллер ЧПУ, PIC или другой CPLD.

Я не узнал о них CPLD. Действительно, интересная альтернатива для просмотра. Спасибо!
Я придумал еще более простой способ сделать это и опубликовал его для вас как еще один ответ.
Допустим, мы меняем дизайн и переходим на CPLD, которые решат проблему выборки на мастере, позволят реализовать любой последовательный протокол и решат проблему коммутации выходов в виде матрицы. единственная вещь, которая остается для меня неясной, — это как создать некоторый уровень свободы конфигурации в CPLD или какой-либо EEPROM или окружающей флэш-памяти. Мы должны иметь возможность «подключать» выходные данные к входным на лету, а не во время компиляции?
Простой способ настроить его онлайн — создать еще один коммуникационный интерфейс (это может быть SPI, UART, 1-wire или даже простой регистр сдвига…), через который вы записываете свою конфигурацию во внутренние регистры. Их состояния будут определять, как будут маршрутизироваться сигналы. Просто следите за тем, чтобы конфигурация всегда выполнялась в состоянии, когда устройство не считывает параллельные входы — иначе вы можете увидеть ложные импульсы (так называемые опасности) в сериализованном выводе.
Альтера или Xilinx? Что посоветуете новичку? Не только кремний, но и среда разработки?
Я не тот человек, чтобы ответить на этот вопрос - попробуйте найти его здесь, в EE, или задайте новый вопрос.
Хорошо, платы разработчика Altera Max II прибыли. Для вдохновения я рассматривал переключатели коммутации, эталонные проекты легко доступны. Но это не точное совпадение. С точки зрения архитектуры, как лучше всего реализовать такой регистр конфигурации?