Перейти к содержанию
    

Передать блок данных с мк на мк

Нужно в одном изделии передавать с одной xmega на другую каждую миллисекунду 12288 бит = 1536 байт.

Чем побыстрее, но не дольше чем за 200 мкс.

Оба мк тактируются от общего внешнего генератора 32MHz.

Свободных ног у каждого по 10 шт. есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При 32МГц в 200мкс 6400 тактов. Как раз должно хватить на инкремент индекса и запихивание в порт.

Одну ногу дергать как клок - на приеме юзать как прерывание. Остальные 8 юзать как шину - меньше придется манипуляций делать с битами.

ЗЫ. можно даже на асме накидать. хотя сейчас компиляторы еще похлеще сделают

Изменено пользователем ЯadiatoR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Одну ногу дергать как клок - на приеме юзать как прерывание.

За 4 такта войти в прерывание чего-то там сделать и выйти обратно :biggrin:

хотя сейчас компиляторы еще похлеще сделают

не верю

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(а все 1536 байт это долго) не оч хорошая идея.

Почему не хорошая? очень даже ничего ведь всего-то ~200 мкс обработка.

Так и сделаю наверное.

В прерывании ресивера дёрну ногой готовности.

И дальше синхронно приму все 1536.

Спасибо за идею.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это если они от одного источника тактируются или от хороших стабильных генераторов,

а так за 200мкс могут и разъехаться приёмник и передатчик и к концу какой-нибудь из последних байтов будет либо два раза прочитан, либо пропущен.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да, действительно.

тогда проблем не должно быть, только у передатчика надо количество nopов подобрать между синхроимпульсом и началом передачи данных, чтобы приёмник в прерывание запрыгнул и принимать начал в нужной фазе по середине.

 

хотя у xmegi есть вроде и по 4ре такта команды, так что джиттер входа в прерывание может быть большим и может понадобится дополнительная синхронизация через таймер в режиме захвата если он случайно среди тех 2 оставшихся ног оказался.

 

ну либо в начале передавать несколько байт синхронизации 0х55 0х55 .. 0х55 0х5d и потом уже в приёмнике найти окуда именно данные начались.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно в одном изделии передавать с одной xmega на другую каждую миллисекунду 12288 бит = 1536 байт.

Чем побыстрее, но не дольше чем за 200 мкс.

Оба мк тактируются от общего внешнего генератора 32MHz.

Свободных ног у каждого по 10 шт. есть.

Т.е. шина должна быть способна прокачать 7.5 МБ в секунду. Ну, наверное можно попробовать. У меня есть работающее решение, но там всего 16 байтов в пакете. Передатчик и приёмник тактируются одним сигналом (32МГц), передача пакета синхронизируется внешним (по отношению к передатчику и приёмнику) сигналом. Приём и передача выполняется без сигнала строба. Каждые 3 такта принимаю байт.

 

Такие большие пакеты я бы попробовал передавать и принимать с помощью DMA и таймеров. Синхронный запуск передачи и приёма решаем. Лишь бы у каждого был свободный порт целиком. Кроме того, нужно проверить влияние конфликтов доступа к памяти со стороны DMA и ядра.

 

Впрочем, и на асме можно:

; приёмник
.rep 1536
   in r16, PORTx_PIN
   st Z+, r16
   nop
.endr

; передатчик
.rep 1536
  ld r16, Z+
  out PORTy_OUT, r16
.endr

Если будет менее трёх тактов, то приём, я думаю, будет нестабильным, т.к. на установку бита в схеме приёма микроконтроллера нужно два такта.

 

Я то вместо nop'а полезную работу ещё выполняю: данные идут со скоростью 1.5 МБ в секунду и их нужно обработать (терять 16 тактов каждые 10 мкс -- непозволительная роскошь, это же 5% времени).

 

Ну и если пакеты идут раз в мс, то на синхронизацию будешь тратить в сто раз меньше, чем я. А я трачу как раз около 10% времени на это.

 

Илья

 

передавать и принимать с помощью DMA и таймеров.

 

Вспомнил. Может не получиться. Надо уточнять минимальный цикл DMA. Он запросто может быть больше пяти тактов.

 

Илья

Изменено пользователем 501-q

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да что вы заморачиваетесь, если обработка в прерывании устраивает (хотя я бы так не делал) то сделал бы примерно так (помойму в атхмеге есть команда на изменение значения 1 ноги):

