Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по алгоритму
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
bbill
День добрый.
Поставлена задача: прием последовательного кода от семи датчиков, для каждого своя линия порта. Формат передачи: старт-бит, 8 бит данных, 1 стоп. Скорость передачи 2400 или 4800 бод. Передача от датчиков НЕ синхронизирована. Сдвиг между каналами от 0 до ∞ (минуты). Старт-бит необходимо использовать для определения точной скорости передачи от датчиков (по длительности бита), т.к. разброс/временной уход? частоты различных каналов составляет до ±10%. Процессор m8 или m88, частота 8МГц. Датчики однонаправленные, не адресные, из-за расстояния (50-100м), сигнал развязывается через оптроны и на свой пин.

Вопрос: как организовать алгоритм приема посылок от датчиков, при одновременном их поступлении и сдвиге между ними менее длины посылки.

Принимаем, что первым начинается прием канала 1.

..... _________
___|..10бит.....|_____________________ - канал 1
...................__________
__________|..10бит......|_____________ - канал 2
………
......................... _________
______________|..10бит....|_________ -канал 6
............___________
______|..10бит........|_______________ - канал 7
_Bill
Цитата(bbill @ May 31 2006, 02:12) *
День добрый.
Поставлена задача: прием последовательного кода от семи датчиков, для каждого своя линия порта. Формат передачи: старт-бит, 8 бит данных, 1 стоп. Скорость передачи 2400 или 4800 бод. Передача от датчиков НЕ синхронизирована. Сдвиг между каналами от 0 до ∞ (минуты). Старт-бит необходимо использовать для определения точной скорости передачи от датчиков (по длительности бита), т.к. разброс/временной уход? частоты различных каналов составляет до ±10%. Процессор m8 или m88, частота 8МГц. Датчики однонаправленные, не адресные, из-за расстояния (50-100м), сигнал развязывается через оптроны и на свой пин.

Вопрос: как организовать алгоритм приема посылок от датчиков, при одновременном их поступлении и сдвиге между ними менее длины посылки.

Ну, так это... Есть специальны схемы многоканальных UART. Можно прицепить одну-две таких к МК без особых проблем.
bbill
Железо уже готово...
_Bill
Цитата(bbill @ May 31 2006, 10:45) *
Железо уже готово...

Ну, тогда только программно. Посмотрите на сайте Atmel AN на эту тему. Должны быть.
beer_warrior
Наверное можно поступить следующим образом:
Есть Application Software UART - если не ошибаюсь там используеться внешнее прерывание и таймер.
Внешние прерывания можно брать от PIN_CHANGE.
Таймер придеться делать софтовый
запустить один из аппаратных в режиме CTC и в прерывании инкрементировать несколько программных счетиков.
Думаю для таких скоростей хватит.

Вот в таком ключе, взяв М88 на скорости поболее, с обильным использованием асма, можно попробовать.
SasaVitebsk
Я делал аналогичное и менее оптимистичен.
1) Надо зафиксировать скорости по каналам. Иначе - не верю в успех.
2) Я бы делал на ASMе
3) Я бы делал так, как это делает аппаратный контролер на уровне железа, а именно:
a) Обрабатывал бы прерывание от таймера с частотой, как минимум в три раза выше максимальной частоты передачи. Лучше в пять!
б) в прерывании читал бы ВСЕ каналы.
в) Если 2 из 3 или 4 из 5 засвечено - единица.
г) Т.о. в прерывании формировал бы последовательность типа 1001001001 по каждому каналу.
д) Частота проца должна быть кратна rs232 и такой чтобы успеть обработать прерывание и оставался запас на голову (14372800 или 18432000)
е) В голове по входной последовательности битов формировал бы байты.
prottoss
Привет! Делал (Создавал ПО) два варианта таких устройств, в производство пошел второй вариант:



1. Наиболее дорогое. К кадому датчику цепляется мелкая Тинька, которая обеспечивает адресацию между хостом и датчиком. Тини считывает данные с определенным периодом и ждет запроса хоста. В Тиньке создается программный буфер FIFO с последними данными измерений. Если хост не успевает забрать данные, то они пропадают. Протокол обена данными наподобие MODBUS но немного более упрощенный.



2. Мене дорогое. Датчики опрашивает один МК программно в основном цикле. Все датчики сидят на одном порту МК (Датчиков 8) и опрашиваются программно с частотой, более частоты приема раз в 10 -16. Так же сохраняет данные в общем FIFO буфере. Связь с хостом по одной линии RS485 протокол - чистый MODBUS. Кроме опроса датчиков (программный асинхронный приемник) и связи с хостом (аппаратный USART) МК больше ничем не занимается.



К сожалению, исходники выложить и переслать кому-то не могу, по известным причинам...Но главное идея)))
bodja74
Да,без фиксации скорости это не реально сделать....,да и с фиксацией тоже smile.gif
Тут же получается произвольный сдвиг между посылками ,который естественно будет не кратен скорости RS.
Вам банально не хватит оперативки smile.gif
Для того чтобы считать порт на приличной скорости,а потом все это пережевать.

Делайте мультипроцессорный блок ,как советовали и не парьте головы.

Я делал на три канала,контроллеры соединял по TWI (двумя мастерами и одним слейвом) и головной боли не знал smile.gif
GetSmart
Я вас умаляю!
При желании всё это можно сделать на асме. И почти на любом АВРе. Было бы желание.
Но тут похоже одни нытики и пессимисты.
ksv198
Цитата(GetSmart @ May 31 2006, 16:24) *
Я вас умаляю!
При желании всё это можно сделать на асме. И почти на любом АВРе. Было бы желание.
Но тут похоже одни нытики и пессимисты.

