Проблема прерывания таймера

l0lhaxx
Пн, 02 апреля 2018 12:32
Привет, ребята,
У меня проблема с прерыванием таймера. Моя программа всегда останавливается, как только я пытаюсь инициализировать прерывание, как показано ниже.
Когда я комментирую линию, в которой функция выполняется, программа снова работает. Что я делаю не так? заранее спасибо!

void setup () {
.......

Таймер3.setChannel1mode (timer_outputcompare);
Таймер3.setPeriod (data_out_rate); // в микросекундах
Таймер3.setCompare1 (1); // переполнение может быть маленьким
// таймер3.ATCTIONCOMPARE1INTRUTP (DATA_OUT);
Таймер3.пауза ();
}

void data_out (void) {

// пустая функция
}

victor_pv
Пн, 02 апреля 2018 13:41
Сначала вы, вероятно, должны сделать паузу, прежде чем прикрепить прерывание, затем снова запустите таймер.
Функция пуста, мне интересно, что компилятор просто его удаляет, или какая -то другая оптимизация продолжается с ним.
Попробуйте использовать ISR, который моргает светодиод, включив один вызов и выключен в следующем. Помимо получения некоторого контента на функции, это поможет вам также посмотреть, не называется ли функция (светодиод не включается) или не вызывает, но никогда не возвращается (светодиод включается, но не выключает во втором вызове).

l0lhaxx
Пн, 02 апреля 2018 г. 15:23
Спасибо за быстрый ответ. Теперь я попробовал функцию, как показано ниже вашего предложения. Это действительно то, что функция хорошо называется. Светодиод включается, но команда Println больше не выполнена. Также петля не называется. Однако я выбрал относительно высокое время с 1.5 секунд. Что я делаю не так?


#define cu_update_rate 1500000 // 1.5 Гц

void data_out (void) {
DigitalWrite (Led, High);
Serial1.println ("Enterrupt2");
Serial1.румянец();
}

l0lhaxx
Пн, 02 апреля 2018 г., 15:30
Я также попробовал это с тем же результатом.....

Задержка (2000);
Таймер3.пауза ();
Таймер3.setPeriod (data_out_rate); // в микросекундах
Таймер3.setChannel1mode (timer_outputcompare);
Таймер3.setCompare1 (1); // переполнение может быть маленьким
Таймер3.ATCTIONCOMPARE1INTRUTP (DATA_OUT);
Таймер3.обновить ();
Таймер3.резюме();

victor_pv
Пн, 02 апреля 2018 г. 15:51
Вы находитесь в ISR, вы должны быть осторожны, чтобы то, что вы делаете, не зависит от прерываний с более низкими приоритетами, потому что они не будут выполняться, пока вы не вернетесь. Более высокое приоритетное прерывание может вызвать в середине более низкого приоритета, но не наоборот,.

Это просто предположение, но серийный.flush () может зависеть от некоторых прерывостей USART, которые могут иметь более низкий приоритет, чем прерывания таймера, и поэтому никогда не будет завершать ожидание прерывания USART, которое никогда не будет обслуживаться, потому что вы ждете в рамках более высокого приоритета ISR.
Проверьте, что вовлечено в Serial1.println и серийный.румянец().

l0lhaxx
Пн, 02 апреля 2018 г., 16:14
Я понимаю. Тем не менее, прерывание выполняется только каждый 1.5 секунд. И даже если я никогда не запускаю таймер (как в моем первом посте), функция выполняется, а светодиод зажигает.

victor_pv
Пн, 02 апреля 2018 г., 16:31
Проверьте, так ли это, но я думаю, что таймеры начинаются по умолчанию в ядре.
В вашем первом посте таймер никогда не останавливается, поэтому, как только вы прикрепите ISR, он может назвать его.
О том, как часто называется ISR, не имеет значения в этом случае, можете ли вы уточнить, почему вы упоминаете, что это каждый 1.5 секунд?
Насколько я понимаю из ваших постов, ISR называется один раз, включите светодиод и никогда не возвращается, так как часто называют не имеют значения.
Выберите серийные вызовы из ISR и проверьте, держу пари, что ISR вернется, и ваш цикл будет работать.

