Постоянный выход тактовой частоты Arduino

Я управляю АЦП с помощью Arduino Uno. Я хотел бы, чтобы часы АЦП были на той же частоте, что и Arduino. Есть ли способ, которым я могу получить постоянный тактовый сигнал от одного из выводов Arduino?

Спасибо,

Лиам

, 👍4

Обсуждение

Очень похоже на этот вопрос, @Gerben

Какой АЦП? Если вы читаете через SPI, то тактовая частота обычно равна тактовой частоте SPI, по умолчанию 4 МГц, а также можно выбрать 8 МГц, 2 МГц, 1 МГц, 512 кГц, 256 кГц, 125 кГц и, я думаю, 62/5 кГц. Если вам просто нужны постоянные, свободные часы, то 16 МГц доступны на выводе CKPOUT с изменением бита 6 младшего байта предохранителя: Предохранитель CKOUT позволяет выводить системные часы на PORTB0 [на микросхеме '328P]. Подробнее см. в разделе «Буфер вывода часов» в главе «Системные часы и параметры часов». Ах - 2015 - ну может кому пригодится., @CrossRoads


2 ответа


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

9

Это выводит 8 МГц на контакт 9:

#ifdef __AVR_ATmega2560__
  const byte CLOCKOUT = 11;  // Мега 2560
#else
  const byte CLOCKOUT = 9;   // Уно, Дуэмиланове и др.
#endif

void setup ()
  {
  // устанавливаем таймер 8 МГц на CLOCKOUT (OC1A)
  pinMode (CLOCKOUT, OUTPUT); 
  // устанавливаем Таймер 1
  TCCR1A = bit (COM1A0);  // включить OC1A при сравнении совпадений
  TCCR1B = bit (WGM12) | bit (CS10);   // CTC, без предварительного масштабирования
  OCR1A =  0;       // вывод каждый цикл
  }  // конец настройки

void loop ()
  {
  // что бы ни
  }  // конец цикла

Как добавить прескалер?

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

Таймер 1 бит

В зависимости от частоты вам может не понадобиться предварительный делитель. Измените OCR1A на число от 0 до 65 535, чтобы замедлить его работу.

Редактирование Эдгара: я проверил значения OCR1A с помощью осциллографа. В конце этого ответа указаны частоты.


вы используете TCR1A, COM1A0 и подобные переменные. Всегда ли они присутствуют и неявно определены при запуске кода на ATmega?

Регистры, такие как TCCR1A и другие, определяются в файлах, которые автоматически включаются средой разработки Arduino IDE. Если вы используете другую цепочку инструментов, они также могут быть включены автоматически. Начальная точка:

#define <avr/io.h>

Внутри этого файла он проверяет тип вашего процессора (по символу, переданному компилятору), а затем включает соответствующий подфайл. Внутри этих файлов находятся определения, которые связывают имена регистров с их адресами в адресном пространстве этого конкретного чипа. Например:

#define TCCR1A _SFR_MEM8(0x80)

По сути, _SFR_MEM8 генерирует указатель на адрес volatile (поскольку он может измениться без ведома компилятора), а затем разыменовывает эту переменную.

Обратите внимание, что число 0x80 в этом определении совпадает с числом, показанным на моей диаграмме.

Под определением в соответствующем файле также находятся битовые позиции для битов в этом регистре, например:

#define TCCR1A _SFR_MEM8(0x80)
#define WGM10 0
#define WGM11 1
#define COM1B0 4
#define COM1B1 5
#define COM1A0 6
#define COM1A1 7

Во-вторых, правильно ли я понимаю, что выходной контакт, определенный в TCR1A, выход A и выход B, должен быть на цифровых контактах 9 и 10 соответственно?

Да, действительно. В техническом описании говорится, что если вы установите соответствующие биты в TCCR1A (обратите внимание на написание), то OC1A (контакт 9 платы на Uno) или OC1B (контакт 10 платы на Uno) будут неизменными/переключены/очищены/установлены в зависимости от битов . Вы можете найти эти имена в таблице данных для Atmega328P (и других устройств), а затем использовать схему Arduino, чтобы найти, какие выводы процессора подключены к каким контактам платы.

Фрагмент спецификации Atmega328P:

Техническое описание Atmega328P

Фрагмент таблицы данных Uno:

Таблица данных Uno


Почему вы установили для него значение "Переключить", а не "Установить"?

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


Что означает CTC?

Очистить таймер при сравнении. Это означает, что (в отличие от других режимов) после того, как сопоставление выполнено, таймер очищается, поэтому он снова начинает отсчет с нуля.

Редактировать Эдгар: значения и частоты OCR1A

Value, MHz
 0 8.00
 1 4.00
 2 2.67
 3 2.00
 4 1.60
 5 1.33
 6 1.14
 7 1.00
 8 0.889
 9 0.800
10 0.727
11 0.667
12 0.615
13 0.571
14 0.533
15 0.500
,

Это именно то, что мне было нужно. Как можно добавить прескалер?, @Liam F-A

См. измененный ответ., @Nick Gammon

Спасибо за эту полезную диаграмму и код. У меня проблемы с пониманием некоторых тонкостей. Во-первых, вы просто _используете_ TCR1A, COM1A0 и подобные переменные. Всегда ли они присутствуют и неявно определяются при запуске кода на ATmega (или только на Arduino), или вы фактически объявляете их вне показанного фрагмента кода? Во-вторых, правильно ли я понимаю, что выходной контакт определен в TCR1A, выход A и выход B, чтобы быть на цифровых контактах 9 и 10 соответственно? Почему вы устанавливаете его на «Переключить», а не «Установить»? И, наконец, простой вопрос: что означает CTC? Большое спасибо Вам., @Kjeld Schmidt

См. измененный ответ., @Nick Gammon

Это совершенно потрясающий ответ. Я бы хотел, чтобы у меня было больше представителей, чтобы дать вам очки за вознаграждение. Пока: Спасибо!, @Kjeld Schmidt

В «Начальная точка: #define <avr/io.h>», define предположительно sb include, @James Waldby - jwpat7

Хм? Что такое "сб"?, @Nick Gammon

Я просто добавил частоты для разных значений. Я сделал это в исходном ответе, потому что форматирование делает его намного более читаемым по сравнению с комментарием., @Edgar


3

Вы можете использовать один из контактов ШИМ на Arduino для вывода сигнала ШИМ. Если вам нужны постоянные часы, вам нужно установить коэффициент заполнения ШИМ равным 0,5, т. е. 50%.

Синтаксис: AnalogWrite(pin, value), где параметр «значение» представляет собой рабочий цикл в диапазоне от 0 (всегда выключен) до 255 (всегда включен), поскольку это 8-битный ШИМ-генератор внутри Arduino.

Если вам нужна волна ШИМ с рабочим циклом 0,5, вам нужно установить "значение" выше равным 127, что находится точно посередине между 0 и 255:

analogWrite(clkpin, 127);
,

analogWrite работает только с выводами PWM, а не с аналоговыми выводами., @Gerben

Ты прав, моя вина., @Penthrite