Arduino: определить, если 2 сигнала изменяются в течение ~ 100 микросекунд друг от друга - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь использовать Arduino Uno как часть большой схемы, которая синхронизирует два прямоугольных сигнала напряжения (эти сигналы подаются на контакты Uno).Uno будет активирован цифровым сигналом из другой части большей цепи, и этот сигнал активации будет поддерживаться в течение нескольких секунд за раз.В то время как сигнал активации является ВЫСОКИМ, работа Уно будет просто определять, когда его измеренные квадратные сигналы синхронизированы: он будет контролировать их и генерировать собственный импульс, если они достигают своих нулевых переходов в течение примерно 100 микросекунд друг от друга (квадратсами волны ~ 50 Гц).

Поскольку 100us - это довольно короткое окно, я подумал, что я бы попробовал использовать прямое управление битами, а не использовать DigitalRead () или DigitalWrite ().Впрочем, я впервые пытаюсь манипулировать битами, и мой опыт в Си довольно ограничен.У меня здесь есть первый набросок моего кода - если кто-нибудь из вас скажет мне, кажется ли логика логичной, я был бы очень признателен!

Это выглядит долго, но есть только несколько строк 'Стоит идей, остальное - куча скопированных / вставленных блоков (что, несомненно, означает, что есть гораздо более элегантные способы написания).

// Synchronism detector

// This code is built to run on an Arduino Uno.
// The hardware timer runs at 16MHz. Using a
// divide by 8 on the counter each count is 
// 500 ns and a 50Hz wave cycle is 40000 clock cycles.


#include <avr/io.h>
#include <avr/interrupt.h>

void setup(){

  // Set clock prescaler
  // This is set to 'divide by 8' but if I can get away
  // with using delay statements that doesn't really matter
  TCCR1B &= ~(1 << CS12);
  TCCR1B != ~(1 << CS11);
  TCCR1B &= ~(1 << CS10);

  // Set up pins
  // 3rd bit of port D will be the activation flag
  // 4th and 5th bits will be read pins for the incoming waves
  DDRD = DDRD & B11100011
  // Note that I'll also have the incoming waves going into the int0 and int1 pins

  // 6th bit will be a write pin for the outgoing signal
  DDRD = DDRD | B00100000
  PORTD = PORTD & B11011111

  // Set initial values for zero-cross detect flags
  wave_0 = ((PIND & B00001000) >> 3);
  wave_0_prev = ((PIND & B00001000) >> 3);
  wave_1 = ((PIND & B00010000) >> 4);
  wave_1_prev = ((PIND & B00010000) >> 4);
}

void loop(){

  // Poll activation flag
  if (((PIND & B00000100) >> 2) == 1)

    // Poll wave input pins
    wave_0 = ((PIND & B00001000) >> 3);
    wave_1 = ((PIND & B00010000) >> 4);

    // Check zero crossing detection, 
    // Start with wave 0, rising edge
    if (wave_0 == 1 && wave_0_prev == 0))
      attachInterrupt(int1,sync_interrupt, RISING);
      delay(.0001);
      detachInterrupt(int1);

      // Reset pins
      wave_0 = ((PIND & B00001000) >> 3);
      wave_0_prev = ((PIND & B00001000) >> 3);
      wave_1 = ((PIND & B00010000) >> 4);
      wave_1_prev = ((PIND & B00010000) >> 4);
      )      

// Wave 0, falling edge
if (wave_0 == 0 && wave_0_prev == 1))
  attachInterrupt(int1,sync_interrupt, FALLING);
  delay(.0001);
  detachInterrupt(int1);

  // Reset pins
  wave_0 = ((PIND & B00001000) >> 3);
  wave_0_prev = ((PIND & B00001000) >> 3);
  wave_1 = ((PIND & B00010000) >> 4);
  wave_1_prev = ((PIND & B00010000) >> 4);
  )

// Wave 1, rising edge
if (wave_1 == 1 && wave_1_prev == 0))
  attachInterrupt(int0,sync_interrupt, RISING);
  delay(.0001);
  detachInterrupt(int0);

  // Reset pins
  wave_0 = ((PIND & B00001000) >> 3);
  wave_0_prev = ((PIND & B00001000) >> 3);
  wave_1 = ((PIND & B00010000) >> 4);
  wave_1_prev = ((PIND & B00010000) >> 4);
  )

// Wave 1, falling edge
if (wave_1 == 0 && wave_1_prev == 1))
  attachInterrupt(int0,sync_interrupt, FALLING);
  delay(.0001);
  detachInterrupt(int0);

  // Reset pins
  wave_0 = ((PIND & B00001000) >> 3);
  wave_0_prev = ((PIND & B00001000) >> 3);
  wave_1 = ((PIND & B00010000) >> 4);
  wave_1_prev = ((PIND & B00010000) >> 4);
  ) 
}

sync_interrupt(){
  // Set output bit high
  PORTD = PORTD | B00100000
  delay(.001}
  // Set output bit low
  PORTD = PORTD & B00100000

  // Reset pins
  wave_0 = ((PIND & B00001000) >> 3);
  wave_0_prev = ((PIND & B00001000) >> 3);
  wave_1 = ((PIND & B00010000) >> 4);
  wave_1_prev = ((PIND & B00010000) >> 4);
}

Еще раз спасибо за любую помощь.

1 Ответ

0 голосов
/ 23 ноября 2018

ОК, так что я не слишком уверен, что именно представляют собой флаги прерываний для этого конкретного устройства, однако лично я бы сказал, что самый простой способ сделать это - настроить его так, чтобы у вас было настроено 2 прерывания для каждого извходы и чтобы каждый из блоков кода прерываний был настроен на активацию прерывания по таймеру, а также путем перехода с выходного контакта.Таким образом, когда один активируется, если другой не активирован в течение заданного периода времени, вы можете сбросить флаги прерываний, а если активирован второй, то вы можете запустить код, который вы хотите запустить, когда волны синхронизированы

...