Назначить прерывание любому контакту микроконтроллера atmega328
Мне нужно записать появление сигнала от датчика на выводе PD0. Это первый раз в моей жизни, когда я хочу использовать прерывание для этого. С вашей помощью я настроил скетч для своего контакта PD0
#include <avr/interrupt.h>
volatile int value = 0;
void setup()
{
cli();
PCICR |= 0b00000100; // включить порт d
PCMSK2 |= 0b00000001; // включить контакты PD0 (PCINT16)
sei();
Serial.begin(9600);
}
void loop()
{
Serial.println(value);
}
ISR(PCINT2_vect)// Порт D, PCINT16 - PCINT23
{
value++;
}
Мне нужно подождать и предпринять определенное действие, когда от датчика поступает высокий сигнал. Например, добавьте единицу к константе. Я также не понимал, когда возникают перебои. Когда сигнал меняется снизу вверх, когда сверху вниз, или неважно как? Не можете увидеть, есть ли здесь эти настройки? Может быть, он установлен как-то по умолчанию?
@Антон, 👍1
Обсуждение1 ответ
Вот ссылка на хорошее руководство по включению, реагированию и очистке прерываний на устройстве ATmega328P:
Прерывания смены контактов Arduino
Я повторю здесь общие шаги на случай, если этот URL-адрес исчезнет в будущем:
Во-первых, вы должны включить прерывания смены контакта:
Обратите внимание на использование 3 бит в регистре PCICR [0:2]. Они позволяют прерывать смену контактов на портах B, C или D в целом. Вы можете выбрать любую комбинацию этих портов или все порты по своему усмотрению.
Затем вы выбираете, какой PIN или контакты на включенных портах, от которых вы хотите получать прерывания. Здесь у вас есть контроль над каждым отдельным битом порта:
Затем вы должны написать ISR (процедуру обслуживания прерываний) для обработки прерывания, как только оно возникает. У вас есть возможность использовать до ТРЕХ ISR, по одному для обработки каждого порта, или у вас может быть один ISR для обработки любого прерывания смены контакта. Это работает так: когда прерывание происходит на включенном порту и PINе, микросхема AVR вызывает ISR, который вы настроили для этого события:
Итак, когда происходит прерывание, как вы узнаете, какой вывод (ы) вызвал ISR? Предположим, вы использовали один ISR для обработки всех 3 портов. На данный момент вы знаете только, что где-то произошло прерывание. Это и есть назначение битов регистра PCIFR. Из таблицы AVR мы видим следующее:
Проверив состояние этих битов, теперь вы можете определить, какой вывод или выводы вызвали прерывание. Обратите внимание, ЧТО их МОЖЕТ БЫТЬ НЕСКОЛЬКО, поэтому вы сами должны определить приоритет каждого из них и обработать их соответствующим образом. Обратите внимание, что у вас есть только ОДИН шанс прочитать их во время любого вызова функции ISR, поскольку они очищаются при выполнении ISR.
Последнее замечание. Вы ДОЛЖНЫ вызвать функцию sei();, чтобы включить любое прерывание для процессора, прежде чем произойдет какое-либо прерывание.
Однако в вашем примере вы, похоже, пытаетесь сгенерировать прерывание смены контакта на выходе. Вероятно, это НЕ то, чего вы хотите. Попробуйте просто использовать существующий выходной вывод светодиода в качестве индикатора и выбрать другой вывод, настроенный в качестве входного, в качестве источника прерывания смены вывода.
Спасибо! У меня кое-что есть. Счетчик увеличивает число, когда я прикасаюсь рукой к проводу, выходящему из контакта PD0. Но я до сих пор не понимаю, на каком фронте и как это работает, @Антон
в исходном вопросе использовалась библиотека для прерываний смены контактов. как этот ответ отвечает на вопрос?, @Juraj
@Juraj Я не вижу, чтобы библиотека использовалась., @jwh20
вопрос был отредактирован, @Juraj
- В чем разница/связь между Arduino и AVR?
- Как преобразовать скетч примера Arduino в полный проект C++?
- Не удается записать загрузчик через Arduino Nano clone ISP в atmega328p
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Как создать задержки на языке ассемблера AVR
- Программирование микроконтроллера Attiny85 без arduino
- AVR (Arduino Uno) Serial.print и Serial.println печатают только 1 или 2 символа
- Прерывание переполнения таймера AVR не работает
Непонятно, в чем именно заключается ваша проблема. В приведенном примере используемый вывод - это "pinBlink" со значением 7. Вы можете изменить его с помощью параметра определить в начале скетча, @chrisl
Выводы пакета TQFP здесь не имеют значения. Вам просто нужно знать, что вывод “PD0” ATmega328P равен “цифре 0” библиотеки Arduino Uno и Arduino core., @Edgar Bonet
PD0 - это последовательный RX и вывод 0 на Uno / Nano / Mini. почему вы хотите использовать этот контакт?, @Juraj
почему бы не использовать периферийное устройство "внешнего прерывания"?, @Juraj
Я не знаю. Кажется, что именно так это и работает, но я не понимаю, как это работает. Какой край импульса. Я включил кнопку вместо датчика, но я все еще не могу понять, @Антон