Нет, почему же, хорошо информированные оптимисты. Делал подобное в 1998 на PIC16F84 на 2 канала при скорости 100 бод (всего то!). Основной проблемой было непредсказуемость начала посылки. В этом случае помочь может только увеличение числа выборок на 1 бит. Чтобы уложиться в стандартное отклонение по скорости RS232 (не более 10%) надо делать 16 выборок или больше (число взято не с потолка, посмотрите сколько выборок делают аппаратные UART- чаще всего 16, некоторые 64). Таким образом на скорости 4800 бит/с надо дергать прерывания через 13 мкс (или чаще smile.gif ). Даже для Меги на 8 МГц маловато времени остается. Так что по-моему одного желания сделать такую задачу почти на любом АВРе маловато.
_4afc_
Цитата(bbill @ May 31 2006, 03:12) *
Вопрос: как организовать алгоритм приема посылок от датчиков, при одновременном их поступлении и сдвиге между ними менее длины посылки.


1. Писать на асм.
2. Считывать весь порт сразу с частотой в 3 раза выше скорости передачи.
3. Логическими функциями отслеживать можеритарность.
4. По полученному числу выполнять от 0 до 7 обработок на соотв каналы.
Получается макс - 100000 обработок в секунду или 80 команд на обработку.
Должно хватить.
Побольше пользуйтесь таблицами и не жалейте флеш.
bodja74
Цитата(_4afc_ @ May 31 2006, 17:20) *
2. Считывать весь порт сразу с частотой в 3 раза выше скорости передачи.


И будем иметь погрешность в 33%.
Тут вообще то хотели меньше 10% иметь ,да и еще и настраиваться на скорость. smile.gif

Правильно сказал ksv198,чтобы хоть что то путное вышло нужно не меньше 16,вот и посчитайте. smile.gif
GetSmart
Да я бы сделал эту прогу баксов за 300-500.
Думаю с лёгкостью на Mege8 @ 8MHz от внутреннего RC.

В данной задаче я бы забыл о мажоритарности. Когда случайный сдвиг внутри бита будет увеличиваться, мажоритарность только помешает качеству. Измерять состояние бит данных только один раз. Однако приход стартового бита нужно анализировать часто. Не менее 16-20 раз выше скорости обмена. В идеале раз в 40. Разумеется это будет компромисс. Для возможности подстройки скорости придётся сделать хотя бы качественный электрический сигнал. А остальное не проблема.
bodja74
А я бы лучше отдал лишних 10$ за контроллеры.И никому бы ничего не платил smile.gif
Хотя, смотря какие обьемы производства нужны. smile.gif
Laksus
для bbill
Ну раз Вы перешли сюда с
http://www.fulcrum.ru/cgi-bin/bbs/mess_sel...TID=4501&page=1
мне тоже тут удобнее.
Пока нет мыслей. Еще хочу уточнить.

А как идут байты от одного датчика?
-Есть ли гарантированные паузы между байтами? Какой длины?
-Если между паузами идут группы бит, то по сколько штук в группе максимум?
-Какие прерывания еще используются в программе?
______________
Александр
2006 05 31
Laksus
И еще забыл спросить.
-А какая нестабильность по времени скорости каждого датчика?
То есть замерив скорость один раз можно ли ее использовать
через секунду, час, сутки?
Если меняется, то медленно, или скачками?
______________
Александр
2006 05 31
defunct
Цитата(_4afc_ @ May 31 2006, 17:20) *
2. Считывать весь порт сразу с частотой в 3 раза выше скорости передачи.


В три раза получается нестабильно. Пробовал.
Наилучший результат без ущерба допуску 2% - пятикратная скорость.
Пример софтового уарта в реализации на T13 выложил в "исходники программ и библиотек", при желании пример можно доработать напильником под нужды автора, тем паче скорости у него значительно меньше..
bbill
От датчика посылки поступают по одному байту, минимально возможный интервал примерно от 0,5 сек и до нескольких минут. Возможны ситуации и до суток. Между байтами тишина.
Нестабильность частоты по времени-мала, изменяется медленно, без скачков. Основное это разброс частот по датчикам порядка ±10%.
Основная задача программы - прием данных от датчиков, декодирование принятого и выдача управляющих сигналов через регистровый буфер, так что основная загрузка- это прием.
И очень прав ksv198: основная проблема это непредсказуемость начала посылок и для полного счастья отклонение частоты.
defunct
Цитата(bbill @ May 31 2006, 23:58) *
И очень прав ksv198: основная проблема это непредсказуемость начала посылок и для полного счастья отклонение частоты.

Непредсказуемость это совсем не проблема, на то и были придуманы UART'ы. А вот отклонение частоты проблема, но незначительная - рашается с помощью наименьшего общего кратного, после чего обеспечиваются пропуски отсчетов для получения требуемых bitrate'ов.
defunct
Цитата(redjin @ Jun 1 2006, 00:08) *
похоже действительно полинг нужен от 4 раз за время бода по прерыванию таймера и по мажоритарному принципу определять 1 или 0. Вроде все равно будет как сигналы расположены относительно друг друга.

Сбоить будет "нипадецки". дело в том что четырех-кратный Polling вносит ошибку 25%, что само по себе уже неприемлемо, пятикратный - 20%. Если решать задачу с помощью поллинга, то необходимо обеспечить ошибку не более 2%, что возможно только при 50-ти кратной частоте поллинга по сравнению с требуемым бод-rate'ом. А это IMHO уже накладно для AVR'ки.
mse
Цитата
Если решать задачу с помощью поллинга, то необходимо обеспечить ошибку не более 2%, что возможно только при 50-ти кратной частоте поллинга по сравнению с требуемым бод-rate'ом. А это IMHO уже накладно для AVR'ки.

