|
Arinc429 на Atmega16, реально ли? |
|
|
|
Jan 14 2013, 06:13
|
Группа: Участник
Сообщений: 7
Регистрация: 14-01-13
Пользователь №: 75 185

|
Здравствуйте, есть задачка организовать приемо\передатчик протокола arinc 429 на МК (скорее всего будет задействована ATmega16 на 16Мгц), общение с ПК будет через USB на FT232, прием с шины аринка будет организован с помощью ттл микросхем которые будут преобразовывать 3х уровневый сигнал аринка в сигналы 0-5В, частота 48кГц(погрешность 5%). Основной вопрос будет ли успевать все работать, так как прием\передача будут идти паралельно ? Пытался ли кто нибудь делать такое на МК ? Буду благодарен всем кто поможет советом
|
|
|
|
|
 |
Ответов
(1 - 13)
|
Jan 15 2013, 13:29
|
Группа: Участник
Сообщений: 7
Регистрация: 14-01-13
Пользователь №: 75 185

|
Цитата(RabidRabbit @ Jan 14 2013, 13:14)  Ну примерно прикиньте: если один бит за 1/48000 секунды, то за время длительности одного бита МК успеет выполнить 16 000 000 / 48 000 примерно 333 команды. Если кроме как выполнять роль моста UART <-> arinc контроллеру больше заняться будет нечем, то по-моему вполне должен успевать. Ну я так подумал что нужно отслеживать еще кучу возможных ошибок таких как - проверять длительность импульсов, дабы ловить только нужный диапазон, првоерка четности и т.п., а также есть проблема в том что UART будет на своей скорости и пока она не известна, а аринк на 48кГц (5%), по идее нужно создавать банк памяти для приема и передачи, дабы ничего не пропало из за разности в скоростях - а это все потребует неплохих ресурсов. Может кто помочь с примерной логикой работы? Я пока думаю так - входные ноги аринка на INT0, INT1, таймер0 на 2Мгц на передачу, таймер2 на 2МГц на прием и таймер1 на 16МГц для слежения за флагами. Прерывания реагируют на входные сигналы, таймер0 проверяет длительность полупериодов, если пришли все 32 бита то запись в банк, из банка циклически вытаскиваются слова и кидаются в уарт. При приеме с ПК по прерыванию от приемника уарта, 8 битные слова записываются в банк памяти из 32 битных слов, из которого в свою очередь циклически выдаются в аринк.
|
|
|
|
|
Jan 15 2013, 17:51
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Если скорость UART будет 115200 - то всё успеете. Прерывания на мегагерцы, по-моему, не нужны (да и не успеет процессор  ) Для проверки длительности битов по-моему достаточно будет таймера, запускаемого при приёме очередного бита (ну это при условии что от Вашей схемы на TTL придут уже готовые сигналы битов 0 и 1, а это видно так и есть, раз Вы собираетесь использовать всего два входа, а не три). Прерывания от INT0, INT1, приёмника и передатчика UART, переполнение от таймера - мне кажется этого будет достаточно. Если сомневаетесь, можно применить мегу из новых серий, которые работают штатно до 20 МГц. А, да, передача - на неё ещё один таймер. Так как +- 5% то беспокоится по поводу "сбивания времянок" прерываниями наверно не стоит...
|
|
|
|
|
Jan 16 2013, 10:17
|
Частый гость
 
Группа: Участник
Сообщений: 105
Регистрация: 22-06-05
Пользователь №: 6 228

|
Делал на ADSP2185 (в ту пору сигнальный процессор, 16 бит, 80МГц). На выдачу 2 канала, на приём 3 канала – всё параллельно. Выдача реализована на SPORT – в AVR можно попробовать пристегнуть SPI. Приём: считывались 6 бит =(CLK+DATA) * 3канала (или DATA0+DATA1, уже не помню). На один канал уходило 5 бит: 4 бита на фильтр-счётчик и 1 бит результат (или м.б. 3 бита - счётчики, 1 - результат, 1 – защитный). 5 бит упаковывались в два 16-битных слова: одно на все 3 CLK и одно – на все 3 DATA (или м.б. DATA0 и DATA1) , каждое слово обрабатывалось целиком – т.е. результат наличия бит и их значений получался параллельно для 3-х входных каналов. Дальше эти результаты распихивались по 3-м каналам, но уже последовательно… Пороги задавались в виде констант, которые прибавлялись-вычитались к этим фильтрам счётчикам. Каждый канал мог работать на своей скорости. Обработка была написана на ассемблере – в ADSP он очень понятный и удобный. От ADSP2185 нужны были битовые операции. Не знаю, как в ATmega16, но в AVR32 – с этим всё очень хорошо! Обмен с HOST-ом был на уровне буферов – буферы приёма, буферы выдачи. На счёт фильтрации адресов – не помню. Т.е. производительности вполне хватило. ATmega16 – это 8бит, 16 МГц… На счёт ARINC – посмотрите компанию HOLT: http://www.holtic.com/default.aspx
Сообщение отредактировал S17 - Jan 16 2013, 10:33
|
|
|
|
|
Jan 17 2013, 10:09
|
Группа: Участник
Сообщений: 7
Регистрация: 14-01-13
Пользователь №: 75 185

