Как я могу синхронизировать 2 сигнала

unsigned long Htime;
unsigned long Ltime;
unsigned long Ttime;
unsigned long f;
int N;


void setup() {
  // поместите сюда код установки для однократного запуска:
cli();      
  TCNT2 = 0;
  TCCR2A = 0;
  TCCR2B = 0;
  Serial.begin(9600);
  pinMode(5,INPUT);
  pinMode(3,OUTPUT);
  pinMode(11,OUTPUT);
  TCCR2A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM21) | (1 << WGM20);
  TCCR2B = (1 << WGM22) | (1 << CS22) | (1 << CS21) | (1 << CS20);
  TIMSK2 = (1 << OCIE2A);   
}


void loop() {
  // поместите сюда ваш основной код для многократного запуска:
  Htime = pulseIn(5, HIGH);
  Ltime = pulseIn(5, LOW);
  Ttime = Htime + Ltime;
  f = 1000000 / Ttime;
  Serial.println(f);
  N = (16000000 / 1024 / f ) - 1;
  OCR2A = N;
  OCR2B = N/2;

}

Привет, это то, что я написал. и мне нужно вывести прямоугольную волну с таймером, ее частота измеряется по входному сигналу на контакте 5. После подключения осциллографа я вижу проблему, есть фазовый сдвиг между 2 сигналами. Как я могу синхронизировать эти 2 сигнала? (нарастающий фронт на нарастающий фронт, спадающий фронт на спадающий фронт) Большое спасибо за вашу помощь !

, 👍1

Обсуждение

Вы предполагаете соотношение ВЫСОКИЙ-НИЗКИЙ 1:1 для вашего квадратного выхода, правильно? С этим предположением вы можете избавиться от неуверенного положения нарастающего фронта., @DataFiddler

переместите println после настроек OCR, @Juraj

Сигнал на канале CH1 является внешним сигналом, верно?, @Sim Son

верхний сигнал имеет нарастающий фронт почти 5 мс .... как вы ожидаете синхронизировать это?, @jsotola

Я не совсем понял, чего вы хотите добиться, но вы можете очистить TCNT2 на заднем фронте канала CH1, чтобы синхронизировать их., @Sim Son


1 ответ


1

Учитывая, что только задний фронт вашего ввода резкий и хороший определено, я предлагаю следующий подход:

  • Используйте функцию захвата ввода таймера 1, чтобы получить метку времени на спадающим фронтом и вызвать прерывание.

  • В ISR начните с переключения вывода, чтобы установить его на низкий уровень. Затем вычислить период сигнала (временная метка этого заднего фронта минус временная метка предыдущего) и запрограммируйте регистр сравнения на инициировать событие сравнения совпадений через половину периода.

  • Совпадение при сравнении снова автоматически переключило бы выходной контакт на используя режим вывода таймера «включить сравнение соответствия».

Следующая программа пытается реализовать этот подход. Обратите внимание, что это полностью не проверено. Вход находится на контакте 8 (т.е. PB0 и ICP1). Выход на контакт 9 (т.е. PB1 и OC1A). Таймер настроен на запуск на F_CPU/8 в чтобы приспособиться к таким низким частотам, как примерно 30,1 Гц. А следует использовать другой прескалер, если требуются более низкие частоты. программа не зависит от ядра Arduino и, таким образом, определяет свою собственную main() вместо setup() и loop().

ISR(TIMER1_CAPT_vect)
{
    TCCR1C = _BV(FOC1A);  // принудительное сравнение вывода -> переключить вывод
    static uint16_t last_capture;
    uint16_t capture = ICR1;
    uint16_t period = capture - last_capture;
    last_capture = capture;
    OCR1A = capture + period/2;  // сравнить совпадение после 1/2 периода

    // Если выход высокий, снова переключиться.
    if (bit_is_set(PINB, PB0))
        TCCR1C = _BV(FOC1A);
}

int main()
{
    // Установите OC1A = PB1 = цифровая 9 в качестве выхода.
    DDRB = _BV(PB1);

    // Настроить Таймер 1.
    TCCR1A = _BV(COM1A0);  // включить OC1A при сравнении соответствия
    TCCR1B = _BV(CS11);    // часы на F_CPU/8
    TCCR1C = _BV(FOC1A);   // принудительное сравнение вывода -> переключить вывод
    TIFR1  = _BV(ICF1);    // очистить флаг захвата
    TIMSK1 = _BV(ICIE1);   // разрешить прерывание захвата
    sei();

    for (;;) {}
}
,

большое спасибо, этот код работает идеально. И теперь мне нужно преобразовать эту прямоугольную волну в синусоиду. Я попытался установить PB2, чтобы изменить рабочий цикл и использовать RC-фильтр, но когда я пишу DDRB = _BV (PB2) и OCR1B = ... в программе, я не могу получить прямоугольную волну. Почему это происходит?, @Xtasy1988