Ужас!!! ;О) Четырёхкратная выборка даст только отклонение от центра "бода" на 25% "вдаль". Кого это волнует? Тем более, если озвучена разница частот 2%. Правильно реализованая процедура непринуждённо принимает поток в 8 дудок по 9600 с тройной выборкой. Асинхронно, ессно.
SasaVitebsk
Цитата(GetSmart @ May 31 2006, 15:24) *
Я вас умаляю!
При желании всё это можно сделать на асме. И почти на любом АВРе. Было бы желание.
Но тут похоже одни нытики и пессимисты.


Делал (выпускается серийно) модем. Там сделан автобод и P&P. Правда автобод грамотно работает до 230к. Частота 7372800 и однокристалка занята по самое немогу на ASM. А пишу я на ASMе с 1986 года. И проектов было ... не перечесть.

Сделать тяп/ляп - пара пустяков. Но если требуется стабильность и безошибочность, то это совсем другое. Человек говорит - датчики. Т.е. там не будет повторной передачи, запросов и CRC. Поэтому я исходил из стабильности работы изделия. В связи с этим я предлагаю - пусть будут разные скорости, но ПРИВЯЗАННЫЕ к каналам. Ну например 1,2 - 2400; 3 - 1200; 5-7 - 2400; Прога пишется таким образом что любой датчик вешается на любой канал, а потом каким-то образом осущ. конфигурация каналов. Алгоритм работы я уже предлогал. Конечно надо прислушится к мнению тех, кто уже осуществлял такие проекты. (имею ввиду увеличение числа выборок до 10-16)

Я не навязываю своё мнение, - я просто предлагаю решение, которое скорее всего выбрал бы я.
SasaVitebsk
Цитата(mse @ Jun 1 2006, 10:40) *
Цитата
Если решать задачу с помощью поллинга, то необходимо обеспечить ошибку не более 2%, что возможно только при 50-ти кратной частоте поллинга по сравнению с требуемым бод-rate'ом. А это IMHO уже накладно для AVR'ки.

Ужас!!! ;О) Четырёхкратная выборка даст только отклонение от центра "бода" на 25% "вдаль". Кого это волнует? Тем более, если озвучена разница частот 2%. Правильно реализованая процедура непринуждённо принимает поток в 8 дудок по 9600 с тройной выборкой. Асинхронно, ессно.


По поводу 2%. Чёто Вы мешаете всё в одну кучу Уважаемые. 2% Вам обеспечит кварц (внимательно пост читайте) А выборок достаточно 3 как это делает аппаратно однокристалка 8051 да и любой др. послед. порт. (3-5). Увеличение числа выборок, я лично могу обосновать только дрожанием прерывания на один-два такта. И "ловить" начало стартового импульса, - абсолютно не надо! Это лишнее. За 10 бит выборки будут ложиться очень точно одна относительно одной! Что тут непонятного?
defunct
Цитата(SasaVitebsk @ Jun 1 2006, 14:16) *
А выборок достаточно 3 как это делает аппаратно однокристалка 8051 да и любой др. послед. порт. (3-5). Увеличение числа выборок, я лично могу обосновать только дрожанием прерывания на один-два такта. И "ловить" начало стартового импульса, - абсолютно не надо! Это лишнее. За 10 бит выборки будут ложиться очень точно одна относительно одной! Что тут непонятного?

Помоему вы заблуждаетесь. Выборок в аппаратных портах - 16.
А что тут непонятного - реализуйте и увидите.

Цитата(mse @ Jun 1 2006, 10:40) *
Четырёхкратная выборка даст только отклонение от центра "бода" на 25% "вдаль". Кого это волнует?

Все верно, вносим сюда еще погрешность кварца 8Mhz для четырех выборок и погрешность вносимую длиной кода и получим еще 2-3% на бит (для 4800), что в итоге приведет к сумманой погрешности 25% + (20..30%) = 45%-55% на 10 бит, а это уже фактически один бит точно потерян. Вот и глюк.
SasaVitebsk
Цитата(defunct @ Jun 1 2006, 14:45) *
Помоему вы заблуждаетесь. Выборок в аппаратных портах - 16.
А что тут непонятного - реализуйте и увидите.


Уважаемый 'defunct'. smile.gif Вы как всегда почти правы и я не берусь спорить. Смотрел я это давно по книге. Может и заблуждаюсь. Если же верить PDF (а не верить ему сложно), то в AVR ядре действительно 16 выборок на бит, но решение принимается по трём 8-9-10 (возможно это и ввело меня в заблуждение). Если же смотреть PDF на at89c51 (книгу на неё я смотрел когда-то), то на рисунке изображено три выборки. Хотя, конечно, рисунок достаточно схематичный. Но всё-таки это АБСОЛЮТНО не меняет написанного. Если брать суть проблемы, то точность определяется кварцем. Начало импульса не нужно определять (т.е. нужно определять с точностью до выборки).

Насчёт реализуйте - увидите. Давайте не опускаться, до банального. У меня нет сейчас такой задачи. Если будет - реализую. Возможно отойду в сторону от своего алгоритма. Но я его предложил! Предложил человеку! Так в чём меня упрекают? Что-то не понимаю? Если у Вас есть свой выложите! Если есть претензии к моему - напишите! А пустых фраз "знающего человека" - не надо! Просто не красиво это.

