Настройка выходной частоты Arduino 75 кГц

Я не знаю, как манипулировать регистрами и таймерами arduino uno или mega, чтобы выходная частота была близка к 75 кГц. Не могли бы вы помочь, пожалуйста?

, 👍-1

Обсуждение

выходная частота откуда куда?, @jsotola


2 ответа


Лучший ответ:

3

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

F_CPU / 75 кГц = 16 000 кГц / 75 кГц ≈ 213,33

Поскольку таймеры могут считать только до целого числа, get составляет 213 циклов процессора. Тогда частота, которую вы получите, будет

F_CPU / 213 = 16 000 кГц / 213 ≈ 75,12 кГц

Теперь вы можете настроить таймер. Я считаю, что проще всего использовать так называется режимом «быстрой ШИМ». Выберите один из тех режимов, где значение TOP можно установить с помощью регистра и установить на единицу меньше желаемого период: таймер будет последовательно считать от 0 до 212.

Вот пример использования канала A таймера 1 на Arduino Uno. Выход находится на цифровом выводе 9 = OC1A = PB1:

// Настройте таймер 1 для ШИМ с частотой 75,12 кГц.
DDRB  |= PB1;         // устанавливаем OC1A = PB1 в качестве выхода
TCCR1A = 0;           // очищаем настройки ядра Arduino
TCCR1B = 0;           // ... то же самое
TCNT1  = 0;           // очищаем таймер
TCCR1A = _BV(COM1A1)  // неинвертирующий ШИМ на OC1A
       | _BV(WGM11);  // режим 14: быстрая ШИМ, TOP = ICR1
TCCR1B = _BV(WGM12)   // ... то же самое
       | _BV(WGM13)   // ... то же самое
       | _BV(CS10);   // часы на F_CPU
ICR1   = 213 - 1;     // период = 213 циклов ЦП = 13,3125 мкс
OCR1A  = 213/2 - 1;   // скважность ~ 50%

Вы можете легко адаптировать его к любому таймеру на Uno или Mega. Просто избегайте Таймер 0, если вы собираетесь использовать функции хронометража Arduino.

,

0

Я думаю, что ответ, данный Эдгаром Боне, является правильным, учитывая все обстоятельства, и по этой причине я проголосовал за него.

Для S&G я хочу добавить следующее:

  1. Самый самый простой способ — просто использовать тон (GPIO, частота); команда - и есть оговорки. НО, аргумент частоты представляет собой целое число без знака, поэтому самая высокая частота составляет 65 535 Гц, а для 75 кГц это не поможет.

Используя счетчик частоты и UNO (кристалл), тон (10,65535); выход был 65556/8 Гц. На Pro Mini 5V (насколько я помню, с керамическим резонатором) было 65540 Гц.

  1. Опять же, для S&G я попробовал этот код (и скорректировал количество NOP), чтобы максимально приблизиться к 75 кГц:

недействительная установка() { pinMode(10, ВЫХОД);

void loop() {
here:
  digitalWrite(10, HIGH);
  delayMicroseconds(3);
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  digitalWrite(10, LOW);
  delayMicroseconds(3);
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  goto here;
}

Выход на UNO был 75004/6 Гц — не так уж и плохо. На Pro Mini лучшее, что я мог сделать, это 74986 Гц.

Разумеется, речь идет о прямоугольных волнах.

,

Обратите внимание, что: 1. Вы можете заменить delayMicroseconds() и последовательность nop одним вызовом [_delay_us()](https://www.nongnu.org/avr-libc/user-manual /group__util__delay.html). Этот макрос имеет разрешение в один цикл: _delay_us(3.4375) задерживает ровно 55 циклов ЦП при тактовой частоте 16 МГц. 2. Этот подход лучше работает с отключенными прерываниями. В противном случае вы получите небольшой сбой при каждом прерывании таймера. Кстати: что означает «S&G»?, @Edgar Bonet

https://www.urbandictionary.com/define.php?term=S%26G где-то давным-давно подобрал выражение :), @DrG