Сдвиг фазы квадратной волны Arduino на 270 градусов
Я использую этот код для генерации прямоугольной волны с помощью Arduino и сдвига ее на 90 и 180 градусов. Однако этот код не способен сдвинуть его на 270 градусов. Не могли бы вы предложить, как я могу изменить код, чтобы он поддерживал операцию фазового сдвига прямоугольной волны на 270 градусов.
void setup() {
pinMode( 9 , OUTPUT ); // Arduino Pin 9 = OCR1A
pinMode( 10 , OUTPUT ); // Arduino Pin 10 = OCR1B
// Оба выхода в режиме переключения
TCCR1A = _BV( COM1A0 ) |_BV( COM1B0 );
// Режим генерации сигнала CTC
// ВЕРХ=ICR1
// Обратите внимание, часы пока отключены
TCCR1B = _BV( WGM13) | _BV( WGM12);
OCR1A = 0; // Первый вывод является базовым, он всегда переключается на 0
}
// прескалер 1 даст нам 8МГц - 488Гц
// Используйте более высокий прескалер для более низких частот
#define PRESCALER 1
#define PRESCALER_BITS 0x01
#define CLK 16000000UL // Тактовая частота по умолчанию 16 МГц на Arduino Uno
// Выходные формы волны со сдвигом по фазе на выводах 9 и amp; 10
// freq = частота в герцах ( 122 < freq <8000000 )
// сдвиг = фазовый сдвиг в градусах ( 0 <= сдвиг < 180 )
// Делайте сдвиги на 180-360 градусов, вы можете инвертировать OCR1B, выполнив дополнительное переключение с помощью FOC
/// Обратите внимание, фазовые сдвиги будут округлены в меньшую сторону до ближайшего возможного значения, поэтому чем выше частота, тем меньше разрешение фазового сдвига вы получите. На частоте 8 МГц у вас может быть только 0 или 180 градусов, потому что за цикл приходится только 2 тактовых импульса.
int setWaveforms( unsigned long freq , int shift ) {
// Предполагается, что предварительный делитель = 1. Для более низких частот используйте больший предварительный делитель.
unsigned long clocks_per_toggle = (CLK / freq) / 2; // /2, потому что для создания полной волны требуется 2 переключателя
ICR1 = clocks_per_toggle;
unsigned long offset_clocks = (clocks_per_toggle * shift) / 180UL; // Сначала делаем mult, чтобы сохранить точность
OCR1B= offset_clocks;
// Включаем таймер сейчас, если он еще не был включен
// Источник часов = clkio/1 (без предварительного масштабирования)
// Примечание: здесь можно использовать предварительный делитель для более низких частот
TCCR1B |= _BV( CS10 );
}
// Демонстрация циклическим изменением некоторых фазовых сдвигов на частоте 50 кГц
void loop() {
setWaveforms( 40000 , 0 );
delay(1000);
setWaveforms( 40000 , 90 );
delay(1000);
setWaveforms( 40000 , 180 );
delay(1000);
}
@Bogdan Raspopin, 👍1
Обсуждение1 ответ
Arduino может переключаться только в диапазоне 180 градусов в режиме CTC, используя 16-битный таймер. Если вы сдвинете один канал на 90 градусов (другой OCR установлен на 1, а не на ноль), а затем добавите логический инвертор, вы получите эквивалент 270 градусов, как упоминал Эдгар Боне.
Что касается использования FOC (принудительного сравнения вывода), Эдгар Б. снова прав. Канал можно предварительно настроить как инвертированный, а затем выполнить сдвиг, установив OCR на 90 градусов — вам не понадобится дополнительный логический инвертор. Но этот метод не для кого-то новым. Вам понадобится O-Scope, чтобы заставить его работать (и некоторое время, чтобы изучить FOC и режим CTC-12).
Я думаю, что проще использовать одну секцию шестнадцатеричного инвертора 7404, чтобы преобразовать сдвинутую на 90 градусов форму сигнала на 270 градусов.
Поиск "Прямоугольные волны с фазовым сдвигом" и вы найдете ВИДЕО (по состоянию на 2022 год) для примера проекта, в котором используется тактика FOC для создания фазовых сдвигов, регулируемых во время выполнения, на Arduino. Возможно, вы найдете способ легко изменить код для нужной вам перевернутой фазы...
FWIW стокву
- связь между двумя arduino с помощью ENC28J60?
- Способы связи между двумя Arduino?
- Сброс Arduino Uno в коде
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
- Отправка значения с одного Arduino на другой
- Как вызвать функции C из скетча ардуино?
- Связь Arduino master/slave с использованием RS485
- Клиент MQTT на Arduino + SIM900
Ответ находится в коде, который вы разместили, в комментарии: «Чтобы выполнять сдвиги на 180-360 градусов, вы можете инвертировать OCR1B, выполнив дополнительный переключатель с помощью FOC»., @Edgar Bonet
Я пытался понять это утверждение, и оно не имеет для меня особого смысла. Не могли бы вы помочь мне изменить код или понять утверждение? @ЭдгарБонет, @Bogdan Raspopin
Не ваш собственный код?, @AJD
Нет, я взял отсюда: https://electronics.stackexchange.com/questions/174656/avr-arduino-output-2-pwm-waveforms-with-90-grade-phase-shift?utm_medium=organic&utm_source=google_rich_qa&utm_campaign= google_rich_qa, @Bogdan Raspopin
Звучит так, как будто это означает «Инвертируйте форму волны и сделайте сдвиг на 90 градусов»., @Majenko
установка бита FOC вызывает однократное сравнение выходных данных независимо от значения OCR, фактически вызывая «преждевременное» переключение. Это инвертирует форму волны в долгосрочной перспективе. FOC — последние 2 бита (6, 7) в регистре TCCRB, FOCxA/B по макросу, @mystery
@mystery, не могли бы вы посоветовать, как мне изменить код, чтобы выполнить операцию. Извините, я действительно новичок в этом пространстве, @Bogdan Raspopin