По поводу второй части поста: Погрешность кварца составляет 0.25% и ей явно можно пренебречь. Ещё раз отмечаю не имеет значение положение относительно центра. Посмотрите PDF. Имеет значение погрешность выборок одна относительно другой - своей. Эта погрешность определяется кварцем и "плаванием прерывания" При правильно написанной проге "плавание" составит 1 максимум 2 такта. И ни какой длины кода!!! Погрешность не будет накапливаться! Подумайте сами. Погрешность кварца только накопительная!
bodja74
Три выборки на бит прекрасно подойдут для фиксированной скорости и для одного канала,
спору нет,но не для шести с произвольным сдвигом посылок и разной погрешностью +/- 10%.
Подумайте сами ,если мы прекрасно настроимся даже на один канал,у нас будет накапливаться ошибка на остальных,и достаточно не слабая.
SasaVitebsk
Цитата(bodja74 @ Jun 1 2006, 15:45) *
Три выборки на бит прекрасно подойдут для фиксированной скорости и для одного канала,
спору нет,но не для шести с произвольным сдвигом посылок и разной погрешностью +/- 10%.
Подумайте сами ,если мы прекрасно настроимся даже на один канал,у нас будет накапливаться ошибка на остальных,и достаточно не слабая.


Давай определимся. Я говорю об rs232. Это так?

Если так, то Вы так и не поняли принцип. Погрешность не зависит от числа каналов. Не надо ни на что настраиваться!

Идёт выборка с частотой в 16 раз превышающая. Ты начинаешь отсчёт. В ОДНОМ прерывании от таймера. Считываешь ВСЕ каналы. Я тебе про это писал и др. чел. тоже писал, просто уточнил что он вешил все каналы на 1 порт. Это чтобы одной командой читать. Теперь представь что первый канал попал на 10% от начала. А пятый на 70%. Ну и что. Значит следующий импульс попадёт на теже самые проценты и так пока на закончится посылка. Т.е все 10 бит!

Поскольку таймер у тебя привязан к кварцу, то погрешность вызыва прерываний не превысит погрешность кварца. Единственно что у тебя может прерывание быть задержано на 1-2 такта (если не использовать MUL и т.п.). Но эта погрешность не накапливается! Давай её посчитаем.
На частоте 14372800 такт сотавляет ~70нс. Два такта 140нс. На частоте 4800 1 бит составит 208333нс. Таким образом погрешность составит менее 1%.

Так где Вы обнаружили 25%?
Или Вам нарисовать?
bzx
to bbill
Я могу Вам сделать за определённый интерес. Обращайтесь ко мне в привате.
GetSmart
bbill
Скажите, у вас скорость связи датчиков стабильна? Как мне показалось скорость стабильна на уровне RC-генератора. То есть как мокроконтроллер, работающий от внутреннего генератора. Во времени он почти стабилен, но всё-таки скорость может отличаться на +-10% от номинальной (2400+-10%).
defunct
Цитата(SasaVitebsk @ Jun 1 2006, 16:10) *
Так где Вы обнаружили 25%?
Или Вам нарисовать?


Вопрос вероятно ко мне был.
Если отрезок в 1м длиной разбить на 4 равные части. Очевидно, что длина каждого из получившихся 4-х отрезков будет равна 25см или 25% от целого ;>

Теперь если переложить все это на задачу приема данных. Имеется некий отрезок времени T удержания передатчиком одного бита. Передатчик имеет свой допуск на стабильность этого отрезка времени - 2%.

Мы же делаем приемник. Для того чтобы бит принимался достоверно нам надо его прочитать в любой момент времени отрезка времени T. Пусть начало отрезка T соответвует 0%, а конец - 100%.

Про непредсказуемость прихода старт бита уже говорили. Т.о. в лучшем случае старт бит придет в самом начале отрезка и ошибка начального сдвига составит 0% - байт примется без вопросов.

В худшем случае старт бит придется на конец четверти отрезка и ошибка начального сдвига составит 25% . Поскольку считывание бита присходит со сдвигом по времени на дополнительных 50% от общей длительности отрезка T, то с этим сдвигом в 25% мы будет читать данные на расстоянии 75% от начала отрезка. Добавляем допуск передатчика в 2% для 10-ти бит соответвенно 2%*10 = 20%, добавляем также и собственную систематическую ошибку приемника (кварц/код) еще 2-3% (для 10-ти бит - 20-30%), а теперь суммируем все это:
25% + 50% + 20% (передатчик) + 20%..30% (приемник) = 115..125%
что явно выходит за рамки отрезка T, следовательно читать мы будем уже другой бит.


почему вообще у УАРТа допуск по стандарту 2% на один бит.
для 10 бит надо принять во внимание, что приемник делает сдвиг в 50% относительно момента прихода старт бита (потому что неизвестно направление ошибки в "плюс" или в "минус"), а общая ошибка (сдвиг момента времени считывания бита относительно начала старт бита) по допуску может достигать:
50% + 2%*10 (передатчик) + 2%*10 (приемник) = 90% т.е. для последнего 10-го бита кадра момент считывания придется на 90% от T этого бита. Гарантированный устойчивый прием.


Цитата
Насчёт реализуйте - увидите. Давайте не опускаться, до банального. У меня нет сейчас такой задачи. Если будет - реализую. Возможно отойду в сторону от своего алгоритма. Но я его предложил! Предложил человеку! Так в чём меня упрекают? Что-то не понимаю? Если у Вас есть свой выложите! Если есть претензии к моему - напишите! А пустых фраз "знающего человека" - не надо! Просто не красиво это.


Свой, доведенный до практической реализации я уже выложил.

Насчет реализуйте - увидите, имелось в виду ответ на вопрос из вышеприведенного Вашего поста:
Цитата
За 10 бит выборки будут ложиться очень точно одна относительно одной! Что тут непонятного?

