Watchog в Arduino Pro Micro

VladimirTsibrov
Offline
Зарегистрирован: 05.03.2019

ЕвгенийП пишет:

Viator пишет:

(Мечтательно...) Вот был, к примеру, в фортране оператор RETURN m - возврат из подпрограммы на метку m...

Здесь есть почти полный аналог, только ... из прерывания ... надеюсь, Вы знаете, что делаете, и знаете, как это правильно делать. Гуглите по словам setjmp и longjmp.

Вы заметили мой пост #37? Проверили?

Из прерывания... наверное, можно попробовать подменить адрес возврата в стеке. Только как-то это... для любителей особых видов извращений

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Viator пишет:

Алгоритм приёма данных простой. Микроконтроллер ардуины периодически опрашивает линию строба данных и при появлении строба принимает байт с шины данных и пересылает его в компьютер по каналу USB. 

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

Раз уж я в этой теме что-то писал, то взял на себя труд ознакомиться с тревогами и печалями автора темы (ТС - Топик Стартер).

Далее 2ТС:

Сказать, что ты решаешь задачу через жопу - это ничего не сказать.

Есть два нормальных пути, вот первый:

Итак предположим, что у тебя 10 линий (больше 8). Вследствии некоторого неудобства пинчейндж прерываний в 32U4 следует выбрать 328ой контроллер, например Ардуино Нано или Мини. У них ЛЮБАЯ нога - имеет закрепленное прерывание. Это первый путь.

Второй путь:

Оставить Микро, и даже вочдог использовать, но не как источник Ресета, а как источник прерывания (читаем ДШ до просветления). Если Импульс столь короток, что его опасно пропустить, не запретив прерывания, то у работающей ардуино задейставовано только одно прерывание - переполнение таймера 0. Просто запрещаем его и ждем важного Импульса ;)). Перед этим взводим таймер вочдога на желаемый таймаут и переводим вочдог в режим прерываний.

---------------------

И важное замечание: что это за короткий строб? Что в твоем понимании "короткий"? 5-10 мкс, это уже не короткий, если что. А то есть у меня подозрения... А если реально меньше микросекунды, то неплохо его защелкнуть электрически и удлиннить до разумного. Раз уж это сигнал для считывания байта (операции неимоверно долгой, в терминах микросекунд), то удлиннение строба простейшей защелкой на диоде и конденсаторе с разряжающим резистором, сделает только много пользы.

Viator
Offline
Зарегистрирован: 18.01.2019

wdrakula пишет:

Сказать, что ты решаешь задачу через жопу - это ничего не сказать.

Промолчим.

Viator
Offline
Зарегистрирован: 18.01.2019

wdrakula пишет:

вочдог использовать, но не как источник Ресета, а как источник прерывания

И из обработки прерывания вернёмся в бесконечный цикл опроса?

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Viator пишет:

wdrakula пишет:

Сказать, что ты решаешь задачу через жопу - это ничего не сказать.

Промолчим.

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Viator пишет:

wdrakula пишет:

вочдог использовать, но не как источник Ресета, а как источник прерывания

И из обработки прерывания вернёмся в бесконечный цикл опроса?

 

выставим флан и вернемся, там проверим флаг и выйдем. Операция проверки выставленного флага - максимум 4 такта, то есть 0.25 мкс.

Viator
Offline
Зарегистрирован: 18.01.2019

wdrakula пишет:

И важное замечание: что это за короткий строб? Что в твоем понимании "короткий"? 5-10 мкс, это уже не короткий, если что. А то есть у меня подозрения... А если реально меньше микросекунды, то неплохо его защелкнуть электрически и удлиннить до разумного. Раз уж это сигнал для считывания байта (операции неимоверно долгой, в терминах микросекунд), то удлиннение строба простейшей защелкой на диоде и конденсаторе с разряжающим резистором, сделает только много пользы.

К сожалению, потерял записи осциллограмм. Надо будет посмотреть заново. На память - длительность строба около 0.3 мкс.

А насчёт дополнительной внешней логики... Собственно, так и было сделано (много лет назад) в предыдущем варианте устройства. Строб запоминался триггером, данные по фронту строба фиксировались в регистре, откуда микроконтроллер (1878ВЕ1) переправлял их в компьютер по интерфейсу RS-232. Быть может, придётся пойти таким же путём... Но исчерпаны ли возможности Pro Micro?

