определение скорости UART спомощу ардуино

APJ
Offline
Зарегистрирован: 25.03.2015

Ок, буду пробовать. Пока ничего дельного не выходит

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

APJ, у вашей задачи есть типовое решение.  Почти как сказал andriano, но не совсем. Запускающая функция читает первое значение, и программирует через это время прерывание. В прерывании читается следущее значение и программируется под него таймер, и так пока весь массив не будет обработан.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax, пока будет вызвано "следующее прерывание", пока функция считает и проанализирует очередные данные и т.п. - пройдет время.

Я не знаю, сколько тактов уходит в AVR на вызов прерывания (в stm32 гордятся, что у них всего 12 тактов), положим, порядка 1 мкс, еще пару уйдет на дальнейшее (для сравнения - digitalWrite() выполняется 7 мкс), т.е. к периоду в 60 мкс добавится еще несколько. IMHO точность задания интервалов будет ниже, чем в предложенном мной способе. Хотя, загрузка процессора прерываниями (т.е. доля времени, проводимая в них), конечно, меньше.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Я бы, может, и оценил мысль, если бы знал, что такое туглинг (гугл на запрос предлагает "туннелирование"). Однако "там все быстро" отнюдь не опровергает моего тезиса, что на каждом прерывании добавляется 2-3 лишних микросекунды. Для кото-то это "быстро", а для кото-то это 4-5%. А в массив, естественно, кладется то, что удобнее для данногослучая. Напрример, в описанном мною случае кладутся не такты таймера, а количество прерываний, которое надо пропускать.

Кстати, вспомнил, я, оказывается, делал как раз так, как написал. Только период опроса чуть поменьше, и управление не 1, а 7 устройствами. http://arduino.ru/forum/proekty/floppy-hdd-music

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano,  Это я некорректно произношу  toggling  (Toggle on compare match mode) , у кого-то услышал это каверканье, и привязалось, знаю, надо переучиваться по-правильному :-)

А дисководную музыку помню, да) Там конечно лишние микросекунды погоды не делают.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

А дисководную музыку помню, да) Там конечно лишние микросекунды погоды не делают.

Ни фига себе не делают!

6% - полутон.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano, Об чём вы? Ну возьмём например "ля" 440Гц, или >2000uS.  Пару микросекунд тут не решат. Конечно чем выше частота, тем... но так дисководы и не умеют как скрипочка пиликать)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

И вообще, мне кажется, уместнее оперировать конкретными числовыми оценками, а не категориями "там все быстро" и "ничего не решает".

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andriano, про ноты речь шла применительно к вашим дисководным звукам.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

намек понял

 

Тем не менее, советую AКJ заглянуть по приведенной мной ссылке - как раз для его задачи там содержится не только подходящее, но даже масштабируемое решение.

APJ
Offline
Зарегистрирован: 25.03.2015

[quote=andriano]

Уже заглянул. Пока что ничего не понял.

Logik
Offline
Зарегистрирован: 05.08.2014

andriano пишет:

Я не знаю, сколько тактов уходит в AVR на вызов прерывания

Если с ардуины -то вход выход в прерывание порядка в сумме 60-80 команд. Грубо говоря 100-120 тактов. Возможно в последних версиях быстрей.  Если на голом си то в разы менше.

Но тут еще надо помнить что таймер может выставить флаг прерывания во время работы обработчика другого прерывания, uart например, и пока тот не кончится - обработчик таймера не стартанет. Или еще где прерывание запретят на какое время. Вобщем 60мксек - неудобный интервал, с какой стороны не подступись.

Кстати, а чего таймером 60мксек делать? Там требуется 120, 300, 400 - вот их сразу и формировать, чтоб лишний раз не дергатся. А научившись настраиватся на 60 не так уж трудно и на переменную длительность сделать, только настраивать таймер так, чтоб не терялось время от завершения предыдущего интервала до момента настройки.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Logik пишет:

Вобщем 60мксек - неудобный интервал, с какой стороны не подступись.

Кстати, а чего таймером 60мксек делать? Там требуется 120, 300, 400 - вот их сразу и формировать, чтоб лишний раз не дергатся.

Там не было 400, было 480. 60 - наибольший общий делитель.

Buzoff
Offline
Зарегистрирован: 03.04.2018

dimax пишет:

Buzoff,   кстати забыл сказать - некоторые модели stm32 имеют аппаратный автодетект скорости uart :) Правда в "народной" серии F103 к сожалению  нету.