Точности здесь нет: хотя выборки и будут ложиться с одинаковым интервалом, но интервал может приводить к тому, что момент выборки будет плыть относительно передатчика. Насколько там понятного и непонятного вопрос спорный, просто предложил проверить Вам реализацией. И необязательно сейчас, может когда-то потом когда у Вас будет время и интерес ;>
bodja74
Цитата(SasaVitebsk @ Jun 1 2006, 16:10) *
Идёт выборка с частотой в 16 раз превышающая. Ты начинаешь отсчёт. В ОДНОМ прерывании от таймера. Считываешь ВСЕ каналы. Я тебе про это писал и др. чел. тоже писал, просто уточнил что он вешил все каналы на 1 порт. Это чтобы одной командой читать. Теперь представь что первый канал попал на 10% от начала. А пятый на 70%. Ну и что. Значит следующий импульс попадёт на теже самые проценты и так пока на закончится посылка. Т.е все 10 бит!


16 выборок на бит ,другое дело. smile.gif
По идее можно вписатся в погрешность,вопрос остается хватит ли нам оперативки?
Если передача действительно идет,как описал автор темы,то мы даже впишемся в 320 байт.
Я думал про непрерывную передачу и однозначно решил что поллинг не проидет,так что извинямс smile.gif
На асме можно и без прерывания обойтись,если других задач не нужно,
в цикле читать порты,если какой рыпнется,сливать всю посылку в оперативку,а потом пережовывать.
Главное что бы между посылками контроллер успел обработать полученные данные.
После пережовывания опять ждать следующую посылку.
Короче ,думаю,на 16 выборках на бит сделать можно. smile.gifsmile.gifsmile.gif
bbill
GetSmart:
Схемотехника датчика мне неизвестна, да и какая разница, плясать будем от того, что есть.

Алгоритм вырисовывается примерно таков:
по появлению первой посылки c канала1(условно1) в прерывании pin chang запускаются таймера:
таймер 0 -прерывания через 80 мкс, такт опроса всего порта(всех каналов);
таймер 1 -счет с нуля и до заполнения, т.е. 65536 мкс.
По окончании старт-бита по повторному pin chang считываем со счетчиков TCNTL,H значения определяющие длину старт-бита(частоту) данного датчика. В ОЗУ пишем данные длины канала 1.
При появлении старта с других каналов также читаем данные с таймера1 о длине старт-бит.
По прерыванию с таймера0 читаем состояние порта и считаем счетчик кол-ва опросов по таймеру.
Значения накапливаем в ОЗУ. И так до окончания посылки или посылок если идут в одно время.
При самом худшем случае, если посылка 2 поступает к окончанию первой, третья к окончанию второй и т.д., на скорости 2400 заполняем ОЗУ не более 90%.
Обработка после окончания приема. Создаем таблицу времен и проводим анализ в какие промежутки времени уложились биты в каждой из посылок. В каждый бит должно укладываться 5-6 опросов порта, в зависимости от момента начала и частоты. При наличии одинаковых 4-х выборок принимаем решение о значении бита.
Прошу комментарии об ошибках или упрощениях.
SasaVitebsk
Цитата(bbill @ Jun 1 2006, 21:59) *
GetSmart:
Схемотехника датчика мне неизвестна, да и какая разница, плясать будем от того, что есть.

Алгоритм вырисовывается примерно таков:
по появлению первой посылки c канала1(условно1) в прерывании pin chang запускаются таймера:
таймер 0 -прерывания через 80 мкс, такт опроса всего порта(всех каналов);
таймер 1 -счет с нуля и до заполнения, т.е. 65536 мкс.
По окончании старт-бита по повторному pin chang считываем со счетчиков TCNTL,H значения определяющие длину старт-бита(частоту) данного датчика. В ОЗУ пишем данные длины канала 1.
При появлении старта с других каналов также читаем данные с таймера1 о длине старт-бит.
По прерыванию с таймера0 читаем состояние порта и считаем счетчик кол-ва опросов по таймеру.
Значения накапливаем в ОЗУ. И так до окончания посылки или посылок если идут в одно время.
При самом худшем случае, если посылка 2 поступает к окончанию первой, третья к окончанию второй и т.д., на скорости 2400 заполняем ОЗУ не более 90%.
Обработка после окончания приема. Создаем таблицу времен и проводим анализ в какие промежутки времени уложились биты в каждой из посылок. В каждый бит должно укладываться 5-6 опросов порта, в зависимости от момента начала и частоты. При наличии одинаковых 4-х выборок принимаем решение о значении бита.
Прошу комментарии об ошибках или упрощениях.


Мои коментарии такие ...
Мы упорно идём своим путём! smile.gif
Ну чтож. Может это даже и к лучшему!!! В конечном итоге никто за Вас прогу писать не будет. (бесплатно). А разведка "боем", - это лучший способ научиться работать самостоятельно.

