Фазовый компаратор на Ардуино

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

В принципе вопрос в заголовке темы, кто реализовывал программно, есть пример, в Гугл не нашёл.

rkit
Offline
Зарегистрирован: 23.11.2016

В лоб написать не судьба?

if  (digitalRead(p1)) {
  res = 1;
  while(digitalRead(p1));
  while(digitalRead(p2));
} else if (digitalRead(p2)) {
  res = -1;
  while(digitalRead(p2));
  while(digitalRead(p1));
}

 

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

так блокирующий жеж

rkit
Offline
Зарегистрирован: 23.11.2016

Тебе на блинк без делея ссылку дать?

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

rkit пишет:

Тебе на блинк без делея ссылку дать?

не надо, подумалось может кто на PCINT делал...
Видимо как-то так!?
 

// Исходный скетч тут - https://tsibrov.blogspot.com/2019/06/arduino-interrupts-part2.html
// MY VERY TKS Владимиру

#define outFK 13      // Пин выхода ФАПЧ
#define inFK1 8       // Пин входа 1-го компаратора
#define inFK2 9       // Пин входа 2-го компаратора

uint8_t oldPINB = 0xFF;

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

ISR (PCINT0_vect) { // Обработчик запросов прерывания от пинов D8..D13
//  uint8_t changedbits = PINB ^ oldPINB;
//  oldPINB = PINB;
  digitalWrite(outFK, (digitalRead(inFK1) ^ digitalRead(inFK2)));
}

void setup() {
  pinMode(outFK, OUTPUT);
  pinMode(inFK1, INPUT_PULLUP);  // Подтянем пины-источники PCINT к питанию
  pinMode(inFK2, INPUT_PULLUP);
  pciSetup(inFK1);               // И разрешим на них прерывания
  pciSetup(inFK2);
  digitalWrite(outFK, HIGH);
  delay(3000);
}


void loop() {
  // здесь наша основная программа
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Плохо. На PCINT есть ограничения на частоту ну и фазу соответственно. Надо на два отдельных пина со своими прерываниями.

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

nik182 пишет:

Плохо. На PCINT есть ограничения на частоту ну и фазу соответственно. Надо на два отдельных пина со своими прерываниями.

интересно какие (по частоте)

nik182
Offline
Зарегистрирован: 04.05.2015

PCINT не различает ноги. После срабатывания прерывания надо ещё читать значения пинов и проанализировать, что бы понять какой из пинов сработал первым. Это требует времени. Собственно эти лишние затраты на чтение и анализ выливаются в довольно длинные процедуры, которые и ограничивают входную частоту, если ещё и фазу надо точнее получить.

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

весь обработчик в 19 строке, прочитать два бита порта и сделать с ними исключающее ИЛИ в кодах видимо небольшие затраты будут, но проще аппаратно конечно решить

nik182
Offline
Зарегистрирован: 04.05.2015

Для таких приложений надо считать не строки а конечные машинные коды. В любом случае через INT0 и INT1 обработка существенно короче.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

nik182 пишет:

 через INT0 и INT1 обработка существенно короче.

Если их делать _NAKED, иначе пасёравну.

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

DetSimen пишет:

nik182 пишет:

 через INT0 и INT1 обработка существенно короче.

Если их делать _NAKED, иначе пасёравну.

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

Параметр ISR_NAKED

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

ISR(TIMER1_OVF_vect, ISR_NAKED)
{
  PORTB |= _BV(0);
  reti();
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Вызов без сохранения/восстановления SREG.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

sadman41 пишет:
Вызов без сохранения/восстановления SREG.

Не только SREG, там для ускорения выполнения ни один регистр не сохраняется при входе, если какие-то регистры используются в подпрограмме, надо их сохранять/восстанавливать самому, врукопашную

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

nik182 пишет:

Для таких приложений надо считать не строки а конечные машинные коды. В любом случае через INT0 и INT1 обработка существенно короче.

Кроме того, я что-то не припомню PCINT на ARM.

Другими словами, если уж ми пишем на форуме Ардуино и, кроме того, выносим "Ардуино" в заголовок темы, то и обсуждать следует именно Ардуино, а в Ардуино PCINT нет.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

andriano пишет:

 а в Ардуино PCINT нет.

О_О Чойта? Клапа запретил? А как у меня тогда счетчики воды работают на Uno?  Пойду проверять срочно. :)))

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

andriano пишет:

 в Ардуино PCINT нет.

выбираю ардуино нано, олд бутлоадер, компилирую, загружаю, работает, "...???... как нет, есть, но маленький" (из народного фольклора)

sadman41
Offline
Зарегистрирован: 19.10.2016

На AVR PCINT, не ARM.

Полагаю, что имелось в виду следующее: в некоторых МК оно есть, но это уже вне концепции платформы Arduino.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DetSimen пишет:

andriano пишет:

 а в Ардуино PCINT нет.

О_О Чойта? Клапа запретил? А как у меня тогда счетчики воды работают на Uno?  Пойду проверять срочно. :)))

Будешь проверять, проверь заодно на Due.