l0lhaxx
Вт, 03 апреля 2018 г., 7:02 утра
Большое спасибо за быструю помощь! Ты прав, без сериала.Печать прерывание работает по желанию. Проблема в том, что я хочу вызовать функции в прерывании, которое содержит сериал.Печать команды. Как мне реализовать все иначе? Есть хитрость?

Могу ли я оценить приоритет прерывания таймера?

Эдогальдо
Вт, 03 апреля 2018 г., 10:32 утра
[l0lhaxx - Вторник 03 апреля 2018 г., 7:02 утра] - Большое спасибо за быструю помощь! Ты прав, без сериала.Печать прерывание работает по желанию. Проблема в том, что я хочу вызовать функции в прерывании, которое содержит сериал.Печать команды. Как мне реализовать все иначе? Есть хитрость?

Могу ли я оценить приоритет прерывания таймера?
Я думаю, вы могли бы попробовать с: Clean cd "$(CURRENT_DIRECTORY)" cmd /c del "$(CURRENT_DIRECTORY)/build" /F /S /Q

l0lhaxx
Вторник 03 апреля 2018 г., 16:20
Спасибо за совет, я попробую это иногда. Я попробовал что -то еще и узнал что -нибудь интересное. Сериал.println работает ..... но только 4-5 раз в прерывании. Если я добавлю больше строк в команду Println, у меня снова есть эффект, что ничего не сделано (даже в цикле). Но почему?! : Twisted:

Стивестронг
Вт 03 апреля 2018 г., 17:40
Вложенное прерывание?

victor_pv
Вторник 03 апреля 2018 г. 18:47
[l0lhaxx - Вторник 03 апреля 2018 г., 16:20] - Спасибо за совет, я попробую это иногда. Я попробовал что -то еще и узнал что -нибудь интересное. Сериал.println работает ..... но только 4-5 раз в прерывании. Если я добавлю больше строк в команду Println, у меня снова есть эффект, что ничего не сделано (даже в цикле). Но почему?! : Twisted:
Вы, вероятно, заполняете буфер. Если прерывание USART имеет более низкий приоритет, данные в очереди в буфере в очереди, но не отправляются, поэтому в какой -то момент буфер заполняется и не может больше получать данные, блокируя вечно.
Если вы планируете использовать USART из своего таймера ISR, скорее всего, лучше всего скорректировать приоритет, как указал Эдогальдо.

l0lhaxx
Ср. 04, 2018, 15:26
Привет, ребята,
Я хотел бы поблагодарить вас. Это на самом деле работает так, как должно. Никогда бы не пришел к нему без вашей помощи. Спасибо и продолжайте в том же духе!

Изменить: возможно ли изменить приоритет внешних прерываний?

Эдогальдо
Ср. 04, 2018, 16:28
Прерывает приоритетное резюме для F1:
  • Все прерывания связаны с настраиваемым приоритетом
  • Значения приоритета варьируются от 0x0 (самый высокий приоритет) до 0xf (самый низкий приоритет)
  • В ядре Libmaple прерывание с более высоким приоритетом (более низкое приоритетное значение) предотвратит прерывание с более низким приоритетом (Это потому, что в ядре Libmaple все приоритетные биты настроены как «приоритетная группа»)
  • Ядро Libmaple по умолчанию назначает приоритет 0xf (самый низкий) ко всем прерываниям (в nvic_init ())
Для более глубоких подробностей о управлении приоритетом F1, приоритетной группировкой и т. Д., вы можете ссылаться на PM0056 (Один из Библий).

Нагисса
Ср 11 апреля 2018 г., 6:10
Для прерываний Ttimerd я разработал (и расширил) библиотеку, чтобы сделать это на разных архитектурах. К настоящему времени есть поддержка AVR, SAMD и STM32:

https: // github.com/naguissa/utimerlib


Вы можете увидеть процедуру прикрепления STM32 здесь: https: // github.com/naguissa/utimerlib/b ... беременный.CPP#L180



Кроме того, я предлагаю прочитать этот интересный вопрос о прерывах и внутренних функциях времени: https: // github.com/naguissa/utimerlib/uppess/1