реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Передать блок данных с мк на мк, как лучше реализовать?
zombi
сообщение Mar 22 2016, 14:20
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Нужно в одном изделии передавать с одной xmega на другую каждую миллисекунду 12288 бит = 1536 байт.
Чем побыстрее, но не дольше чем за 200 мкс.
Оба мк тактируются от общего внешнего генератора 32MHz.
Свободных ног у каждого по 10 шт. есть.
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Mar 22 2016, 14:52
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



При 32МГц в 200мкс 6400 тактов. Как раз должно хватить на инкремент индекса и запихивание в порт.
Одну ногу дергать как клок - на приеме юзать как прерывание. Остальные 8 юзать как шину - меньше придется манипуляций делать с битами.
ЗЫ. можно даже на асме накидать. хотя сейчас компиляторы еще похлеще сделают

Сообщение отредактировал ЯadiatoR - Mar 22 2016, 14:55
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 22 2016, 15:28
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(ЯadiatoR @ Mar 22 2016, 17:52) *
Одну ногу дергать как клок - на приеме юзать как прерывание.

За 4 такта войти в прерывание чего-то там сделать и выйти обратно biggrin.gif
Цитата(ЯadiatoR @ Mar 22 2016, 17:52) *
хотя сейчас компиляторы еще похлеще сделают

не верю
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Mar 22 2016, 15:37
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



Ну вариантов определения первого байта не много - либо ожидать что дернется управляющая ножка, либо по крайней мере 1 раз перейти в прерывание. Ну да - не подумал, что пока в прерывание войдет в стэк что-нить положит и прочее... пройдут такты. Но и обработка прерывания на длительный процесс (а все 1536 байт это долго) не оч хорошая идея. Ну если прога позволяет - можно периодически проверять ножку и если есть активный сигнал вешать 10 ногу - и начинать передачу. В таком случае трансивер подождет какое-то непродолжительное время, пока ресивер увидит активный сигнал и потом без задержек начнут передачу.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 22 2016, 15:46
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(ЯadiatoR @ Mar 22 2016, 18:37) *
(а все 1536 байт это долго) не оч хорошая идея.

Почему не хорошая? очень даже ничего ведь всего-то ~200 мкс обработка.
Так и сделаю наверное.
В прерывании ресивера дёрну ногой готовности.
И дальше синхронно приму все 1536.
Спасибо за идею.
Go to the top of the page
 
+Quote Post
_pv
сообщение Mar 22 2016, 16:08
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



это если они от одного источника тактируются или от хороших стабильных генераторов,
а так за 200мкс могут и разъехаться приёмник и передатчик и к концу какой-нибудь из последних байтов будет либо два раза прочитан, либо пропущен.
Go to the top of the page
 
+Quote Post
Lerk
сообщение Mar 22 2016, 16:20
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 339
Регистрация: 5-05-11
Пользователь №: 64 797



_pv,
Цитата(zombi @ Mar 22 2016, 17:20) *
Оба мк тактируются от общего внешнего генератора 32MHz.


...
Go to the top of the page
 
+Quote Post
_pv
сообщение Mar 22 2016, 17:10
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



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

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

ну либо в начале передавать несколько байт синхронизации 0х55 0х55 .. 0х55 0х5d и потом уже в приёмнике найти окуда именно данные начались.
Go to the top of the page
 
+Quote Post
501-q
сообщение Mar 23 2016, 04:21
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296



Цитата(zombi @ Mar 22 2016, 19:20) *
Нужно в одном изделии передавать с одной 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% времени на это.

Илья

Цитата(501-q @ Mar 23 2016, 08:35) *
передавать и принимать с помощью DMA и таймеров.


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

Илья

Сообщение отредактировал 501-q - Mar 23 2016, 08:14
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Mar 23 2016, 05:21
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



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

В принципе если выдерживать эту последовательность то и вставлять nop не придется, т.к. вместо него будут выполняться полезные такты - инкремент счетчика, сброс активного сигнала управления и загрузка регистра с новым значением. Как раз на прием должно хватать. Ну если что можно довести нопами если приемник не будет успевать.
Go to the top of the page
 
+Quote Post
_pv
сообщение Mar 23 2016, 07:49
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(ЯadiatoR @ Mar 23 2016, 11:21) *
Да что вы заморачиваетесь, если обработка в прерывании устраивает (хотя я бы так не делал) то сделал бы примерно так
for(ushort i=0; i<1536;i++){
SendSignal=1;// Управляющая нога сбрасывается в 1
Portx=buf[i];
SendSignal=0;// Устанавливаем сигнал в активное состояние - для мониторинга приемником
}[/code]

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

я так понимаю без дма можно сделать только
:loop
IN REG, PORT
ST Y+, REG
RJMP loop
NOP
NOP
NOP
NOP

будет как раз четыре такта на цикл, и выходить из этого бесконечного цикла придётся по прерыванию от таймера или от внешнего, исправляя адрес возврата на стэке чтобы на те нопы после цикла выпрыгнуть
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Mar 23 2016, 07:59
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



Ну на деле есть 6400 тактов.
Конечно, компилятор развезет это на много операций. Я описал примерно алгоритм работы.
То есть вы собрались выйти из передачи только по таймеру заранее зная сколько прйдет тактов на операции?
А как будет приемник принимать данные за 3 такта? 3 такта это 93нс. Только если их соединить чуть ли не вплотную, ибо 10+МГц будет и принимать без синхронизации. Непонятно
Go to the top of the page
 
+Quote Post
501-q
сообщение Mar 23 2016, 08:48
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296



Цитата(_pv @ Mar 23 2016, 12:49) *
я так понимаю без дма можно сделать только
: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 - Mar 23 2016, 08:52
Go to the top of the page
 
+Quote Post
_pv
сообщение Mar 23 2016, 09:10
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(501-q @ Mar 23 2016, 14:48) *
Но если памяти хватает, то можно тупо повторить 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мкс.
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Mar 23 2016, 09:18
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



Ну флеш то заиспользовать не проблема - а принимать то за 2 такта как он будет? Успеет ли?
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 13th July 2025 - 10:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01501 секунд с 7
ELECTRONIX ©2004-2016