Назначить прерывание любому контакту микроконтроллера atmega328

avr

Мне нужно записать появление сигнала от датчика на выводе 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

Обсуждение

Непонятно, в чем именно заключается ваша проблема. В приведенном примере используемый вывод - это "pinBlink" со значением 7. Вы можете изменить его с помощью параметра определить в начале скетча, @chrisl

Выводы пакета TQFP здесь не имеют значения. Вам просто нужно знать, что вывод “PD0” ATmega328P равен “цифре 0” библиотеки Arduino Uno и Arduino core., @Edgar Bonet

PD0 - это последовательный RX и вывод 0 на Uno / Nano / Mini. почему вы хотите использовать этот контакт?, @Juraj

почему бы не использовать периферийное устройство "внешнего прерывания"?, @Juraj

Я не знаю. Кажется, что именно так это и работает, но я не понимаю, как это работает. Какой край импульса. Я включил кнопку вместо датчика, но я все еще не могу понять, @Антон


1 ответ


4

Вот ссылка на хорошее руководство по включению, реагированию и очистке прерываний на устройстве ATmega328P:

Прерывания смены контактов Arduino

Я повторю здесь общие шаги на случай, если этот URL-адрес исчезнет в будущем:

Во-первых, вы должны включить прерывания смены контакта:

Pin change Interrupts

Обратите внимание на использование 3 бит в регистре PCICR [0:2]. Они позволяют прерывать смену контактов на портах B, C или D в целом. Вы можете выбрать любую комбинацию этих портов или все порты по своему усмотрению.

Затем вы выбираете, какой PIN или контакты на включенных портах, от которых вы хотите получать прерывания. Здесь у вас есть контроль над каждым отдельным битом порта:

Pin Change Bits

Затем вы должны написать ISR (процедуру обслуживания прерываний) для обработки прерывания, как только оно возникает. У вас есть возможность использовать до ТРЕХ ISR, по одному для обработки каждого порта, или у вас может быть один ISR для обработки любого прерывания смены контакта. Это работает так: когда прерывание происходит на включенном порту и PINе, микросхема AVR вызывает ISR, который вы настроили для этого события:

AVR ISR

Итак, когда происходит прерывание, как вы узнаете, какой вывод (ы) вызвал ISR? Предположим, вы использовали один ISR для обработки всех 3 портов. На данный момент вы знаете только, что где-то произошло прерывание. Это и есть назначение битов регистра PCIFR. Из таблицы AVR мы видим следующее:

AVR PCIFR Bits

Проверив состояние этих битов, теперь вы можете определить, какой вывод или выводы вызвали прерывание. Обратите внимание, ЧТО их МОЖЕТ БЫТЬ НЕСКОЛЬКО, поэтому вы сами должны определить приоритет каждого из них и обработать их соответствующим образом. Обратите внимание, что у вас есть только ОДИН шанс прочитать их во время любого вызова функции ISR, поскольку они очищаются при выполнении ISR.

Последнее замечание. Вы ДОЛЖНЫ вызвать функцию sei();, чтобы включить любое прерывание для процессора, прежде чем произойдет какое-либо прерывание.

Однако в вашем примере вы, похоже, пытаетесь сгенерировать прерывание смены контакта на выходе. Вероятно, это НЕ то, чего вы хотите. Попробуйте просто использовать существующий выходной вывод светодиода в качестве индикатора и выбрать другой вывод, настроенный в качестве входного, в качестве источника прерывания смены вывода.

,

Спасибо! У меня кое-что есть. Счетчик увеличивает число, когда я прикасаюсь рукой к проводу, выходящему из контакта PD0. Но я до сих пор не понимаю, на каком фронте и как это работает, @Антон

в исходном вопросе использовалась библиотека для прерываний смены контактов. как этот ответ отвечает на вопрос?, @Juraj

@Juraj Я не вижу, чтобы библиотека использовалась., @jwh20

вопрос был отредактирован, @Juraj