Viator
Offline
Зарегистрирован: 18.01.2019

wdrakula пишет:

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

Я хотел вложить в ответ иронию... но если задел Вас - прошу извинить.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ОК. Если 0.3 мкс, то нет никакой возможности детектировать такой импульс опросом. Цикл из 10 опросов уже займет больше 300 нс, даже если порт опрашивать целиком, в одной команде.

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

Читай про PCINT. Если не поймешь - спрашивай.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Лучшее враг хорошего, оставить всё как было заменив только контроллер )))

Viator
Offline
Зарегистрирован: 18.01.2019

Благодарю всех откликнувшихся.

С помощью библиотек setjmp/longjmp (по совету VladimirTsibrov'а) удалось построить желаемый алгоритм. Но стробы иногда пропускаются. Хотя длительность стробов оказалась не 0.3, а 0.45 мкс, и при периодичности опроса в 0.25 мкс они, казалось бы, должны отлавливаться.

Wdrakula указал, что помехой могут быть прерывания от таймера0. Для проверки был сочинён скетч, генерирующий меандр:



void setup() 
{
  __asm__ __volatile__("ldi r30, 0x80"); // Разрешаем изменение коэф-та
  __asm__ __volatile__("sts 0x61, r30"); //  деления такт.частоты (CLKPR)
  __asm__ __volatile__("ldi r30, 0x00"); // Устанавливаем максимальную
  __asm__ __volatile__("sts 0x61, r30"); //  частоту - 16 МГц (CLKPR)

  pinMode( 7, OUTPUT);         // Вывод 10 платы = сигнал /ВЧ   = PORTE.6 - выход

M2:
  __asm__ __volatile__("cbi 0x0E, 6");
  __asm__ __volatile__("nop        ");
  __asm__ __volatile__("nop        ");
  __asm__ __volatile__("sbi 0x0E, 6");
  goto M2;
}

void loop() {
}

По осциллографу видно, что меандр время от времени прерывается паузами длительностью около 9 мкс. Это и есть эффект прерываний? Как можно запретить на время все прерывания, кроме как по таймеру1?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Viator пишет:

С помощью библиотек setjmp/longjmp (по совету VladimirTsibrov'а) 

Вообще-то, такой совет был от другого участника (#46), а VladimirTsibrov, наоборот, написал "наверное, можно ... только как-то это... для любителей особых видов извращений" (#51). Ты бы уж не путал людей.

Viator пишет:

Как можно запретить на время все прерывания, кроме как по таймеру1?

Никак. Прерывания можно отключить или все, или по-одному. Но тебе и не надо все, выруби прерывание по переполнению таймера №0, больше тебе ничего особо не надо. Ну или весь таймер №0 обесточь.

Знаешь, как это делается?

Кстати, а чё строки 8 и 18 не на ассемблере? Если уж всё на нём

Viator
Offline
Зарегистрирован: 18.01.2019

Ворота пишет:

Прерывания можно отключить или все, или по-одному. Но тебе и не надо все, выруби прерывание по переполнению таймера №0, больше тебе ничего особо не надо. Ну или весь таймер №0 обесточь.

Знаешь, как это делается?

Должен признаться - не знаю. Пробовал так:

  TIMSK0 = 0;

и сяк:

  TCCR0B = 0;

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

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

Viator, Нужно ещё и USB прерывания вырубить.

void setup() {
delay(5000); 
TCCR0B=0;
UDIEN=0;
pinMode( 7, OUTPUT);   
asm( "M:         " );
asm( "sbi 0x0e, 6" );
asm( "nop        " );
asm( "nop        " );
asm( "cbi 0x0e, 6" );
asm( "rjmp     M" );
}

void loop() {}

 

Viator
Offline
Зарегистрирован: 18.01.2019

Dimax, спасибо! Запрет прерываний от USB сработал. Правда, один раз. Теперь ардуина - неизвестное USB-устройство...

А меандр стал без пауз, как надо.

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

Viator пишет:

Запрет прерываний от USB сработал. Правда, один раз. Теперь ардуина - неизвестное USB-устройство...

Логично, нет прерываний USB  нет и USB ком-порта. Для этого я и вставил паузу, после включения платы есть 5 секунд пока работает ком-порт, что бы успеть перепрошить. Иначе без программатора не оживить :)