Я не выражал сомнений по поводу реальности создания 7-ми канального RS232. На мой взгляд на скорости 1200 - 4800 это не сложно. Я выражал сомнение по поводу реальности автоопределения скорости по всем каналам.
Причина проста. Байт данных 0xfe на 4800, это байт данных 0xff на скорости 2400 (То же f8/fe; e6/fd). Между ними нет разницы! Поняв принцип того что я написал, Вы поймёте почему я был песимистом. smile.gif
В модеме, который я реализовывал существует префикс команды (at/AT), но датчики же не являются интелектуальными. Или датчики интелектуальны?
Если данные могут быть любыми, то скорость по стартбиту не определишь. Это сложнее делается и всё равно не гарантирует от ошибки. Я восстанавливал примерно 97%.
dimka76
от каждого датчика посылки поступают довольно редко (мин. 0.5 сек.), вот эту паузу и использовать для определения начала посылки. В m88 любую ножку можно использовать как источник внешнего прерывания. Прерывание это начало посылки, далее на время посылки запрещаем прерывание с этого пина, а по завершению приема 10 бит восстанавливаем разрешение прерывания
defunct
Цитата(bbill @ Jun 1 2006, 21:59) *
Алгоритм вырисовывается примерно таков:
по появлению первой посылки c канала1(условно1) в прерывании pin chang запускаются таймера:
таймер 0 -прерывания через 80 мкс, такт опроса всего порта(всех каналов);
таймер 1 -счет с нуля и до заполнения, т.е. 65536 мкс.
По окончании старт-бита по повторному pin chang считываем со счетчиков TCNTL,H значения определяющие длину старт-бита(частоту) данного датчика.
....
Прошу комментарии об ошибках или упрощениях.


Согласен с Александром (SashaVitebsk).

Ну и плюс мой коментарий:
Определение длины старт бита это какая-то галиматья.. Почитайте Atmel appnote "AVR304" для того чтобы иметь хоть какое-то представление о природе УАППа.
Раз длину старт бита определить нельзя, то дальше алгоритм читать бесполезно.

Цитата(dimka76 @ Jun 2 2006, 13:51) *
от каждого датчика посылки поступают довольно редко (мин. 0.5 сек.), вот эту паузу и использовать для определения начала посылки. В m88 любую ножку можно использовать как источник внешнего прерывания. Прерывание это начало посылки, далее на время посылки запрещаем прерывание с этого пина, а по завершению приема 10 бит восстанавливаем разрешение прерывания

Здесь абсолютно верный ход мысли.


Как бы вашу задачу решал я:
1. Завел бы таймер на генерацию прерывания с частотой 4800 * 5 Гц.
2. Разрешил бы PinChange int по N каналам.
3. Завел бы счетчик текущего бита для каждого канала.
4. Завел бы номер цикла чтения бита для каждого канала.
5. Завел бы флаг приема для каждого канала.
6. По прерыванию PinChange считывал бы весь порт.
7. В обработчике прерывания анализировал бы значения каналов для которых не ведется прием.
8. При обнаружении старт-бита устанавливал бы флаг "ведется прием" для этого канала, одновременно внес бы в номер цикла чтения бита - номер текщего цикла +2.
9. В обработчике таймера - первым делом считывал бы значение всех каналов.
10. В обработчике таймера увеличивал бы номер текущего цикла "циклически" (0, 1, 2, 3, 4, 0, 1 ... ).
11. При условии ("установлен флаг приема" AND (номер цикла = текущий цикл)) заносил бы приянтый бит с канала в сдвиговый регистр и увеличивал бы счетчик текущего бита.
12. Если счетчик текущего бита = 9, то сбрасывал бы флаг приема.
13. Заносил бы принятый байт в буфер канала если 9-й бит = 1 (стоп бит распознан) .

14. Проверил бы работу N каналов на одной скорости.
15. При НЕУСПЕШНОМ прохождении теста - правил бы баги, до тех пор пока все каналы не заработают.
16. При успешном прохождении теста внес бы переменную "делитель скорости" для каждого канала.
17. В пункт 11 внес бы коррективу с учетом "делителя скорости".
18. Проверил бы работу N каналов на разных скоростях.

все.
GetSmart
Оказывается я так и не написал важную мыслю. Хотя мне казалось что писал на 1-2 странице. Мысля такая:

Чтобы по старт-биту определять скорость передачи нужно либо его поделить пополам на пол-бита 0 и пол-бита 1. А я бы сделал два стартовых бита 0 и 1. А для совместимости со стандартным УАРТом передавал бы байты с всегда установленным младшим битом, в которых было бы только 7 бит произвольных данных.
defunct
Цитата(GetSmart @ Jun 2 2006, 23:28) *
Чтобы по старт-биту определять скорость передачи нужно либо его поделить пополам на пол-бита 0 и пол-бита 1. А я бы сделал два стартовых бита 0 и 1.

и с чем бы это дело было совместимо интересно? ;>
хотя идея практичная.

Но не проще ли просто забить скорости каналов в EEPROM или выставлять джамперами.
GetSmart
Цитата
и с чем бы это дело было совместимо интересно? ;>

Ну как... Передавая по обычному UART байт с всегда установленным младшим битом мы имеем два стартовых бита 0 и 1, 7 бит данных и стоп бит. Это я имел ввиду. Так в самом начале можно определить скорость.

А насчёт джамперов... Я до сих пор не понял постановку задачи. Что это за объяснение:
Цитата
Схемотехника датчика мне неизвестна, да и какая разница, плясать будем от того, что есть.

Непонятно, скорость стабилизирована кварцем? Может принимать только стандартные значения? Или вообще любая +-200% с шагом до 1%. Непонятно!
bbill
Я перечитал текст своего вопроса: Формат передачи: старт-бит, 8 бит данных, 1 стоп. Скорость передачи 2400 или 4800 бод.
Фраза с разночтением. Скорость у всех датчиков одинакова или 2400, или 4800. Переключается.

Еще мне минус, в конфе fulcruma я указал на уточнение облегчающее мне жизнь: данные в посылке занимают 7 бит, старший бит нулевой, ВСЕГДА. Поэтому мне очень удобно измерять длительность старт-бита. Скорость дрейфует очень медленно, а разброс, читай скорость, фактически измеряется.

