Pro Mini нужно на PD0,PD1(RX,TX) повесить PCINT

В проекта закончились пины:-( Плата уже готова, но нужно добавить пульт ДУ, который должен к тому же будить МК из deepsleep. На плате остался разьем для перепрошивки (RX/TX на PD0,1) через который и хочу подключить аккуратно приемник ПДУ. Serial будет использоваться ТОЛЬКО для обновления прошивки, режим работы пинов переключу когда нужно в скетче.
Итак - не работает! После разрешения PCInt при любом изменении их состояния происходит REBOOT.

volatile uint8_t oldPIND = 0x00;

void pciSetup(byte pin)
{
  *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // Разрешаем PCINT для указанного пина
  PCIFR  |= bit (digitalPinToPCICRbit(pin)); // Очищаем признак запроса прерывания для соответствующей группы пинов
  PCICR  |= bit (digitalPinToPCICRbit(pin)); // Разрешаем PCINT для соответствующей группы пинов
}

void Setup ()
{
DDRD = DDRD & B11111100;  // bit0,1 - входы пульта
pciSetup (RemoteInPin0);           //прерывание пульта на RX (PD0)
}

ISR (PCINT0_vect)
{ // Обработчик запросов прерывания от пинов PD0,PD1
  uint8_t changedbits = PIND ^ oldPIND;
  oldPIND = PIND;
  if (changedbits & (1 << PD0))
  { // Изменился RX(PD0)
    interruptRemote0 = true;
  }
  if (changedbits & (1 << PD1))
  { // Изменился TX(PD1)
    interruptRemote1 = true;
  }
void Main()
{ что угодно}

после этого изменение состоянии PD0 приводит в жесткому ребуту. Если не делать pciSetup - ребут не происходит. Если ISR (PCINT0_vect) пустой или там пишу не значущую команду - все равно ребут…

это че такое? может там надо PORTD ?

все правильно там, кмк

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

oldPIND это не макрос, а пользовательская переменная. Он ее сам придумал :slight_smile:

Upd: RemoteInPin0 определяю #define RemoteInPin0 PD0 (или PD1) - соответственно МК перегружается при изменению уровня(или шуме от щупа осцилла на бывшем RX или TX). Попробую еще отдельно от основного скетча на голой дуинке… Нет сейчас под рукой, одни Атмелы голые…И попробую на другие ноги перевесить для проверки прерывание, понять бы какие не приведут бы к последствиям для платы…
PIND - состояние порта D - 8 бит. Из него выгребаем бит 0, бит1.

Очевидно что по факту обработчика нет.

pcisetup - функция есть в коде в 1-м сообщении, переменные все тоже написал там. Пин задается правильно - реагирует на сигнал на НУЖНОМ пине (только еще не пробовал уйти на другие пины кроме RXTX для теста…). Но блин ресетом реагирует вместо обработки по ISR (PCINT0_vect).

так по большому счету я могу там просто return написать или присвоение какой-то переменной. Оно не должно приводить к reset…

стоп, а вектор то какой должен быть для PortD? может не на тот вектор обработчик вешаю? PCINT0_vect, может не 0?

Я в таких случаях дебажу по тактам с момента поступления сигнала с целью понять на какой вектор прерывания перескакивает. Даташита нет под рукой, надо бы ещё раз перепроверить правильность настройки. Код неполный, непонятно что такое digitalPinToPCMSK(pin).

Это вектор сброса) в даташите адреса есть. А вообще гляди в своей IDE в хедерах файлик iom328.h (mega328, вставь свою модель). Там всё расписано какие isr по каким адресам.

то функция IDE - по мнемонике порта дает маску для регистра прерываний.
Upd: ЗАРАБОТАЛО! Порт D на векторе PCINT2_vect, порт B на PCINT0_vect

1 лайк

не, это адрес вектора обработчика прерывания от порта B… А у мну порт D

Немного подумать и чуточку внимания и всё)

А нельзя ли привести нормальный код? Так чтобы он компилировался? И при этом демонстрировал проблему?

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

1 лайк

Так проблема то только в имени вектора была.