|
Оцените такой вариант: Прием из аринка - Прерывания INT0, INT1 устанавливают флаги и запускают таймер0 на 1\2500000 секунды (получается примерно 50 прерываний за полупериод сигнала аринка). По прерыванию таймера мы проверяем состояние ног и считаем счетчик который сравнивается с пороговыми значениями - так мы проверяем длительность полупериодов и узнаем наступлиа ли пауза или нет. Если приняли бит то записываем его в 32битное слово, если записаны все 32 бита то проверяем четность и записываем в массив памяти. В свою очередь есть прерывание УАРТа которое постоянно циклически шлет слова из этого массива, если они есть. Передача в аринк - Если сработало прерывание УАРТа то принимаем оттуда посылки и соединяем их в 32битное слово, которое записывается в свой массив памяти, и потом запускаем таймер2 с частотой 96кГц. По прерыванию записываем слово из массива памяти во временную пременную и побитно отправляем в аринк, после 32 бита делаем паузу и дальше по циклически опрашиваем массив памяти. У меня получается все выполняется только в прерываниях... подскажите как лучше организовать программу ? Чертежик посылки, а точнее как выглядят последние 3 бита слова, пауза между словами, и первый бит нового слова. http://img13.imageshost.ru/img/2013/01/17/...f7c0b28e52d.jpg
|
|
|
|
|
Jan 18 2013, 05:45
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Ну сами посчитайте 16 000 000 / 2 500 000 = 6.4 тактов за период, что Вы успеете сделать за это время? По-моему этого не хватит даже чтобы просто войти в прерывание и сделать reti  Я Вам предлагаю по приёму очередного бита (прерывание от INT0 или INT1) запускать таймер, прерывание от которого будет больше длительности интервала между битами (на сколько, это Ваше решение). Это самое прерывание будет Вам сигнализировать, что поток битов нарушен, а программа уже решит, это признак паузы между посылками (если приняли все 32 бита) или сбой в посылке. UART с обоих сторон подцепите к кольцевым буферам, например. Расскажите лучше, как у Вас организована схема выдачи битов в аринк, также, как приём (две линии, для 0 и для 1), или три линии (+, -, 0)? То, что всё будет в прерываниях - на мой взгляд не страшно, научитесь писать лаконичный и скорострельный код  А мэйн-луп при этом может мигать светодиодом, к примеру  Ну или примените алгоритм, который предложил Сергей Борщ - вполне приятное решение, единственно, в нём меня смущает жёсткое задание скорости опроса входящих битов, хотя наверно при 32 битах и 5% может всё будет в порядке.
|
|
|
|
|
Jan 18 2013, 07:46
|
Группа: Участник
Сообщений: 7
Регистрация: 14-01-13
Пользователь №: 75 185

|
RabidRabbit Не совсем понимаю ваш вариант, т.е. он просто фиксирует превышение заданного периода посылки битов ? А что если придут несколько коротких помех за один полупериод, ониже зафиксируются как биты ? Посылка в аринк двумя линиям для 0 и 1, дальше железом преобразуется. Насчет варианта который дал Сергей Борщ - у меня теже сомнения что жесткое задание скорости в конечном счете даст сбой. Можно попробовать так: прерывания по положительному фронту INT0, INT1 запускают таймер, который проверяет состояние ножек в середине положительного полупериода и в середине отрицательного полупериода. т.е. получается сначала прерываемся на 1\4 периода, потом 1\2 периода и дальше если не сработали INT0 или INT1 то считаем по 1\2 периода и решаем пауза это или разрыв.
Сообщение отредактировал AlexandrB - Jan 18 2013, 07:50
|
|
|
|
|
Jan 18 2013, 09:10
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (AlexandrB @ Jan 18 2013, 09:46)  Насчет варианта который дал Сергей Борщ - у меня теже сомнения что жесткое задание скорости в конечном счете даст сбой. Я предложил частоту прерываний двое больше битовой скорости. Значит в первый бит вы попадете с точностью до половины битового интервала. Далее от этого места обрабатываете каждый второй отсчет начиная с третьего. За время одной посылки набег будет мизерным, а на следующей вы снова засинхронизируетесь. P.S. Подзабыл, что в ARINC битовый интервал поделен пополам и значащий уровень передается только в первой половине битовго интервала. Значит делать опрос на учетверенной частоте и обнаружив уровень отличный от IDLE обрабатывать каждый четвертый отсчет начиная с пятого, т.е. сместившись на четверть битового интервала - примерно в середину первой (значащей) половины бита. Добавлено: Возможные ошибки вы отсеете по четности. Если этого недостаточно и вы хотите более тщательный контроль с фильтрацией коротких помех - надо искать более шустрый процик или ПЛИС.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|