SasaVitebsk внимательно прочитал ваше сообщение:
1) Надо зафиксировать скорости по каналам. Иначе - не верю в успех.
2) Я бы делал на ASMе
3) Я бы делал так, как это делает аппаратный контролер на уровне железа, а именно:
a) Обрабатывал бы прерывание от таймера с частотой, как минимум в три раза выше максимальной частоты передачи. Лучше в пять!
б) в прерывании читал бы ВСЕ каналы.
в) Если 2 из 3 или 4 из 5 засвечено - единица.

Мой путь как-то не очень отличается от приведенного выше.
Если скорости хватит, то можно проводить обработку во время приема.

С предполагаемого m8, принял m88 из-за наличия pin chang. До сих пор не применял. Из-за расположения адресов в пространстве во многих обращениях к портам используется по два такта. Скорость то падает вдвое, чем лучше новый m88 старого m8? Ну это так...
defunct
Цитата(GetSmart @ Jun 3 2006, 00:02) *
Цитата
Схемотехника датчика мне неизвестна, да и какая разница, плясать будем от того, что есть.

Непонятно, скорость стабилизирована кварцем? Может принимать только стандартные значения? Или вообще любая +-200% с шагом до 1%. Непонятно!

Я думаю здесь "схемотехника датчика неизвестна" можно трактовать как - "датчик покупной". А покупной датчик обязан придерживаться стандартного допуска к отклонению (2%).

Цитата
Еще мне минус, в конфе fulcruma я указал на уточнение облегчающее мне жизнь: данные в посылке занимают 7 бит, старший бит нулевой, ВСЕГДА. Поэтому мне очень удобно измерять длительность старт-бита.

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

Вы пример(здесь) хоть скачали и посмотрели уже?
GetSmart
Да, pin chang намного жизнь упростит. Именно он должен обнаруживать поступление первого стартового бита.

С такой постановкой задачи действительно хватит 3-5 выборок на бит.

Цитата
Скорость то падает вдвое, чем лучше новый m88 старого m8? Ну это так...

Думаю это не так. Я почти уверен, что скорость чтения портов у обоих процов одинаковая.
bbill
Не знаю схемотехнику датчиков, залиты, есть разъем и параметры выходных сигналов. И все. Все вопросы к заказчику...., моему.

Знаком я с УАПП. Но если присутствует разброс по скорости, как привязаться? И дрейф. Измеряя длительность старт-бита я привязываюсь точно. Так и поступал когда работал с одним или двумя датчиками.
Мне кажется все потеряли условие: разброс скоростей датчиков от номинала ±10%, а не разные скорости. Или не правильно выразился, как написал.

defunct
Я принял примерно тоже, но так подробно не расписывал. Вот только не уверен, что успею обработать прием по ходу, поэтому скидываю в буфер.

10. В обработчике таймера увеличивал бы номер текущего цикла "циклически" (0, 1, 2, 3, 4, 0, 1 ... ).
Это 4800*5 и счетчик. Я правильно понял.

Цитата(defunct @ Jun 3 2006, 00:23) *
Цитата(GetSmart @ Jun 3 2006, 00:02) *

Цитата
Схемотехника датчика мне неизвестна, да и какая разница, плясать будем от того, что есть.

Непонятно, скорость стабилизирована кварцем? Может принимать только стандартные значения? Или вообще любая +-200% с шагом до 1%. Непонятно!

Я думаю здесь "схемотехника датчика неизвестна" можно трактовать как - "датчик покупной". А покупной датчик обязан придерживаться стандартного допуска к отклонению (2%).

Цитата
Еще мне минус, в конфе fulcruma я указал на уточнение облегчающее мне жизнь: данные в посылке занимают 7 бит, старший бит нулевой, ВСЕГДА. Поэтому мне очень удобно измерять длительность старт-бита.

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

Вы пример(здесь) хоть скачали и посмотрели уже?
Самое "смешное", после старт-бита идет старший и в инверсном коде. Это наверное роли не играет, протокол дан.
defunct
Цитата(bbill @ Jun 3 2006, 01:10) *
Самое "смешное", после старт-бита идет старший и в инверсном коде. Это наверное роли не играет, протокол дан.

Самое "смешное", что протокол дан Вам, а на обсуждение вы его не представили. И это действительно смешно.

Последнее Ваше уточнение является определяющим. Теперь точно можно сказать, что задача поставленная в первом посте - решаема на AVR как есть, с автоопределением скоростей. Только для отклонений в +-10% придется брать не 5 и тем более не 3 отстчета, а хотя бы 15-25 отсчетов. Опорная частота таймера (4800 * 15) - (4800 * 25) Гц... Столько отсчетов просто необходимо для компенсации 10% отклонения передатчика, которое для 10-ти бит выливается в +-100% отклонение. Соответвенно частота МК у вас должна быть не 8Mhz, а как можно выше - 14.7456 - 20Mhz чтобы справляться с этой задачей.

Цитата
Это 4800*5 и счетчик. Я правильно понял.

да правильно, счетчик момента считывания, моментов всего 5 т.к. частота завышена в 5 раз,
только это для допуска 2%, у вас же допуск отклонения 10% соответвенно моментов должно быть больше в 10%/2% раз. И алгоритм приведенный выше придется подкорректировать (номера п. соответвуют вышеприведенному посту):
1. Таймер завести на 4800*15 гц
1.1. Добавить байт-коррекции цикла считывания.
8.1. При обнаружении старт-бита установить флаг "ведется прием" для этого канала,
8.2. одновременно установить номер цикла чтения бита как номер текщего цикла +7.
8.3. Определить количество циклов удержания старт-бита.
8.4. Записать байт-коррекции номера цикла чтения бита для текущего канала как: "15 - (минус) количество циклов удержания старт-бита".