1. на приемнике прерывание на управляющей ноге по спаду сигнала

Это код для передатчика, для приемника будет похожий, но с обработкой 1 прерывания и мониторингом состояния активного сигнала.

SendSignal=1;//Устанавливаем активный сигнало о готовности к передаче;
while(ReadyToSend);// Тут ожидаем от 10 ноги сигнала, тчо приемник вошел в прерывание и готов принимать. Можно тут добавить еще пожарный таймер, что бы вышел из цикла если долго ожидает.
for(ushort i=0; i<1536;i++)
{
    SendSignal=1;// Управляющая нога сбрасывается в 1
    Portx=buf[i];
    SendSignal=0;// Устанавливаем сигнал в активное состояние - для мониторинга приемником
}

В принципе если выдерживать эту последовательность то и вставлять nop не придется, т.к. вместо него будут выполняться полезные такты - инкремент счетчика, сброс активного сигнала управления и загрузка регистра с новым значением. Как раз на прием должно хватать. Ну если что можно довести нопами если приемник не будет успевать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да что вы заморачиваетесь, если обработка в прерывании устраивает (хотя я бы так не делал) то сделал бы примерно так

for(ushort i=0; i<1536;i++){

SendSignal=1;// Управляющая нога сбрасывается в 1

Portx=buf;

SendSignal=0;// Устанавливаем сигнал в активное состояние - для мониторинга приемником

}[/code]

скомпилируйте это и посмотрите что получится, напомню у ТС есть всего 4 такта

 

я так понимаю без дма можно сделать только

:loop

IN REG, PORT

ST Y+, REG

RJMP loop

NOP

NOP

NOP

NOP

 

будет как раз четыре такта на цикл, и выходить из этого бесконечного цикла придётся по прерыванию от таймера или от внешнего, исправляя адрес возврата на стэке чтобы на те нопы после цикла выпрыгнуть

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну на деле есть 6400 тактов.

Конечно, компилятор развезет это на много операций. Я описал примерно алгоритм работы.

То есть вы собрались выйти из передачи только по таймеру заранее зная сколько прйдет тактов на операции?

А как будет приемник принимать данные за 3 такта? 3 такта это 93нс. Только если их соединить чуть ли не вплотную, ибо 10+МГц будет и принимать без синхронизации. Непонятно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я так понимаю без дма можно сделать только

:loop

IN REG, PORT

ST Y+, REG

RJMP loop

NOP

NOP

NOP

NOP

 

будет как раз четыре такта на цикл, и выходить из этого бесконечного цикла придётся по прерыванию от таймера или от внешнего, исправляя адрес возврата на стэке чтобы на те нопы после цикла выпрыгнуть

 

С прерыванием от таймер -- это тоже хорошо. И, кстати, в икс-меге обязательно нужно возвращаться из прерывания (но не обязательно в то же место, где прерывание начали обрабатывать; в меге можно было бы вообще не возвращаться из прерыания от таймера, а только убрать адрес возврата из стека).

 

Но если памяти хватает, то можно тупо повторить 1536 раз фрагмент:

in reg, PORT_PIN

st Y+, reg

rjmp 1f

1:

 

Вот так:

.rep 1536

in reg, PORTx_PIN

st Y+, reg

rjmp 1f

1:

.endr

 

Если устраивает три такта на передачу байта, то rjmp заменить на nop.

 

Илья

Изменено пользователем 501-q

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но если памяти хватает, то можно тупо повторить 1536 раз фрагмент:

in reg, PORT_PIN

st Y+, reg

rjmp 1f

1:

 

Вот так:

.rep 1536

in reg, PORTx_PIN

st Y+, reg

rjmp 1f

1:

.endr

Если устраивает три такта на передачу байта, то rjmp заменить на nop.

 

от прерывания по таймеру из цикла придётся выходить на передатчике, на приёмнике можно таймер сэкономить и заканчивать по внешнему прерыванию от передатчика.

и что-то не припомню наличие аппаратных циклов у xmegи, то есть вот этот макрос .rep он не бесплатный, а всё равно развернётся в dec и brne, так что тактов на нормальный цикл там в любом случае не хватит.

а вот ценой нескольких кб флэша цикл можно действительно полностью развернуть, и передать всё за пару тактов на байт или за ~100мкс.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну флеш то заиспользовать не проблема - а принимать то за 2 такта как он будет? Успеет ли?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...