Как проверить, на какой частоте работает 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 МГц | 0xFF | 0xBF | 16 МГц |
| новый кристалл, RC 8 МГц и CKDIV8 | 0x62 | 0x22 | 1 МГц |
| RC 8 МГц без CKDIV8 | 0xE2 | 0xA2 | 8 МГц |
Значения — наш расчёт по таблице 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 раз — самая частая после смены фьюзов.
Источники
- 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
- Arduino. ArduinoCore-avr, коммит 11b9130: boards.txt, variants/standard/pins_arduino.h — uno.bootloader.low_fuses = 0xFF; цифровой вывод 8 — PB0
Нашли ошибку?