|
Передать блок данных с мк на мк, как лучше реализовать? |
|
|
|
Mar 22 2016, 15:46
|

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

|
Цитата(ЯadiatoR @ Mar 22 2016, 18:37)  (а все 1536 байт это долго) не оч хорошая идея. Почему не хорошая? очень даже ничего ведь всего-то ~200 мкс обработка. Так и сделаю наверное. В прерывании ресивера дёрну ногой готовности. И дальше синхронно приму все 1536. Спасибо за идею.
|
|
|
|
|
Mar 22 2016, 16:20
|
Местный
  
Группа: Свой
Сообщений: 339
Регистрация: 5-05-11
Пользователь №: 64 797

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

Группа: Участник
Сообщений: 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
|
|
|
|
|
Mar 23 2016, 05:21
|

Местный
  
Группа: Свой
Сообщений: 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 не придется, т.к. вместо него будут выполняться полезные такты - инкремент счетчика, сброс активного сигнала управления и загрузка регистра с новым значением. Как раз на прием должно хватать. Ну если что можно довести нопами если приемник не будет успевать.
|
|
|
|
|
Mar 23 2016, 07:49
|
Гуру
     
Группа: Свой
Сообщений: 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 будет как раз четыре такта на цикл, и выходить из этого бесконечного цикла придётся по прерыванию от таймера или от внешнего, исправляя адрес возврата на стэке чтобы на те нопы после цикла выпрыгнуть
|
|
|
|
|
Mar 23 2016, 08:48
|
Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Mar 23 2016, 09:10
|
Гуру
     
Группа: Свой
Сообщений: 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мкс.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|