а не вкурсе, какой там алгоритм определения? может есть какие-то моменты, которые помогут с большей вероятностью определять правильную скорость с помощу атмеги.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Buzoff, не в курсе. Наверняка есть какие-то документы на этот счёт на сайте st, поищите.  В любом случае нужно измерять длительность старт-бита. На меге измерить единицы микросекунд в принципе трудно, а без применения ассемблера так вообще вряд ли возможно, почитайте про мои  тесты в ветке про микрос.

Buzoff
Offline
Зарегистрирован: 03.04.2018

dimax пишет:

Buzoff пишет:

способ с таймером может реагировать на смену значения на порту, с LOW на HIGH и наоборот одновременно (по аналогии с прерыванием CHANGE)? 

Может, но с нюансом - либо одно, либо другое. Логика выбирается  битом ICES (Input Capture Edge Select). Но это не проблема, в своём примере я как раз  ловлю и так и эдак именяя этот бит, обратите внимание на комменты в функции rising(falling) icp detect.

я правильно понимаю, что функция uint16_t asm_func() будет делать подсчет, только в момент обращения к ней, и на некоторое время будет останавливать основной код (пока будет ожидать импусы)?

и для того чтоб она делала подсчет по факту наличия импульса, нужно использовать внешнее прерывание?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Buzoff, Да, верно понимаете.

Buzoff
Offline
Зарегистрирован: 03.04.2018

dimax пишет:

Buzoff, Да, верно понимаете.

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

как вариант думал, по первому внешнему прерыванию запустить цикл на некоторое время и крутить данную функцию, собирая данные в массив.

или может есть какая-то возможность подсчитывать такты между каждым внешним прерыванием, как это делается с МИКРОС, сранивая новое и старое значение

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Buzoff пишет:

тогда если я буду обращатся к функции по внешнему прерыванию, то скорее всего первый импульс она пропустит и будет ждать следующий

Балинн.. вы плохо прочли.  Если вы хотите измерять микросекунды -забудьте про прерывания. Я же писал, что 700nS уходит только что б зайти в голое прерывание. Пока дойдёт дело до измерения стартовый бит уже проскочит. Вообще тема изначально тупиковая, на AVR такое бессмысленно мутить.  Справиться с задачей сможет таймер в stm32, он без всяких прерываний может измерять  импульс. А если брать стм32 -то сразу ту модель, которая с автодетктом. Задача сама собой отпадёт.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Хотя может и не всё так плохо, заглянул в апноут от стм, там есть вариант софтового измерения. Предлагают измерять целый пакет, и потом вычислять скорость. Есть пример, но не ардуино френдли :)

Buzoff
Offline
Зарегистрирован: 03.04.2018

dimax пишет:

Buzoff пишет:

тогда если я буду обращатся к функции по внешнему прерыванию, то скорее всего первый импульс она пропустит и будет ждать следующий

Балинн.. вы плохо прочли.  Если вы хотите измерять микросекунды -забудьте про прерывания. Я же писал, что 700nS уходит только что б зайти в голое прерывание. Пока дойдёт дело до измерения стартовый бит уже проскочит. Вообще тема изначально тупиковая, на AVR такое бессмысленно мутить.  Справиться с задачей сможет таймер в stm32, он без всяких прерываний может измерять  импульс. А если брать стм32 -то сразу ту модель, которая с автодетктом. Задача сама собой отпадёт.

я это все понимаю, но мне не нужно измерять импульсы в пару микросек.

самый короткий импуль, который мне нужно засечь - 8мкс (115200бод), но не с погрешностью +/- 4, как у микрос. 

ладно, пока поэксперементирую с вашив кодом, посмотрю, что вообще получается.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Buzoff, кстати а как вы измеряли то, по какой методике? Там ведь полно граблей. Вот например если послать ноль по сериалу, то все биты слипнутся в лог.ноле, и будет один большой импульс. Получается нужно какое-то время на ожидание  всей посылки..

 

Buzoff
Offline
Зарегистрирован: 03.04.2018

dimax пишет:

Buzoff, кстати а как вы измеряли то, по какой методике? Там ведь полно граблей. Вот например если послать ноль по сериалу, то все биты слипнутся в лог.ноле, и будет один большой импульс. Получается нужно какое-то время на ожидание  всей посылки..

ну когда использовал прерывание, я записывал все полученые интервалы в массив на протяжении 100мс (время обусловлено спецификой устройства на котором пытаюсь определять скорость), а потом анализирую полученый массив. устройства шлют пакеты байт, на практике пока не анализировал, но я надеюсь что там будут присутствуют такие очередности бит как 010 и 101. аналогично хочу поробовать и с таймером, в определенный момент запустить цикл на теже 100мс и крутить вашу функцию. полученные показания тоже хотелось бы собирать в массив, и потом анализировать. 

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