11.1 При условии ("установлен флаг приема" AND (номер цикла = текущий цикл)) занести принятый бит с канала в сдвиговый регистр и увеличить счетчик текущего бита.
11.2. Подправить "номер цикла чтения бита" на величину хранящуюся в байте-коррекции канала.

пп 14-17 - удалить.

остальные пункты без изменений.
GetSmart
10% ???
Это очень подозрительно. Обычно 2..5%, но чтобы 10 ? Ведь 10%*10бит = 100%, а это уже ошибка. Что-то здесь не так. И протокол ещё какой-то странный!?
SasaVitebsk
Цитата(bbill @ Jun 3 2006, 00:18) *
Я перечитал текст своего вопроса: Формат передачи: старт-бит, 8 бит данных, 1 стоп. Скорость передачи 2400 или 4800 бод.
Фраза с разночтением. Скорость у всех датчиков одинакова или 2400, или 4800. Переключается.

Еще мне минус, в конфе fulcruma я указал на уточнение облегчающее мне жизнь: данные в посылке занимают 7 бит, старший бит нулевой, ВСЕГДА. Поэтому мне очень удобно измерять длительность старт-бита. Скорость дрейфует очень медленно, а разброс, читай скорость, фактически измеряется.

SasaVitebsk внимательно прочитал ваше сообщение:
1) Надо зафиксировать скорости по каналам. Иначе - не верю в успех.
2) Я бы делал на ASMе
3) Я бы делал так, как это делает аппаратный контролер на уровне железа, а именно:
a) Обрабатывал бы прерывание от таймера с частотой, как минимум в три раза выше максимальной частоты передачи. Лучше в пять!
б) в прерывании читал бы ВСЕ каналы.
в) Если 2 из 3 или 4 из 5 засвечено - единица.

Мой путь как-то не очень отличается от приведенного выше.


Это означаетодно из двух. Либо Вы не умеете читать, либо я не умею писать. smile.gif Давайте выберем второе. Итак в третий раз старик забросил свои сети ...

Разница в алгоритме СУЩЕСТВЕННАЯ. Я исходил из того что датчики независимы. Это значит, что даже если посылка происходит раз в несколько минут, то всё равно наступит момент когда прерывание от одного не закончится, а от второго поступит.
Т.о. может поступить посылка от двух и более датчиков. И если их обрабатывать по прерыванию, то те посылки которые предут "не вовремя" не будут обработаны должным образом.
Моему алгоритму - данное не страшно.

Итак ещё раз.
1) Инициализируем ОДНО прерывание от таймера с частотой 1/16 от максимальной частоты посылки.
2) В НАЧАЛЕ прерывания (до ветвлений) читаем все порты.
3) Если хотите определять старт бит, то пожалуйста определяйте примерно так.
(Данная работа выполняется не с портом, а со считанными данными по каждому порту)
3.1) Если посылки не было, то проверяем 0/1 и если 0, - то помечаем номер такта посылки как нулевой такт (начинаем отсчёт тактов по каждому каналу)
3.2) Если посылка идёт, то смотрим какой такт и какой бит сверяем бит и считаем длину бита если равна 16, то переходим к след биту.
(для более низкой скорости - 32)
3.3) Если прошло 10 бит, то формируем байт и выставляем признак готовности данных по данному каналу. (Или "загоняем" его в кольцевой буффер канала)
3.4) Сбрасываем признак того что идёт посылка.

При таком подходе Вы можете принимать данные от N каналов одновременно.

Данный подход не исключает возможность автоопределения частоты. Просто размеры битов Вы будете видеть в тактах прерывания.

Откуда у Вас данный расчёт по занятому ОЗУ - можно только гадать. Я со своим опытом работы предсказать не берусь.
Но я бы весь сигнал загонял в озу и работал бы в голове. Думаю что озу m8 Вам за глаза. Если не делать сжатие "на лету". smile.gif
bbill
Это говорит о том, что я излагаю совсем не точно на бумаге, ну есть такое.
dimka76
А что это за датчики такие интересные, передают данные когда захотят ?
("пауза может быть 0.5 сек, час и до суток")
SasaVitebsk
Цитата(dimka76 @ Jun 5 2006, 09:11) *
А что это за датчики такие интересные, передают данные когда захотят ?
("пауза может быть 0.5 сек, час и до суток")

Это же не принципиально. Если они не СИНХРОНИЗИРОВАНЫ, т.е. не связаны м/у собой или не отвечают по запросу, то всегда возможна ситуация с перекрыванием ответов. Т.н. коллизия. Вероятность её возникновения есть фактически дробь где в числителе время посылки умноженное на количество датчиков а в знаменателе период м/у поступлениями посылки. Но важно только одно, что она отлична от 0. И следовательно её надо обрабатывать.
dimka76
Цитата(SasaVitebsk @ Jun 5 2006, 17:51) *
Цитата(dimka76 @ Jun 5 2006, 09:11) *

А что это за датчики такие интересные, передают данные когда захотят ?
("пауза может быть 0.5 сек, час и до суток")

Это же не принципиально. Если они не СИНХРОНИЗИРОВАНЫ, т.е. не связаны м/у собой или не отвечают по запросу, то всегда возможна ситуация с перекрыванием ответов.


С этим все понятно и нет вопросов.
Вопрос в том, почему интервал между посылками не постоянен и от чего он зависит?
defunct
Цитата(dimka76 @ Jun 6 2006, 14:49) *
Вопрос в том, почему интервал между посылками не постоянен и от чего он зависит?

Может и ни от чего не зависеть... Какая принципиальная разница? Соединение точка-точка хорошо тем, что не требует никакой синхронизации. И позволяет инициализировать посылку данных в произвольный момент времени.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.