Перейти к содержанию

Как проверить, на какой частоте работает ATmega328P?

Обновлено Редакция GAW

Микроконтроллер не знает своей частоты: её задают фьюзы CKSEL, делитель CKDIV8, регистр CLKPR и кварц на плате. Ошибки здесь ведут к неверным задержкам и скоростям UART, а проверить частоту проще всего снаружи — ATmega328P умеет выводить свой такт на ножку.

Фьюз CKOUT

По разделу 9.9 даташита DS40002061B при запрограммированном фьюзе CKOUT системный такт выходит на вывод CLKO — это PB0, у Arduino Uno — цифровой вывод D8. Работает с любым источником, включая внутренний RC-генератор, и даже во время сброса. «Запрограммирован» у AVR значит ноль, поэтому для включения бит 6 младшего байта сбрасывают:

КонфигурацияМладший байтС CKOUTЧто будет на PB0
Arduino Uno, кварц 16 МГц0xFF0xBF16 МГц
новый кристалл, RC 8 МГц и CKDIV80x620x221 МГц
RC 8 МГц без CKDIV80xE20xA28 МГц

Значения — наш расчёт по таблице 28-9; проверить каждый бит поможет калькулятор фьюзов AVR, а смысл инверсии — статья о фьюзах AVR.

avrdude -c usbasp -p m328p -U lfuse:r:-:h        # read the current value
avrdude -c usbasp -p m328p -U lfuse:w:0xBF:m     # Uno with CKOUT on

Что увидите

  • 16 МГц у Uno — кварц и фьюзы в порядке.
  • 1 МГц — заводская настройка: внутренний RC-генератор 8 МГц и делитель CKDIV8; программа, собранная с F_CPU = 16 МГц, работает в 16 раз медленнее. Те же 1 МГц даст и кварц 16 МГц с делителем CLKPR на 16.
  • 2 МГц — кварц 16 МГц с запрограммированным CKDIV8: он делит на 8, а не на 16 (наш расчёт).
  • Ничего — кристалл не тактируется, программатор его тоже не увидит. Причины разобраны в ответе «Почему ATmega328P не запускается от кварца?».

После проверки верните младший байт: пока CKOUT включён, PB0 нельзя использовать как обычный вывод. Связь фьюзов, F_CPU и задержек подробно объясняет урок «Тактовая частота, фьюзы и F_CPU».

Похожие вопросы

Можно ли измерить частоту на PB0 мультиметром?

Только если частотомер мультиметра рассчитан на такую частоту и такой уровень сигнала — предел измерения частоты указан в паспорте прибора. Надёжнее осциллограф или отдельный частотомер. С 1 МГц нового кристалла справиться проще, чем с 16 МГц Arduino Uno.

Можно ли использовать D8, пока включён CKOUT?

Нет: по даташиту при запрограммированном CKOUT обычная функция вывода PB0 отключается, на нём всегда такт. После проверки верните фьюз в исходное состояние.

Как проверить частоту без измерительных приборов?

Помигайте светодиодом с периодом 10 секунд через _delay_ms и засеките время секундомером: если вместо 10 секунд выходит 160, F_CPU равна 16 МГц, а кристалл работает на 1 МГц. Грубее, но так видна ошибка в 2, 8 или 16 раз — самая частая после смены фьюзов.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet, DS40002061B, 2020 — 9.9 «Clock Output Buffer» (с. 45): при запрограммированном CKOUT системный такт выводится на CLKO, в том числе во время сброса, обычная функция вывода отключается, при делителе выводится поделённый такт; табл. 28-9 — CKOUT, бит 6 младшего байта, по умолчанию не запрограммирован; примечание 3 — такт выводится на PORTB0; 9.11 и 9.12.2 — регистр CLKPR делит системный такт на 1…256, CKDIV8 задаёт начальное деление на 8
  2. Arduino. ArduinoCore-avr, коммит 11b9130: boards.txt, variants/standard/pins_arduino.h — uno.bootloader.low_fuses = 0xFF; цифровой вывод 8 — PB0

Нашли ошибку?