В этой статье мы рассмотрим что такое фьюзы (Fuse Bits) в платах Arduino и как их можно использовать для повышения эффективности программ для данной платформы. Если говорить точнее, то понятие фьюзы следует соотносить не с платами Arduino, а с микроконтроллерами семейства AVR, которые являются «сердцем» данных плат.
Фьюзы в микроконтроллерах семейства AVR представляют собой специальные биты конфигурации (переключатели), изменяя которые (то есть устанавливая в них 0 или 1) мы можем изменять некоторые режимы работы микроконтроллера или использовать какие либо его специальные возможности, которые недоступны в его конфигурации «по умолчанию». Эти биты расположены в отдельном адресном пространстве, доступном только при программировании. Биты объединяются в конфигурационные байты и их состав зависит от конкретной модели микроконтроллера. Фьюзы есть во всех микроконтроллерах AVR, но в данной статье мы рассмотрим работу с ними на примере микроконтроллера ATmega328P поскольку он является одним из самых распространенных микроконтроллеров семейства AVR в связи с его использованием в платах Arduino.
Как мы уже рассмотрели, фьюзы (биты конфигурации) представляют собой «маленькие переключатели», изменяя которые можно управлять логикой работы микроконтроллера. Каким образом мы можем устанавливать или сбрасывать эти биты? Ответ на этот вопрос достаточно простой – это можно сделать с помощью специальных регистров (fuse registers).
В микроконтроллере ATmega328P имеется 19 фьюзов (битов), которые объединены в 3 байта (fuse bytes), которые называются конфигурационными байтами и включают в себя “Extended Fuse Bytes” (дополнительный байт), “High Fuse Byte” (старший байт) и “Low Fuse Byte” (младший байт).
Значения конфигурационных байтов в микроконтроллере ATmega328P по умолчанию: Low: 0x62, High: 0xD9, Extended: 0xFF. Следует помнить, что это значения именно для «чистого» микроконтроллера ATmega328P , а не для платы Arduino. Значения фьюзов для платы Arduino можно найти в файле Arduino_dirhardwarearduinoavrBoards.txt, где Arduino_dir — это путь к Arduino IDE. Откройте файл в текстовом редакторе и найдите интересующую плату по названию, чуть ниже будет информация о фьюзах:
uno.name=Arduino/Genuino Uno
...
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
Примечание: при работе с конфигурационными битами в микроконтроллерах AVR необходимо помнить один важный момент – они инверсные, то есть 1 это выкл, 0 – это вкл. То есть если бит содержит логическую единицу, то это означает что он не запрограммирован (unprogrammed), соответственно, запрограммированный (programmed) конфигурационный бит содержит логический ноль. Такая логика основана на принципе хранения данных в EEPROM: чистая микросхема памяти содержит во всех ячейках единицы, а термин запрограммирована по отношению к такой ячейке означает, что в нее записали ноль.
Если вы посмотрите на таблицу 27 даташита на ATmega328P под номером 7810D–AVR–01/15, то в ней вы можете узнать много подробностей о работе фьюзов в данном микроконтроллере. На следующем рисунке вы можете посмотреть краткий (но достаточно важный) фрагмент из данной таблицы:
Далее последовательно рассмотрим состав конфигурационных байтов в микроконтроллерах семейства AVR.
Дополнительный конфигурационный байт (Extended Fuse Byte)
В следующей таблице показан состав дополнительного байта фьюзов (Extended Fuse Byte), который также называется “EFUSE”.
| Номер бита | Название | Описание | Значение по умолчанию |
| 7 | — | — | 1 |
| 6 | — | — | 1 |
| 5 | — | — | 1 |
| 4 | — | — | 1 |
| 3 | — | — | 1 |
| 2 | BODLEVEL2 | Brown-out Detector trigger level | 1 (не запрограммирован) |
| 1 | BODLEVEL1 | Brown-out Detector trigger level | 1 (не запрограммирован) |
| 0 | BODLEVEL0 | Brown-out Detector trigger level | 1 (не запрограммирован) |
Как вы можете видеть из представленной таблицы, в этом байте используются всего 3 бита, а остальные биты зарезервированы.
Конфигурационные биты BODLEVEL определяют порог срабатывания схемы BOD (Brownout Detection level), которая следит за уровнем напряжения источника питания. Схема BOD (Brownout Detection) сбрасывает микроконтроллер когда напряжения питания падает ниже определенного уровня. Когда напряжение питания вновь увеличивается до заданного порогового значения (определяемого битами BODLEVEL), то сигнал сброса снимается и происходит запуск микроконтроллера.
В следующей таблице представлены значения порога срабатывания схемы BOD в зависимости от значения битов BODLEVEL. Также в микроконтроллере ATmega328P можно полностью отключить работу схемы BOD с помощью указанных битов (комбинация битов 111).
| Порог срабатывания схемы BOD (В) | Значение BODLEVEL2..0 |
| Схема BOD выключена | 111 |
| Vcc = 1.8 | 110 |
| Vcc = 2.7 | 101 |
| Vcc = 4.3 | 100 |
Старший конфигурационный байт (High Fuse Byte)
В следующей таблице представлен состав старшего конфигурационного байта в микроконтроллере ATmega328P.
| Номер бита | Название | Описание | Значение по умолчанию |
| 7 | RSTDISBL | External Reset Disable | 1 (не запрограммирован) |
| 6 | DWEN | debugWIRE Enable | 1 (не запрограммирован) |
| 5 | SPIEN | Enable Serial Program and Data Downloading | 0 (запрограммирован) |
| 4 | WDTON | Watchdog Timer Always On | 1 (не запрограммирован) |
| 3 | EESAVE | EEPROM memory is preserved through the Chip Erase | 1 (не запрограммирован) |
| 2 | BOOTSZ1 | Select Boot Size | 0 (запрограммирован) |
| 1 | BOOTSZ0 | Select Boot Size | 0 (запрограммирован) |
| 0 | BOOTRST | Select Reset Vector | 0 (запрограммирован) |
Биты BOOTRST, BOOTSZ0 и BOOTSZ1 в составе данного байта отвечают за размер Flash памяти микроконтроллера, резервируемой для загрузчика, и за положение вектора сброса.
Загрузчик (начальный загрузчик) – это специальная программа, которая выполняется в самом начале работы микроконтроллера и может решать различные задачи. В случае с платами Arduino данный загрузчик обеспечивает загрузку скетча (основной программы) в память микроконтроллера. По умолчанию для загрузчика резервируется максимальный размер – 2048 слов.
| Начало секции загрузчика | Размер секции (слов) | Значение BOOTSZ1..0 |
| 0x3F00 | 256 | 11 |
| 0x3E00 | 512 | 10 |
| 0x3C00 | 1024 | 01 |
| 0x3800 | 2048 | 00 |
Бит BOOTRST определяет положение вектора сброса микроконтроллера. По умолчанию он указывает на адрес 0х0000.
Бит EESAVE определяет режим стирания энергонезависимой памяти EEPROM. Если в нем логический 0 (бит запрограммирован), то при команде «стирание кристалла» информация в памяти EEPROM сохраняется, если в нем логическая 1 – то содержимое EEPROM по указанной команде стирается.
Бит WDTON отвечает за работу сторожевого таймера (Watchdog Timer). Сторожевой таймер – это таймер, который работает отдельно от всех остальных таймеров микроконтроллера AVR. Если сторожевой таймер установлен, то вам будет необходимо его сбрасывать через определенный период, иначе данный таймер будет сбрасывать микроконтроллер. Если данный бит установлен в логический 0, то работу сторожевого таймера нельзя будет запретить из программы и при переполнении он будет автоматически подавать сигнал сброса на микроконтроллер.
Бит DWEN разрешает/запрещает работу отладочного интерфейса debugWire – это предварительный протокол, который «зашит» в железо микроконтроллера и используется для его программирования и отладки. Когда он установлен (enabled) вы можете загружать программу в микроконтроллер и производить ее отладку по одиночному проводнику. Но для этого необходимы специальные программно-аппаратные средства.
Оставшиеся два бита желательно оставить в «покое» до тех пор, пока вы точно не будете знать что они делают, иначе это может привести к тому, что микроконтроллер перестанет у вас корректно работать. Бит SPIEN разрешает/запрещает программирование микроконтроллера по интерфейсу SPI. По умолчанию он запрограммирован, то есть установлен в 0. Бит RSTDISBL запрещает/разрешает внешний сброс микроконтроллера. Отключать внешний сброс целесообразно только в моделях микроконтроллеров, имеющих очень малое количество выводов (в этом случае данный вывод можно будет задействовать для каких-нибудь других целей), во всех остальных случаях данный фьюз лучше не трогать.
Младший конфигурационный байт (Low Fuse Byte)
В следующей таблице представлен состав младшего конфигурационного байта в микроконтроллере ATmega328P.
| Номер бита | Название | Описание | Значение по умолчанию |
| 7 | CKDIV8 | Divide clock by 8 | 0 (запрограммирован) |
| 6 | CKOUT | Clock output | 1 (не запрограммирован) |
| 5 | SUT1 | Select start-up time | 1 (не запрограммирован) |
| 4 | SUT0 | Select start-up time | 0 (запрограммирован) |
| 3 | CKSEL3 | Select Clock source | 0 (запрограммирован) |
| 2 | CKSEL2 | Select Clock source | 0 (запрограммирован) |
| 1 | CKSEL1 | Select Clock source | 1 (не запрограммирован) |
| 0 | CKSEL0 | Select Clock source | 0 (запрограммирован) |
Бит CKDIV8 в младшем конфигурационном байте ответственен за деление тактовой частоты на 8. Если он не запрограммирован (установлен в 1), то в регистре делителя будет значение «0000», если в данном бите установить 0, то в регистре будет значение «0011», благодаря чему тактовая частота будет делиться на 8. Однако независимо от значения бита CKDIV8 частоту делителя можно будет изменять в программе в любой момент времени.
Бит CKOUT отвечает за вывод тактовой частоты «наружу» микроконтроллера, на контакт CLK0 (цифровой контакт 8 в плате Arduino Uno). Если он запрограммирован (установлен в 0), то сигнал тактовой частоты выводится наружу – это может быть полезно в случаях когда тактовая частота используется другими периферийными устройствами. При использовании делителя системной частоты на вывод CLK0 также выводится пониженная частота.
Конфигурационные биты SUT1 и SUT0 совместно с битами CKSEL устанавливают длительность задержки при включении (старте) микроконтроллера и выбор типа осциллятора (керамический или встроенный в кристалл). Задержка нужна для того, чтобы источник тактовой частоты после подачи питания стабилизировал свою работу и вошел в рабочий режим. Величина задержки может составлять от 0 до 65 мс. Возможные значения этих битов и соответствующие устанавливаемые ими параметры приведены в следующей таблице.
Биты CKSEL0 – 4 отвечают за выбор источника тактового сигнала. В представленной на следующем рисунке таблице приведены возможные значения этих битов и соответствующие этим значениям источники тактового сигнала. В следующей таблице приведены источники тактового сигнала, поддерживаемые микроконтроллером ATmega328P, и соответствующие им значения битов CKSEL.
| Источник тактового сигнала | Значение CKSEL3..0 |
| Экономичный кварцевый генератор | 1111-1000 |
| Кварцевый генератор | 0111-0110 |
| Низкочастотный кварцевый генератор | 0101-0100 |
| Внутренний RC-генератор на 128кГц | 0011 |
| Внутренний калиброванный RC-генератор | 0010 |
| Внешний сигнал синхронизации | 0000 |
| Зарезервировано | 0001 |
С составом фьюзов разобрались, теперь перейдем к способам их чтения и изменения.
Чтение фьюзов в Arduino
Для того, чтобы прочитать фьюзы в плате Arduino, нам понадобится программа под названием Avrdude. Данная программа используется для чтения, записи и модифицирования памяти в микроконтроллерах AVR. Она работает по интерфейсу SPI и поддерживает широкий список программаторов. На нашем сайте есть достаточно подробная статья по программе Avrdude, можете ознакомиться при желании, ее свежую версию вы можете скачать по следующей ссылке:
• Download Avrdude Version 6.3 Windows-ming32.
После того, как вы скачали эту программу, вы должны извлечь ее из архива и открыть окно команд Windows в этой папке. После этого подключите программатор USBasp к вашему компьютеру, убедитесь в том, что на вашем компьютере установлен правильный драйвер для программатора USBasp. После этого вы получите возможность чтения фьюзов в плате Arduino. Для этого выполните следующую команду:
avrdude.exe -c usbasp -p m328p -U lfuse:r:low_fuse_val.txt:h -U hfuse:r:high_fuse_val.txt:h -U efuse:r:ext_fuse_val.txt:h
Если все прошло нормально, эта команда прочитает байты фьюзов (fuse bytes) и поместит их в три раздельных текстовых файла. На следующем рисунке показан общий ход этого процесса.
Как видно из представленного рисунка, программа Avrdude считала фьюзы из платы Arduino Nano и поместила их в три отдельных текстовых файла. Если вы откроете эти файлы, то вы увидите считанные значения фьюзов: EFUSE – 0xFD, HFUSE – 0XDA, LFUSE – 0xFF. Это и есть значения фьюзов по умолчанию в плате Arduino Nano
Теперь, когда мы знаем значения фьюзов по умолчанию в плате Arduino, мы можем сравнить со значениями фьюзов по умолчанию в в микроконтроллере ATmega328P
Исходное состояние фьюзов в микроконтроллере ATmega328P и в плате Arduino
Сравнение значений конфигурационных байтов микроконтроллера ATmega328P и платы Arduino представлено в трех следующих таблицах.
| № бита | Low Fuse Byte | Значение по умолчанию в AVR | Значение по умолчанию в Arduino |
| 7 | CKDIV8 | 0 (programmed) | 1 (unprogrammed) |
| 6 | CKOUT | 1 (unprogrammed) | 1 (unprogrammed) |
| 5 | SUT1 | 1 (unprogrammed) | 1 (unprogrammed) |
| 4 | SUT0 | 0 (programmed) | 1 (unprogrammed) |
| 3 | CKSEL3 | 0 (programmed) | 1 (unprogrammed) |
| 2 | CKSEL2 | 0 (programmed) | 1 (unprogrammed) |
| 1 | CKSEL1 | 1 (unprogrammed) | 1 (unprogrammed) |
| 0 | CKSEL0 | 0 (programmed) | 1 (unprogrammed) |
| № бита | High Fuse Byte | Значение по умолчанию в AVR | Значение по умолчанию в Arduino |
| 7 | RSTDISBL | 1 (unprogrammed) | 1 (unprogrammed) |
| 6 | DWEN | 1 (unprogrammed) | 1 (unprogrammed) |
| 5 | SPIEN | 0 (programmed) | 0 (programmed) |
| 4 | WDTON | 1 (unprogrammed) | 1 (unprogrammed) |
| 3 | EESAVE | 1 (unprogrammed) | 1 (unprogrammed) |
| 2 | BOOTSZ1 | 0 (programmed) | 0 (programmed) |
| 1 | BOOTSZ0 | 0 (programmed) | 1 (unprogrammed) |
| 0 | BOOTRST | 1 (unprogrammed) | 0 (programmed) |
| № бита | Extended Fuse Byte | Значение по умолчанию в AVR | Значение по умолчанию в Arduino |
| 7 | – | 1 | 1 |
| 6 | – | 1 | 1 |
| 5 | – | 1 | 1 |
| 4 | – | 1 | 1 |
| 3 | – | 1 | 1 |
| 2 | BODLEVEL2 | 1 (unprogrammed) | 1 (unprogrammed) |
| 1 | BODLEVEL1 | 1 (unprogrammed) | 0 (programmed) |
| 0 | BODLEVEL0 | 1 (unprogrammed) | 1 (unprogrammed) |
Начальное состояние микроконтроллеров ATmega328/P, в котором они поставляются с завода, является следующим: микроконтроллер сконфигурирован на работу с внутренним RC генератором на 8МГц, при этом прошитый бит CKDIV8 обеспечивает деление частоты генератора на 8; внешний сброс (по низкому уровню на выводе Reset) не запрещен; разрешено программирование по интерфейсу SPI; для загрузчика отведена область памяти 2048 слов; стартовый адрес программы 0x0000; схема контроля питания отключена.
В плате Arduino Uno фьюзы микроконтроллера изменены таким образом, чтобы он был настроен на работу с экономичным кварцевым генератором без делителя частоты; для загрузчика отводится 256 слов; прошитый бит BOOTRST назначает стартовым адресом адреса начала секции загрузчика; порог срабатывания схемы BOD составляет 2.7В.
Теперь рассмотрим процесс изменения фьюзов в плате Arduino (микроконтроллере AVR).
Необходимые компоненты
Для чтения/изменения фьюзов в микроконтроллере AVR нам будут необходимы следующие компоненты:
- Плата Arduino Nano (купить на AliExpress).
- Программатор USBasp и конвертер 10-Pin в 6-Pin для AVR (купить на AliExpress — по этой ссылке можно купить как отдельно программатор).
- USB кабель.
- Светодиод (купить на AliExpress).
- Резистор 330 Ом (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
- Программа Avrdude.
Внешний вид этих компонентов показан на следующем рисунке.
Схема проекта
Схема для чтения/изменения фьюзов в микроконтроллере AVR представлена на следующем рисунке.
Мы подключили плату Arduino Nano к компьютеру с помощью USB кабеля, также к компьютеру мы подключили программатор USBasp. Но нашей целью является программирование/изменение фьюзов в микроконтроллере AVR. Для этого мы подключили программатор USBasp к плате Arduino.
Внешний вид получившейся у нас конструкции показан на следующем рисунке:
Как вы видите из рисунка, к нашему ноутбуку подключена и плата Arduino, и программатор USBasp.
Программирование/изменение фьюзов в микроконтроллере AVR
Откройте Arduino IDE и загрузите в плату Arduino базовый скетч для мигания светодиодом (basic blink sketch).
Вы увидите, что встроенный в плату Arduino светодиод (подключенный к ее контакту 13) начнет мигать. Более подробно все эти процессы вы можете посмотреть в видео, приведенном в конце статьи. Теперь давайте попоробуем изменить фьюзы и посмотрим что произойдет. Как мы уже выяснили ранее, по умолчанию значения фьюзов в плате Arduino следующие: EFUSE – 0XFF, HFUSE – D9, LFUSE – 62. Изменим их с помощью Avrdude, для этого выполним следующую команду:
avrdude -c usbasp -p m328P -U lfuse:w:0x62:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m
После выполнения этой команды вы увидите что скорость мигания светодиода станет значительно меньше. Дело в том, что по умолчанию частота мигания светодиода определялась частотой внешнего кварцевого генератора (16 МГц), теперь же, после изменения фьюзов, она определяется частотой внутреннего RC генератора (1 МГц). Поэтому и светодиод теперь будет мигать значительно медленнее.
Но, поскольку мы изменили фьюзы, мы изменили и настройки загрузчика. Вы можете увидеть это на следующем рисунке:
Чтобы исправить это и вернуть плату Arduino в ее исходное состояние, мы должны снова загрузить в нее загрузчик. Для этого выполните Tools -> Programmer- USBasp, после этого снова зайдите в Tools и выберите пункт «burn bootloader». После этого исходная функция загрузчика загрузится в плату Arduino и она снова начнет функционировать как обычно.
После этого светодиод на плате станет снова мигать с прежней частотой.
Видео, демонстрирующее работу проекта
Загрузка…
11 405 просмотров
Загрузка прошивки
В этом уроке мы рассмотрим загрузку прошивки в ардуино через внешние “программаторы”. Давайте вспомним, о чем уже говорили в одном из первых уроков: загрузка прошивки в Arduino возможна двумя способами:
- “Напрямую” во flash память микроконтроллера при помощи ISP (In System Programming) внутрисистемного программатора.
- При помощи загрузчика (bootloader), который живёт в конце Flash памяти МК, принимает программный код по протоколу TTL (UART) и записывает его во Flash память.
Загрузчик (bootloader)
Загрузчик живёт в самом конце Flash памяти МК и позволяет записывать прошивку, отправляемую через UART. Загрузчик стартует при подаче питания на МК, ждёт некоторое время (вдруг кто-то начнёт слать код прошивки по UART), затем передаёт управление основной программе. И так происходит каждый каждый раз при старте МК.
- Загрузчик позволяет прошивать МК через UART;
- Загрузчик замедляет запуск МК, т.к. при каждом запуске ждёт некоторое время для потенциальной загрузки прошивки;
- Загрузчик занимает место во Flash памяти. Стандартный старый для Arduino NANO занимает около 2 кБ, что весьма существенно!
- Именно загрузчик мигает светодиодом на 13 пине при включении, как индикация работы.
Программатор
Помимо записи прошивки во flash память, программатор позволяет:
- Считывать содержимое Flash памяти (скачать прошивку на компьютер)
- Полностью очищать чип от всех данных и настроек
- Записывать и читать загрузчик
- Считывать/записывать EEPROM память
- Читать и настраивать фьюзы (fuses, fuse-bits) и лок биты.
Программатор – ваш единственный друг при работе с “голым” микроконтроллером, то есть для его низкоуровневой настройки и загрузки прошивки.
USB-TTL (UART)
Этот способ реализован прямо на платах Arduino при помощи USB-TTL (USB-UART) преобразователя, именно поэтому мы можем подключить плату к компьютеру и загрузить код. USB-TTL позволяет только загрузку данных во flash, остальные возможности (как у ISP программатора) ему недоступны. В то же время он ограничен только возможностями загрузчика, но в этом уроке мы рассматриваем только стандартные. Также USB-TTL мост позволяет микроконтроллеру общаться с компьютером по последовательному соединению (тот самый Serial и монитор com порта). Есть платы без бортового USB-TTL, например Arduino Pro Mini. Для работы с ними нужно купить внешний USB-TTL преобразователь. Также загрузка прошивки через UART возможна и в “голый” микроконтроллер при условии наличия там загрузчика, который запишет принятый код во flash. Про запись загрузчика мы поговорим ниже. UART “загружатор” подключается к пинам RX и TX Ардуино (или микроконтроллера), RX->TX и TX->RX, также обязательно подключается земля GND. Если у прошиваемой платы нет своего питания, то подключается и питание. Загрузчик отрабатывает при запуске МК, поэтому непосредственно перед загрузкой прошивки МК должен быть сброшен (перезагружен), и для этого на платах USB-UART есть вывод DTR (Data Terminal Ready), который подключается к пину RST Reset и собственно выполняет сброс перед перед загрузкой прошивки. На платах Pro Mini есть отдельный пин DTR.
| USB-TTL | Arduino |
| DTR | DTR |
| RX | TX |
| TX | RX |
| GND | GND |
| VCC/5V/3.3V | VCC |


ISP программатор
USBasp
Дешёвые ISP программаторы также есть в ассортименте у китайцев, рекомендую брать USBasp как самый распространенный. Поискать на алиэкспресс, мне нравится версия в корпусе. USBasp имеет не очень удобный выход 10-пин на шлейфе, поэтому рекомендуется купить также переходник 10-пин на 6-пин, который позволяет сразу подключаться к ISP header’у, который есть на большинстве плат Arduino. Внимание! Очень часто встречается брак в виде непропая контактов, поэтому во избежание проблем рекомендуется пропаять переходник и отмыть флюс (зубная щётка + бензин калоша).
Быстрый старт:
- Подключить usbasp к компьютеру
- Скачать и установить драйвера на usbasp (скачать с моего сайта, скачать с Яндекс диска, ещё есть тут и тут)
- Открыть диспетчер устройств и убедиться, что программатор определился системой
- Открыть Arduino IDE
- Выбрать usbasp в Инструменты > Программатор
Решение проблем
Решение большинства проблем с загрузкой через программатор (независимо от того, что написано в логе ошибки):
- Вытащить и обратно вставить usbasp в usb порт
- Вставить в другой usb порт
- Переустановить драйвер на usbasp
- Проверить качество соединения USBasp с МК
- Перепаять переходник и отмыть флюс
Для прошивки микроконтроллера, тактирующегося низкой частотой (менее 1 МГц внутренний клок):
- USBasp: на плате есть перемычка JP3, которая включает режим низкой скорости загрузки. В новых версиях прошивки для USBasp скорость выбирается автоматически, но китайцы продают старую версию. Как прошить новую – ищите в интернете.
Основные ошибки в логе Arduino IDE
avrdude: error: could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp' Причина – компьютер не видит USB ASP
- Проверить и сменить USB порт
- Попытаться переустановить драйвер
- Проверить пайку USB разъема на плате программатора
- Проверить наличие и целостность элементов вблизи usb разъема программатора, кварцевый резонатор
- Возможно программатор криво прошит – при возможности попытаться перепрошить
- Возможно микроконтроллер на плате программатора – брак или же мертв, попытаться заменить и прошить
avrdude: error: program enable: target doesn't answer. Причина – usbasp не видит подключаемый микроконтроллер
- Проверить правильность и целостность соединения с МК
- Попытаться снизить частоту прошивки, джампером или же указав более низкую скорость в среде программирования
- Проверить пайку разъема 10 pin и переходника 10 pin – 6 pin
- Возможно прошиваемый микроконтроллер попался с браком, или же мертв.
Arduino as ISP
Почти любая другая плата Arduino может стать ISP программатором, для этого нужно просто загрузить в неё скетч ArduinoISP:
- Открыть скетч Файл > Примеры > 11. ArduinoISP > ArduinoISP
- Всё! Ваша Arduino теперь стала ISP программатором
- Подключаем к ней другую Arduino или голый чип по схеме ниже
- Выбираем Arduino as ISP в Инструменты > Программатор
- И можем писать загрузчики, фьюзы или загружать прошивку напрямую во Flash
ISP программатор подключается к четырем пинам микроконтроллера, не считая питания: один из пинов передает сброс, остальные – для передачи данных. Чтобы плата-программатор не сбрасывалась при загрузке, на неё нужно:
- Либо поставить поставить конденсатор ёмкостью ~10 мкФ между RST и GND (рекомендуется)
- Либо просто закоротить пины RST и 5V проводом
По использованию других плат Arduino в качестве программатора читай на официальном сайте.
Решение проблем
Для прошивки микроконтроллера, тактирующегося низкой частотой (менее 1 МГц внутренний клок):
- Arduino ISP: нужно изменить частоту загрузки прошивки в скетче Arduino ISP и снова прошить его в ардуино-программатор (см. строку в скетче 45 и ниже);
Работа в Arduino IDE
Прошивка загрузчика
Из Arduino IDE при помощи ISP программатора мы можем записать другой загрузчик (по факту загрузчик + фьюзы) и загрузить скетч, а также настроить/прошить фьюзы и лок-биты, но не очень удобным способом. Когда мы выбираем плату в Инструменты > Плата и загрузчик в Инструменты > Плата (загрузчик, bootloader), Arduino IDE автоматически делает “активным” нужный загрузчик. Нажимая Инструменты > Записать загрузчик мы прошиваем загрузчик, соответствующий выбранной плате и её настройкам. Также одновременно с загрузчиком прошиваются фьюзы и лок-биты, соответствующие выбранной плате в Arduino IDE. Как и где их поменять, смотрите чуть ниже. Рассмотрим на примере записи загрузчика для atmega328, стоящей на китайской плате Arduino NANO. На данный момент китайцы прошивают в МК старую версию загрузчика, которая называется old bootloader в меню платы. Оригинальные платы идут с более современным загрузчиком, поэтому при работе с китайскими платами нам приходится выбирать old bootloader для загрузки прошивки через бортовой usb порт. Подключим usbasp по схеме выше, выберем его как программатор в Инструменты > Программатор, выберем плату Arduino NANO, загрузчик для atmega328 (первый в списке). Нажмём записать загрузчик. Всё! Теперь плату можно шить через бортовой usb порт, выбирая первый загрузчик. Он кстати легче, быстрее “прошивает” и сама прошивка быстрее “запускается”.
Как убрать загрузчик?
В стандартном “ядре” Arduino не предусмотрен вариант “без загрузчика”. Для того, чтобы вручную убрать поддержку загрузчика, нужно уметь работать с boards.txt и фьюзами: нужно будет изменить фьюз BOOTRST и подправить максимальный размер скетча. Есть более простой вариант – найти и установить ядро, в котором реализован выбор загрузчика с вариантом “без загрузчика”, например для ATmega328 это miniCore и наше GyverCore. Нужно установить поддержку ядра по рассмотренной ранее инструкции, выбрать плату, указать вариант “без загрузчика” и нажать “Записать загрузчик”. В МК будут прошиты соответствующие фьюзы.
Загрузка скетча
В Arduino IDE можно зашить скетч через программатор, для этого надо нажать Скетч > Загрузить через программатор. Это очень удобно в том случае, когда МК используется без загрузчика, или просто голый МК.
Внимание! Загрузчик будет стёрт!
Фьюзы
Конфигуратор платы в Arduino IDE устроен следующим образом: каждой плате в Инструменты > Плата соответствует свой набор настроек, включая фьюзы, которые прошиваются вместе с загрузчиком. Некоторые из них:
- Загрузчик (путь к файлу)
- Скорость загрузки (через загрузчик)
- Объем доступной flash и sram памяти
- Весь набор фьюзов и лок-биты
Файл конфигурации называется boards.txt и найти его можно в папке с ядром Arduino: C:Program Files (x86)Arduinohardwarearduinoavrboards.txt. Документацию на boards.txt можно почитать здесь. При желании можно вывести нужные фьюзы через калькулятор (читайте выше), изменить их в boards.txt (главное не запутаться, для какой выбранной конфигурации платы делается изменение) и прошить в МК, нажав Инструменты > Записать загрузчик.
- Фьюзы подписаны как low/high/extended fuses, можно вставлять полученное в калькуляторе значение.
- Локбиты работают следующим образом: unlock_bits это локбиты, которые прошьются до записи загрузчика (при нажатии на кнопку Записать загрузчик). А вот после прошивки загрузчика будут автоматически прошиты lock_bits, которые и определят доступ к памяти контроллера во время его работы. Чтобы защитить прошивку от чтения – ставим lock_bits 0x3C.
Такая работа с фьюзами максимально неудобна, но есть и другие варианты:
- Ядро GyverCore для atmega328, в нем мы сделали кучу готовых настроек фьюзов прямо в настройках платы, читайте в уроке про GyverCore. Несколько загрузчиков, включая вариант без загрузчика, выбор источника тактирования и другие настройки в один клик мышкой.
- Программа AVRdudeprog, про нее поговорим ниже
Фьюзы (Pro)
Фьюзы (фьюз-биты) являются низкоуровневыми настройками микроконтроллера, которые хранятся в специальном месте в памяти и могут быть изменены только при помощи ISP программатора. Это такие настройки как выбор источника тактирования, размер области памяти под загрузчик, настройка отсечки по напряжению и прочее. Фьюз-биты собраны по 8 штук в байты (т.н. байты конфигурации), как типичный регистр микроконтроллера AVR. Таких байтов может быть несколько, они называются low fuses, high fuses, extended fuses. Для конфигурации байтов рекомендуется использовать калькулятор фьюзов (например, вот такой), в котором просто ставятся галочки на нужных битах, и на выходе получается готовый байт в hex виде. Рассмотрим на примере ATmega328p:
Важный момент: в AVR биты у нас инверсные, то есть 1 это выкл, 0 это вкл. Расставляя галочки в калькуляторе, мы формируем байт, галочка стоит – бит включен, но в результирующем байте включенные биты являются нулями. Об этом стоит задумываться при ручном составлении фьюз-байта, при использовании калькулятора можете об этом даже не вспоминать. Что позволяют настроить биты?
- CKSEL0–CKSEL3 – выбор источника и частоты тактирования (уточняй в даташите на свой МК, какая конфигурация за что отвечает)
- SUT0–SUT1 – задержка старта МК после перезагрузки
- CKOUT – дублирование тактирования на один из пинов (см. в даташите на какой)
- CKDIV8 – делит тактовую частоту на 8
- BOOTRST – если включен, МК запускается с загрузчика
- BOOTSZ0–BOOTSZ1 – задаёт размер сектора загрузчика
- EESAVE – защита EEPROM от стирания во время выполнения полной очистки чипа
- WDTON – если включить, то Watchdog будет принудительно включен без возможности отключения
- SPIEN – опасный бит, при его отключении пропадает возможность прошивки через ISP, и возможность выключить этот бит в том числе*
- DWEN – вкл/выкл отладочный интерфейс DebugWire. На других моделях бывает и JTAG, и его бит – JTAGEN
- RSTDISBL – опасный бит, при его включении можно использовать ногу RST как обычный цифровой пин, но пропадает возможность прошивки через ISP и выключить этот бит как следствие*
- BODLEVEL0–BODLEVEL3 – настройка контроля напряжения (МК сбросится при падении ниже установленного напряжения)
* – прошивка возможна при помощи высоковольтного программатора
Лок-биты (Pro)
Лок-биты (lock-bits) позволяют управлять доступом к памяти микроконтроллера, что обычно используется для защиты устройства от копирования. Лок-биты собраны опять же в конфигурационный лок-байт, который содержит: BOOTLOCK01, BOOTLOCK02, BOOTLOCK11, BOOTLOCK12, LOCKBIT1, LOCKBIT2 (для ATmega328). Калькулятор лок-битов можно использовать этот. BOOTLOCK биты позволяют запретить самому МК запись (самопрограммирование) во flash память (область программы и область загрузчика)
А вот локбиты LOCKBIT позволяют запретить запись и чтение flash и EEPROM памяти извне, при помощи программатора, т.е. полностью защитить прошивку от скачивания и копирования:
Таким образом включив LOCKBIT1 (лок-байт будет 0x3E) мы запретим внешнюю запись во Flash и EEPROM память, т.е. при помощи ISP программатора, а включив LOCKBIT1 и LOCKBIT2 (лок-байт: 0x3C) полностью заблокируем заодно и чтение данных из памяти микроконтроллера. Повторюсь, всё описанное выше относится к ATmega328p, для других моделей МК читайте в соответствующих даташитах.
Avrdudeprog
Avrdudeprog – утилита от русского программиста, являющаяся удобной оболочкой для avrdudue. Скачать AVRDUDE_PROG можно с официального сайта (прямая ссылка на загрузку, на всякий случай зеркало на моём ЯД и FTP этого сайта). В рамках этого урока, программа умеет следующее:
- Чтение/запись/очистка flash памяти
- Чтение/запись/очистка eeprom памяти
- Полная очистка чипа
- Калькулятор фьюзов и локбитов (чтение/запись)
Более подробный обзор на avrdudeprog можно посмотреть здесь. Давайте посмотрим на калькулятор фьюзов. Выбираем свой микроконтроллер и программатор (можно добавить другие модели микроконтроллеров и программаторов, читай тут). Переходим во вкладку Fuses, нажимаем прочитать. При успешном чтении увидим текущий набор настроек своего чипа. Можно их поменять и загрузить. Важно! Галку инверсные биты не трогаем! Лок-биты и отключение RST заблокирует микроконтроллер, не трогайте их, если такой цели нет! Можно загружать прошивку или загрузчик из .hex файла, указав путь к ней на первой вкладке в окне Flash. Очень удобная утилита для низкоуровневой работы с МК.
Видео
Полезные страницы
- Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
- Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
- Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
- Полная документация по языку Ардуино, все встроенные функции и макросы, все доступные типы данных
- Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
- Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
- Поддержать автора за работу над уроками
- Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])
Статья не очень интересная, но может кто-то столкнётся с такой проблемой.
В моём арсенале «приборчиков радиолюбителя» имеется программатор UsbTiny. В качестве программы для прошивки микроконтроллеров (МК) я использую SinaProg.
SinaProg – это графическая оболочка для программы AVRDude – очень мощной, но консольной программы для прошивки МК. И чтобы не мучиться с прописыванием параметров как во времена доброго MS-DOSа, придумали такую программку-оболочку.
До недавнего времени меня всё устраивало. Но вот приехала партия микроконтроллеров ATmega328P (на них работают Arduino Uno), и тут началось… В списке поддерживаемых программой микроконтроллеров ATmega328P имеется, прошивка шьется, читается, всё бы ничего, но не работает функция установки фьюзов. При входе в «калькулятор фьюзов», программа не даёт изменять значения (см.скриншот):
Непорядок. Я решил разобраться в чём дело. Первым делом я поискал новую версию SinaProg. Нашел какую то другую версию, обновил, но всё осталось по прежнему. Сайт разработчиков, как выяснилось, уже давно не работает. Ну что ж, придётся разбираться самому. Заходим в папку с программой. Видим там файлы:
В файле «Device.txt» содержится список поддерживаемых МК. Можно добавлять новые МК если их нет в списке. ATmega328P в этом списке есть (левый столбец). Также в файле содержатся сигнатуры (типа уникального ID номера) всех МК (в правом столбце). Смотрим скриншот, поехали дальше.
Проблема в том, что не меняются фьюзы, обратим внимание на файлы Calc_xx.cal. Они нам и нужны, и отвечают за калькулятор фьюзов. Очевидно, что где-то в них что-то не дописано, либо написано неверно. Открываем файлы при помощи «Блокнота», так как внутри они содержат обычный текст. Содержание у всех файлов похожее, и я не буду рассматривать каждый из них. Коротко расскажу какой файл за что отвечает:
-«Calc_EF.cal» – отвечает за фьюзы группы «Extended Fuses», или расширенные настройки
-«Calc_HF.cal» – отвечает за фьюзы группы «High Fuses»
-«Calc_LB.cal» – отвечает за фьюзы группы «Lock Bits», проще говоря – блокировки, защита.
-«Calc_LF.cal» – отвечает за фьюзы группы «Low Fuses»
Для примера откроем в «блокноте» файл «Calc_LB.cal». Вот что мы увидим:
Как мы видим, сразу после ATmega3250 идёт ATmega329, а нашей атмеги328 здесь нету. А это значит, что её нужно добавить. Как нам это сделать? В принципе не сложно. Для этого взглянем на даташит ATmega328P:
Как видно из даташита, МК ATmega328P совместим по своему устройству с МК ATmega48PA/88PA/168PA, отличие лишь в количестве памяти программ, памяти данных, и размере загрузчика. Поэтому попробуем найти например ATmega168 в нашем файле:
ATmega168 в файле имеется, выделяем и копируем все строки, относящиеся к ATmega168. Затем добавляем пустую строку между ATmega3250 и ATmega329, и вставляем туда то, что мы скопировали. Во всех строках заменяем ATmega168 на ATmega328P. Должно получиться что-то вроде этого:
Закрываем файл, сохранив внесённые изменения. Такую же операцию проделываем и над файлами «Calc_HF.cal» и «Calc_LF.cal».Остаётся изменить содержимое файла «Calc_EF.cal», всё делается по тому же принципу, но с небольшой поправкой. В этом файле прописаны фьюзы, отвечающие в основном за размер загрузчика. А так, как ATmega48PA/88PA/168PA/328P отличаются обьёмом памяти на борту, то и размеры загрузчиков у них разные. Поэтому внесём поправки. ATmega168 имеет 16кб памяти программ, а ATmega328P соответственно 32 кб памяти. И размер загрузчика у них отличается ровно в 2 раза. Поэтому открываем файл, находим ATmega168, копируем все строки, вставляем, меняем название МК на ATmega328P, и смотрим на скриншот:
Нужно размеры загрузчиков увеличить в 2 раза, так как размер памяти стал больше в 2 раза. Увеличили, закрываем и сохраняем файл. Теперь запускаем SinaProg, заходим в калькулятор фьюзов, и видим:
Кнопочки стали активны, и фьюзы можно изменять. Таким же образом можно добавлять и другие МК, а значения необязательно копировать от другого МК. Если хорошенько почитать даташит, то все эти значения там имеются, и можно просто написать строки самому, по аналогии с любым другим МК.
Так как SinaProg работает на основе AVRDUDE, то напоследок скачаем и обновим AVRDUDE в папке с SinaProg. Последнюю версию AVRDUDE можно взять с официального сайта, либо скачать внизу страницы, я приложил последнюю версию на момент написания статьи. Из архива нам потребуется собственно, сама программа «AVRDUDE.exe» и конфигурационный файл «avrdude.conf». Так было:
Так стало после замены старых файлов AVRDUDE на новые:
В консоль теперь стали выводиться байты фьюзов.
В файлах прилагаю архив с моей «доделанной» версией SinaProg (с поддержкой фьюзов ATmega328P и обновлённым AVRDUDE).
Теги:




Я собрал
0
1
x
Оценить статью
- Техническая грамотность
- Актуальность материала
- Изложение материала
- Полезность устройства
- Повторяемость устройства
- Орфография
0
Средний балл статьи: 5
Проголосовало: 1 чел.
Добавлено 17 января 2018 в 19:05
В данном проекте приводится введение во fuse-биты ATmega328P и показывается, как установить их для использования внешнего кварцевого резонатора 16 МГц.
Обзор статьи
Fuse-биты, также известные как фьюзы или биты конфигурации, – это настройки микроконтроллера для управления определенными действиями, которые обычно не изменяются во время выполнения программного кода. В данной статье вкратце объясняется, какие действия находятся в ATmega328P, и как их устанавливать. Fuse-биты для выбора источника тактового сигнала будут рассмотрены более подробно, в том числе, как и зачем выбрать внешний кварцевый резонатор 16 МГц.
Схема программирования ATMega328P
На фотографии ниже показана простая схема программирования ATmega328P. Схема, полный список компонентов и подробности о сборке содержатся в предыдущей статье. Для продолжения работы с данной статьей вам понадобится собрать данную схему.
Биты конфигурации ATmega328P
Три байта конфигурации
В ATmega328P в общей сложности имеется 19 бит конфигурации, и они разделены на три разных байта конфигурации. Три бита конфигурации содержатся в «дополнительном байте конфигурации», восемь – в «старшем байте конфигурации», и еще восемь – в «младшем байте конфигурации».
Ниже приводится таблица 31-5 из технического описания ATmega328P версии от ноября 2016 года. Как вы можете видеть, весь дополнительный байт конфигурации работает с уровнем контроля понижения напряжения питания микроконтроллера (brownout).Контроль понижения напряжения питания (brownout) является особенность многих микроконтроллеров, что позволяет им перезагружаться, когда напряжение питания падает ниже определенного уровня. В случае ATMega328P в качестве минимально допустимого напряжения питания можно выбрать одно из трех разных напряжений (1,8 В, 2,7 В или 4,3 В).
Возможно, самое важное, на что следует обратить внимание в таблице, состоит в том, что программирование битов конфигурации состоит в установке их в состояние логического нуля, что является противоположностью ожидаемого поведения. Например, обратите внимание, что каждый бит не запрограммирован, когда он установлен в высокий логический уровень, т.е. 1. Этот несколько необычный метод применяется ко всем байтам конфигурации ATmega328P.
| Название бита конфигурации | Номер бита | Описание | Значение по умолчанию |
|---|---|---|---|
| – | 7 | – | 1 |
| – | 6 | – | 1 |
| – | 5 | – | 1 |
| – | 4 | – | 1 |
| – | 3 | – | 1 |
| BODLEVEL2 | 2 | Уровень срабатывания детектора понижения напряжения питания | 1 (не запрограммирован) |
| BODLEVEL1 | 1 | Уровень срабатывания детектора понижения напряжения питания | 1 (не запрограммирован) |
| BODLEVEL0 | 0 | Уровень срабатывания детектора понижения напряжения питания | 1 (не запрограммирован) |
Ниже приведена таблица 31-6 из технического описания. Биты 2-0 используются для установки размера области загрузки ATmega328P; размер области загрузки относится к объему памяти, зарезервированному для установки «загрузчика», аналогичного функции загрузчика, используемого в линейке отладочных плат Arduino. Назначение оставшихся битов в старшем байте конфигурации достаточно понятно из описаний в таблице. Два бита, которых следует избегать, если вы не уверены, что знаете, что делаете, это бит 7, бит RSTDISBL (выключение внешнего сброса), и бит 5 бит SPIEN (включение последовательного периферийного интерфейса). Отключение одного из них часто является причиной появления «кирпичных» микроконтроллеров Atmel; поэтому хорошим советом будет: «оставить их в покое».
| Название бита конфигурации | Номер бита | Описание | Значение по умолчанию |
|---|---|---|---|
| RSTDISBL | 7 | Выключение внешнего сброса | 1 (не запрограммирован) |
| DWEN | 6 | Включение DebugWire | 1 (не запрограммирован) |
| SPIEN | 5 | Включение последовательного программирования и загрузки данных | 0 (запрограммирован, SPI программирование включено) |
| WDTON | 4 | Сторожевой таймер всегда включен | 1 (не запрограммирован) |
| EESAVE | 3 | Память EEPROM сохраняется при стирании чипа | 1 (не запрограммирован), EEPROM не защищена |
| BOOTSZ1 | 2 | Выбор размера области загрузки (смотрите параметры загрузчика) | 0 (запрограммирован) |
| BOOTSZ0 | 1 | Выбор размера области загрузки (смотрите параметры загрузчика) | 0 (запрограммирован) |
| BOOTRST | 0 | Выбор вектора сброса | 1 (не запрограммирован) |
Подробная информация о назначении всех 19 битов конфигурации содержится в техническом описании ATmega328P; в данной статье будет включено описание настройки младшего байта конфигурации. Однако общий процесс программирования всех битов конфигурации аналогичен.
Варианты выбора младшего байта конфигурации
Младший байт конфигурации выбирает источник тактового сигнала ATmega328P и управляет некоторыми деталями работы тактовой синхронизации. Ниже приведена таблица 31-7 из технического описания.
| Название бита конфигурации | Номер бита | Описание | Значение по умолчанию |
|---|---|---|---|
| CKDIV8 | 7 | Делитель на 8 | 0 (запрограммирован) |
| CKOUT | 6 | Выход тактового сигнала | 1 (не запрограммирован) |
| SUT1 | 5 | Выбор времени запуска | 1 (не запрограммирован) |
| SUT0 | 4 | Выбор времени запуска | 0 (запрограммирован) |
| CKSEL3 | 3 | Выбор источника тактового сигнала | 0 (запрограммирован) |
| CKSEL2 | 2 | Выбор источника тактового сигнала | 0 (запрограммирован) |
| CKSEL1 | 1 | Выбор источника тактового сигнала | 1 (не запрограммирован) |
| CKSEL0 | 0 | Выбор источника тактового сигнала | 0 (запрограммирован) |
Не забывайте, что программирование бита конфигурации состоит в том, чтобы установить его в состояние низкого логического уровня, т.е. 0. Например, обратите внимание, что бит 7 используется для включения/выключения деления частоты тактового сигнала на 8; чтобы включить деление тактовой частоты на 8, бит 7 должен быть установлен в 0, а для отключения деления бит 7 должен быть установлен в 1.
- Бит 7 управляет тем, включена ли функция деления тактовой частоты на 8, а бит 6 определяет, присутствует ли выходной тактовый сигнал на выводе PORTB0 микроконтроллера.
- Биты 5 и 4 управляют временем запуска микроконтроллера, что предназначено для предотвращения попытки микросхемы начать работу до того, как напряжение питания достигнет приемлемого минимального уровня.
- Биты с 3 по 0 используются для выбора источника тактового сигнала, а в таблице 13-1 представлены доступные источники.
| Тактирующее устройство | CKSEL[3:0] |
|---|---|
| Маломощный генератор на кварцевом резонаторе | 1111 – 1000 |
| Генератор на кварцевом резонаторе | 0111 – 0110 |
| Низкочастотный генератор на кварцевом резонаторе | 0101 – 0100 |
| Внутренний RC генератор 128 кГц | 0011 |
| Откалиброванный внутренний RC генератор | 0010 |
| Внешний тактовый сигнал | 0000 |
| Зарезервировано | 0001 |
Примечание: для всех битов конфигурации, ‘1’ означает не запрограммированный, а ‘0’ – запрограммированный.
Значения по умолчанию младшего байта конфигурации
Вау! По общему признанию, чтобы установить 8 бит младшего байта конфигурации, требуется много данных, но всё это необходимо, и нет «пути обхода» (рискуя казаться чрезмерно критичным, автор данной статьи считает, что техническое описание может быть написано более четко, чтобы передать детали этого довольно запутанного процесса).
К счастью, есть много информации, которая в техническом описании указана четко, значения по умолчанию, установленные в ATmega328, не содержат ошибок. Посмотрите на таблицу 31-7, представленную ранее:
- деление частоты тактового сигнала на 8 включено установкой бита 7 в 0;
- выход тактового сигнала на PORTB0 выключен установкой бита 6 в 1;
- выбор источника тактового сигнала установлен на внутренний откалиброванный RC генератор установкой битов 3, 2, 1 и 0 в значения 0010 (смотрите таблицу 13-1 выше и таблицу 13-11 ниже);
| Диапазон частот(1), МГц | CKSEL[3:0] |
|---|---|
| 7,3 – 8,1 | 0010(2) |
Примечание:
- если согласно спецификации на устройство ожидается частота 8 МГц (зависит от VCC), бит CKDIV8 должен быть запрограммирован соответствующим образом;
- устройство поставляется с выбором этого варианта.
- время запуска частично зависит от выбранного типа генератора и устанавливается битами 5 и 4. В случае внутреннего откалиброванного RC генератора эта информация берется из таблицы 13-12. Программирование битов 5 и 4 (SUT1 и SUT0) задается для каждого из трех условий питания. По умолчанию используется медленно нарастающее питание и приводит к времени запуска 6 тактовых циклов после выключения и снижения энергопотребления, плюс дополнительные 14 тактовых циклов и 65 миллисекунд запуска после сброса. Смотрите таблицу 13-12 ниже
| Условия питания | Время запуска после выключения и снижения энергопотребления | Дополнительная задержка после сброса (VCC = 5.0 В) | SUT[1:0] |
|---|---|---|---|
| Контроль понижения напряжения питания (BOD) включен | 6 тактовых циклов | 14 тактовых циклов | 00 |
| Быстро нарастающее напряжение питания | 6 тактовых циклов | 14 тактовых циклов + 4,1 мс | 01 |
| Медленно нарастающее напряжение питания | 6 тактовых циклов | 14 тактовых циклов + 65 мс | 10(1) |
| Зарезервировано | 11 |
Примечание:
- устройство поставляется с выбором этого варианта.
Теперь вам должно быть понятно, что младший байт конфигурации предварительно запрограммирован на 01100010 (что в шестнадцатеричной нотации равно 0x62), и что это значит для работы микроконтроллера. Если что-то из этого вам непонятно, не удивляйтесь: это сложный вопрос. Вероятно, вам стоит потратить время и перечитать разделы 13 и 31 технического описания ATmega328P.
Теперь сделаем некоторые изменения
Если вы знакомы с семейством микроконтроллерных платформ Arduino, особенно с Arduino Uno, вы, вероятно, помните, что она использует микроконтроллер ATmega328P. Возможно, вы также помните, что UNO имеет внешнюю схему генератора, состоящую из кристалла 16 МГц и двух небольших керамических конденсаторов (часто около 22 пФ каждый). Вы можете также вспомнить, что рабочая частота UNO равна 16 МГц.
Но как насчет ATmega328P? Можете ли вы определить его стандартную рабочую частоту, когда он поставляется с завода?
Вы знаете, что по умолчанию источник тактового сигнала в ATmega328P – это внутренний RC генератор, но вы помните его частоту? Ответ в приложении 2 в таблице 31-7: 8 МГц. И поскольку значение по умолчанию бита 7 младшего байта конфигурации равно 0, деление тактовой частоты на 8 включено. Таким образом, стандартная рабочая частота ATmega328P равна… погодите… 1 МГц.
Но предположим, ваш проект требует тактовую частоту ATmega328P 16 МГц, знаете ли вы, как это сделать? Как обычно, требуется и аппаратное, и программное вмешательство.
Аппаратные изменения: добавим кварцевый резонатор
Чтобы запустить ATmega328P на частоте 16 МГц, вам нужно добавить в схему, показанную в самом начале статьи, внешний кварцевый резонатор. Требуются только три новые детали: резонатор 16 МГц и два керамических конденсатора 22 пФ. Полученная схема показана ниже, а после нее показана фотография собранного макета.
Программные изменения: изменение настроек младшего байта конфигурации
После того, как вы добавили схему кварцевого генератора на 16 МГц и дважды перепроверили разводку, следующая цель – определить, какие изменения в битах конфигурации необходимы для кварцевого генератора низкой мощности. Дополнительный и старший байты конфигурации не зависят от изменений генератора; необходимо изменить только младший байт конфигурации.
Предупреждение! Не меняйте источник синхронизации на внешний кварц, если у вас на самом деле кварцевый резонатор не установлен. Если вы сделаете это, на ATmega328P не будет поступать тактовый сигнал, и поэтому перепрограммировать его возможности не будет.
Рассмотрим младший байт конфигурации бит за битом.
- Бит 7 управляет операцией деления на 8, и значение по умолчанию 0 включает эту функцию, которая нам не нужна. Итак, бит 7 необходимо изменить с 0 на 1.
- Бит 6 управляет выходом тактового сигнала PORTB0, который нам неинтересен. Таким образом, бит 6 может оставаться установленным в 1.
- Биты 3-0 управляют выбором генератора, а настройка по умолчанию 0010 использует калиброванный внутренний RC генератор, который нам не нужен. Вам нужен кварцевый генератор малой мощности, и согласно таблице 13-1 биты 3-0 должны быть установлены на 1111, 1110, 1101, 1100, 1011, 1010, 1001 или 1000, но на какое именно значение? Читаем дальше.
| Тактирующее устройство | CKSEL[3:0] |
|---|---|
| Маломощный генератор на кварцевом резонаторе | 1111 – 1000 |
| Генератор на кварцевом резонаторе | 0111 – 0110 |
| Низкочастотный генератор на кварцевом резонаторе | 0101 – 0100 |
| Внутренний RC генератор 128 кГц | 0011 |
| Откалиброванный внутренний RC генератор | 0010 |
| Внешний тактовый сигнал | 0000 |
| Зарезервировано | 0001 |
Примечание: для всех битов конфигурации, ‘1’ означает не запрограммированный, а ‘0’ – запрограммированный.
Таблица 13-3 указывает, что для работы с частотой от 8,0 до 16,0 МГц биты 3-1 (CKSEL[3:1]) должны быть установлены в 111. Но что с CKSEL0? Читаем дальше.
| Диапазон частот, МГц | CKSEL[3:1](2) | Диапазон номиналов конденсаторов C1 и C2, пФ |
|---|---|---|
| 0,4 – 0,9 | 100(3) | – |
| 0,9 – 3,0 | 101 | 12 – 22 |
| 3,0 – 8,0 | 110 | 12 – 22 |
| 8,0 – 16,0 | 111 | 12 – 22 |
Примечание:
- если частота кварцевого резонатора превышает требования в спецификации устройства (зависит от VCC), бит CKDIV8 может быть запрограммирован на деление внутренней частоты на 8. При этом необходимо убедиться, что полученная деленная частота соответствует требованиям к частоте в спецификации устройства;
- рекомендуемые настройки CKSEL для разных частотных диапазонов;
- этот вариант не может использоваться с кварцевыми резонаторами, а только с керамическими резонаторами.
Биты 5 и 4 управляют временем запуска, а значение по умолчанию 10 обеспечивает задержку запуска на 6 тактовых циклов после выключения или снижения энергопотребления плюс дополнительную задержку запуска на 14 тактовых циклов плюс 65 миллисекунд после сброса. Из таблицы 13-4 видно, что, чтобы быть в безопасной зоне для кварцевого генератора малой мощности, вам необходима максимально возможная задержка в 16000 тактовых циклов после выключения или снижения энергопотребления, поэтому SUT1 должен быть установлен в 1, плюс дополнительная задержка запуска на 14 тактовых циклов и 65 миллисекунд после сброса, поэтому SUT0 должен быть установлен в 1. Кроме того, CKSEL0 должен быть установлен в 1.
| Резонатор генератора источника / условия питания | Время запуска после выключения и снижения энергопотребления | Дополнительная задержка после сброса (VCC = 5.0 В) | CKSEL0 | SUT[1:0] |
|---|---|---|---|---|
| Керамический резонатор, быстро нарастающее напряжение питания | 258 тактовых циклов | 14 тактовых циклов + 4,1 мс(1) | 0 | 00 |
| Керамический резонатор, медленно нарастающее напряжение питания | 258 тактовых циклов | 14 тактовых циклов + 65 мс(2) | 0 | 01 |
| Керамический резонатор, BOD включен | 1 тактовый цикл | 14 тактовых циклов(2) | 0 | 10 |
| Керамический резонатор, быстро нарастающее напряжение питания | 1 тактовый цикл | 14 тактовых циклов + 4,1 мс(2) | 0 | 11 |
| Керамический резонатор, медленно нарастающее напряжение питания | 1 тактовый цикл | 14 тактовых циклов + 65 мс(2) | 1 | 00 |
| Кварцевый резонатор, BOD включен | 16 тактовых циклов | 14 тактовых циклов | 1 | 01 |
| Кварцевый резонатор, быстро нарастающее напряжение питания | 16 тактовых циклов | 14 тактовых циклов + 4,1 мс | 1 | 10 |
| Кварцевый резонатор, медленно нарастающее напряжение питания | 16 тактовых циклов | 14 тактовых циклов + 65 мс | 1 | 11 |
Примечание:
- эти варианты могут использоваться только, когда рабочая частота не близка к максимальной частоте устройства, и если стабильность частоты при запуске для приложения не важна. Эти варианты не подходят для кварцевых резонаторов;
- эти варианты предназначены для использования с керамическими резонаторами и обеспечивают стабильность частоты при запуске. Они также могут использоваться с кварцевыми резонаторами, когда рабочая частота не близка к максимальной частоте устройства, а стабильность частоты при запуске для приложения не важна.
Таким образом, бит 7 равен 1, бит 6 равен 1, бит 5 равен 1, бит 4 равен 1, биты 3-0 равны 1111. Следовательно, младший байт конфигурации должен быть равен 11111111, что в шестнадцатеричной нотации равно 0xFF. Наконец-то мы получили его!
Avrdude
Avrdude – это утилита с командной строкой, которая более подробно объясняется в этой статье. Это единственный программный инструмент, необходимый для программирования изменений байтов конфигурации в ATmega328P и длинного списка других микроконтроллеров Atmel. Скриншот ниже – это реальный сеанс avrdude с карманным программатором AVR, подключенным к ATmega328P, как показано на принципиальной схеме и макетной сборке выше. Номера строк были добавлены на скриншот, чтобы упростить описание сессии программирования.
Строки 1-3 были сгенерированы avrdude, как только программа была запущена.
Строка 5 показывает, что активный каталог изменяется на место, где была установлена avrdude. В этом случае каталог также называется «avrdude». Вы должны перейти в каталог, в который установили avrdude на свой компьютер.
Строка 7 – это команда, чтобы указать avrdude, какие используются программатор и микроконтроллер. В этом случае программатор AVR Pocket использует драйвер USBTiny, а используемый микроконтроллер – ATmega328P.
Строки 9-17 – это отклики avrdude. Строка 13 представляет сигнатуру ATmega328P в шестнадцатеричной нотации 0x1e950f. Строка 15 представляет байты конфигурации, запрограммированные в ATmega328P в текущее время, также в шестнадцатеричной нотации; в этом случае байты конфигурации запрограммированы на заводе и имеют значения по умолчанию. Дополнительный байт конфигурации равен 0xFF, старший байт конфигурации равен 0xD9, и младший байт конфигурации равен 0x62.
Строка 20 – это команда, чтобы сказать avrdude, какие используются программатор и микроконтроллер, и изменить младший байт конфигурации на 0xFF.
Строки 22-45 – это ответы от avrdude. Каждая строка представляет выполненный шаг, а строка 43 представляет программирование новых битов конфигурации в ATmega328P. Дополнительный байт конфигурации равен 0xFF, старший байт конфигурации равен 0xD9, и младший байт конфигурации равен 0xFF.
Строка 48 – это команда, указывающая avrdude, какие используются программатор и микроконтроллер, и изменить младший байт конфигурации на 0x62 (установка младшего байта конфигурации на 0x62 необходима, только если вы хотите вернуться к исходной конфигурации, поскольку значение 0x62 является значением по умолчанию).
Строки 50-73 – это ответы от avrdude. Каждая строка представляет выполненный шаг, а строка 71 представляет программирование новых битов конфигурации в ATmega328P. Дополнительный байт конфигурации равен 0xFF, старший байт конфигурации равен 0xD9, и младший байт конфигурации равен 0x62. Теперь байты конфигурации снова запрограммированы на заводские значения по умолчанию.
«Прошивка» младшего байта конфигурации
Когда всё (и аппаратное, и программное обеспечение) готово, реальное перепрограммирование байтов конфигурации довольно противоречиво; оно происходит так быстро, что, если вы не смотрите внимательно, то можете упустить его. Таким образом, стоит представить некоторые доказательства выполненных изменений. Это достаточно легко сделать, используя ту же программу мигания светодиодом, что и в статье «Макетирование и программирование ATmega328P и ATtiny45 с помощью Atmel Studio 7». Если она всё еще запрограммирована в ваш ATmega328P, то вы готовы; если нет, то создайте файл с кодом, приведенным ниже, и запрограммируйте микроконтроллер скомпилированной программой.
//New Blink.c
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB |= 0b00000001;
while (1) {
PORTB = 0b00000001;
_delay_ms(500);
PORTB = 0b00000000;
_delay_ms(500);
}
return 0;
}
New_Blink.c мигает желтым светодиодом, включая его на ½ секунды и выключая на ½, 60 раз в минуту. Убедитесь, что программа всё еще делает это на вашем макете.
Как вы (надеюсь) вспомните, ATmega328P использует свой откалиброванный внутренний генератор и не полагается на 16-мегагерцовый кварцевый резонатор, который вы только что добавили. В данный момент резонатор игнорируется из-за настроек младшего байта конфигурации (помните, что младший байт конфигурации всё еще установлен в заводское значение по умолчанию 0x62, которое указывает на использование внутреннего геренатора). К счастью, наличие резонатора и двух конденсаторов 22 пФ ничем не мешает использованию внутреннего генератора. Чтобы перейти на 16-мегагерцовый кварцевый генератор, выполните следующие два шага:
- сначала запустите avrdude, а затем выполните процедуру, описанную в строках 4-17 на скриншоте выше. Результат должен подтвердить, что младший байт конфигурации по-прежнему установлен в 0x62, что указывает на использование откалиброванного внутреннего генератора;
- затем следуйте процедуре, описанной в строках 20-45. Результат должен подтвердить, что младший байт конфигурации теперь изменен на 0xFF, что указывает на использование кварцевого генератора.
Следите за желтым светодиодом; вы заметили, что скорость мигания изменилась? Вот почему.
Мало того, что значение младшего байта конфигурации 0x62 вызывает использование внутреннего генератора 8 МГц, оно также указывает на то, что включена функция деления на 8. Поэтому эффективная частота генератора составляет 1 МГц, что отражено в строке 3 кода New_Blink.c (важно понимать, что строка 3 не контролирует частоту, с которой запускается ATmega328P, а просто сообщает компилятору, что микроконтроллер должен работать на частоте 1 МГц, чтобы код выполнялся с нужной скоростью).
Поскольку вы изменили младший байт конфигурации с 0x62 на 0xFF, вы изменили используемый генератор на кварцевый генератор 16 МГц. Кроме того, вы отключили функцию деления на 8. Чистый эффект этих двух изменений заключается в том, что тактовая частота ATmega328P теперь составляет 16 МГц, но строка 3 New_Blink.c всё еще сообщает компилятору, что микроконтроллер работает на частоте 1 МГц. Поэтому скорость мигания теперь в 16 раз больше, чем должна быть. Что делать?
Запустите Atmel Studio 7 и, разумеется, измените строку 3. Вместо #define F_CPU 1000000UL измените строку 3 на #define F_CPU 16000000UL, что сообщит компилятору, что тактовая частота теперь равна 16 МГц. Затем перекомпилируйте проект и загрузите обновленный код в ATmega328P. Почти сразу диод возобновит мигание, выключаясь на ½ секунды и включаясь на ½ секунды, 60 раз в минуту, что именно то, чего мы и хотели.
А есть способ проще?
Вы можете спросить: «А нет более простого способа?», и ответ: «Да». Есть несколько онлайн-приложений, которые будут определять настроки байта конфигурации, отображающие выбранные функции, и одним из самых популярных является калькулятор EngBedded’s AVR Fuse Calculator. Тем не менее, веб-сайты могут исчезать, и всегда хорошо знать, как сделать это самостоятельно; таким образом вы можете в дополнение к «что» понять «как» и «почему».
Что дальше?
В следующей статье из серии мы обсудим работу Atmel Studio 7 более подробно и рассмотрим более дешевый способ получения genuine Atmel ICE программатора.
Теги
ATmegaATmega328PAVRAVRDUDEMCUБиты конфигурацииВнешний генераторКварцевый генераторКварцевый резонаторМикроконтроллерПрограммированиеФьюзы (fuse bits)
Сегодня я хочу рассказать о том, что такое фьюзы, за что они отвечают и как их можно прочитать и записать в Ардуино. Рекомендую также заглянуть в предыдущую публикацию, т.к. работа с фьюзами возможна только через программатор.
Фьюзы (от английского Fuse bits) — это конфигурационные биты микроконтроллера, отвечающие за его предварительную настройку. Эти биты расположены в отдельном адресном пространстве, доступном только при программировании. Биты объединяются в конфигурационные байты и их состав зависит от конкретной модели микроконтроллера.
При работе с конфигурационными битами нужно помнить один важный момент: если бит содержит логическую единицу, то это означает что он не запрограммирован, соответственно, запрограммированный конфигурационный бит содержит логический ноль. Такая логика основана на принципе хранения данных в EEPROM: чистая микросхема памяти содержит во всех ячейках единицы, а термин запрограммирована по отношению к такой ячейке означает, что в нее записали ноль.
Фьюзы ATmega328 / ATmega328p
Микроконтроллеры ATmega328 и ATmega328p, на базе которых построено большинство плат семейства Ардуино, имеют 3 байта конфигурации: младший, старший и дополнительный. Их описание приведено ниже в таблицах.
Младший конфигурационный байт ATmega328/P
| Номер бита | Навание | Описание | Значение по умолчанию |
|---|---|---|---|
| 7 | CKDIV8 | Divide clock by 8 | 0 (запрограммирован) |
| 6 | CKOUT | Clock output | 1 (не запрограммирован) |
| 5 | SUT1 | Select start-up time | 1 (не запрограммирован) |
| 4 | SUT0 | Select start-up time | 0 (запрограммирован) |
| 3 | CKSEL3 | Select Clock source | 0 (запрограммирован) |
| 2 | CKSEL2 | Select Clock source | 0 (запрограммирован) |
| 1 | CKSEL1 | Select Clock source | 1 (не запрограммирован) |
| 0 | CKSEL0 | Select Clock source | 0 (запрограммирован) |
Старший конфигурационный байт ATmega328/P
| Номер бита | Навание | Описание | Значение по умолчанию |
|---|---|---|---|
| 7 | RSTDISBL | External Reset Disable | 1 (не запрограммирован) |
| 6 | DWEN | debugWIRE Enable | 1 (не запрограммирован) |
| 5 | SPIEN | Enable Serial Program and Data Downloading | 0 (запрограммирован) |
| 4 | WDTON | Watchdog Timer Always On | 1 (не запрограммирован) |
| 3 | EESAVE | EEPROM memory is preserved through the Chip Erase | 1 (не запрограммирован) |
| 2 | BOOTSZ1 | Select Boot Size | 0 (запрограммирован) |
| 1 | BOOTSZ0 | Select Boot Size | 0 (запрограммирован) |
| 0 | BOOTRST | Select Reset Vector | 0 (запрограммирован) |
Дополнительный конфигурационный байт ATmega328/P
| Номер бита | Навание | Описание | Значение по умолчанию |
|---|---|---|---|
| 7 | — | — | 1 |
| 6 | — | — | 1 |
| 5 | — | — | 1 |
| 4 | — | — | 1 |
| 3 | — | — | 1 |
| 2 | BODLEVEL2 | Brown-out Detector trigger level | 1 (не запрограммирован) |
| 1 | BODLEVEL1 | Brown-out Detector trigger level | 1 (не запрограммирован) |
| 0 | BODLEVEL0 | Brown-out Detector trigger level | 1 (не запрограммирован) |
Таким образом, значения конфигурационных байтов в ATmega328/P по умолчанию: Low: 0x62, High: 0xD9, Extended: 0xFF. Обратите внимание, это значения именно для «чистого» микроконтроллера ATmega328/P , а не для Ардуино. Значения фьюзов для Ардуино можно найти в файле Arduino_dirhardwarearduinoavrBoards.txt, где Arduino_dir — это путь к IDE Arduino. Откройте файл в текстовом редакторе и найдите интересующую плату по названию, чуть ниже будет информация о фьюзах:
uno.name=Arduino/Genuino Uno
…
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
Для расшифровки шестнадцатеричных значений конфигурационных байтов удобно использовать онлайн калькулятор Engbedded Atmel AVR® Fuse Calculator:
Выберите модель микроконтроллера и введите значения фьюзов в соответствующие поля внизу страницы в разделе Current settings — введенные значения будут моментально расшифрованы и представлены в удобном виде. И, наоборот, можно изменить конфигурацию битов в разделах Manual fuse bits configuration и Feature configuration и получить значения конфигурационных байтов для записи в микроконтроллер.
Рассмотрим назначение конфигурационных битов более подробно.
CKDIV8
Данный бит отвечает за деление тактовой частоты на 8. Он определяет начальное значение регистра делителя частоты: если бит не запрограммирован, то регистр делителя будет сброшен в «0000»; если бит CKDIV8 запрограммирован, то в регистре будет установлено значение «0011», что обеспечит деление тактовой частоты на 8. Однако вне зависимости от значения фьюза CKDIV8 значение делителя может быть изменено программой в любой момент.
CKOUT
ATmega328/p позволяет выводить тактовую частоту на цифровой вывод CLKO (digital pin 8 на Ардуино Уно). Для этого конфигурационный бит CKOUT должен быть запрограммирован. Данная функция может быть полезна при использовании таковой частоты микроконтроллера внешними устройствами. При использовании делителя системной частоты на вывод CLKO также будет поступать пониженная частота.
SUT
Конфигурационные биты SUT совместно с битами CKSEL определяют длительность задержки при старте микроконтроллера. Задержка необходима для того, чтобы источник тактовой частоты стабилизировался после подачи питания и вошел в свой рабочий режим. Величина задержки зависит от выбранного источника и составляет от 0 до 65мс. Конкретные значения можно найти в даташите.
CKSEL
Современные микроконтроллеры способны работать с различными источниками тактового сигнала. Выбор источника осуществляется установкой конфигурационных битов CKSEL. В таблице ниже приведены источники тактового сигнала, поддерживаемые микроконтроллерами ATmega328 / ATmega328P, и соответствующие им значения CKSEL.
| Источник тактового сигнала | Значение CKSEL3..0 |
|---|---|
| Экономичный кварцевый генератор | 1111-1000 |
| Кварцевый генератор | 0111-0110 |
| Низкочастотный кварцевый генератор | 0101-0100 |
| Внутренний RC-генератор на 128кГц | 0011 |
| Внутренний калиброванный RC-генератор | 0010 |
| Внешний сигнал синхронизации | 0000 |
| Зарезервировано | 0001 |
RSTDISBL
Фьюз RSTDISBL управляет работой цифрового вывода микроконтроллера, совмещенного с входом внешнего сброса. Если RSTDISBL запрограммирован, то вывод может быть использован как обычный цифровой пин ввода/вывода. Если фьюз RSTDISBL не запрограммирован, то вывод используется для внешнего сигнала сброса: низкий уровень напряжения на нем приводит к генерации сигнала сброса микроконтроллера. Отключение внешнего сброса может быть оправдано при работе с микроконтроллерами, имеющими небольшое количество выводов, в других случаях лучше не трогать этот фьюз.
DWEN
Бит DWEN разрешает/запрещает работу отладочного интерфейса debugWire.
SPIEN
Данный бит разрешает/запрещает программирование по интерфейсу SPI. По умолчанию он запрограммирован и лучше не менять значение данного фьюза, как и значение RSTDISBL.
WDTON
Если запрограммировать конфигурационный бит WDTON, то сторожевой таймер начнет свою работу сразу после подачи питания на микроконтроллер. Работу таймера нельзя будет запретить программно и при его переполнении будет генерироваться сигнал сброса. Если данный фьюз не запрограммирован, то работой сторожевого таймера можно управлять программно, в том числе настроить его на генерацию прерывания, сигнала сброса или того и другого.
EESAVE
Данный бит определяет влияние команды «Стирание кристалла» на EEPROM-память: если бит запрограммирован, то при выполнении команды Chip Erase будут очищены Flash, SRAM и Lock-биты, а содержимое EEPROM затронуто не будет. В противном случае содержимое EEPROM также будет стерто.
BOOTSZ
Конфигурационные биты BOOTSZ определяют размер FLASH памяти микроконтроллера, резервируемой для загрузчика. Значения битов BOOTSZ и соответствующие им размеры указаны в таблице ниже. По умолчанию резервируется максимальный размер — 2048 слов.
| Начало секции загрузчика | Размер секции (слов) | Значение BOOTSZ1..0 |
|---|---|---|
| 0x3F00 | 256 | 11 |
| 0x3E00 | 512 | 10 |
| 0x3C00 | 1024 | 01 |
| 0x3800 | 2048 | 00 |
BOOTRST
Определяет положение вектора сброса. Если бит не запрограммирован, то вектор сброса располагается по адресу 0x0000, выполнение программы начнется именно с этого адреса. Если бит BOOTRST запрограммирован, то выполнение программы начнется с адреса начала секции загрузчика.
BODLEVEL
Конфигурационные биты BODLEVEL определяют порог срабатывания схемы BOD (Brown-Out Detection), которая отслеживает уровень напряжения источника питания. Если работа схемы BOD разрешена, то при снижении напряжения питания ниже установленного порога она переводит микроконтроллер в состояние сброса. Когда напряжение питания вновь увеличивается до порогового значения (данный порог чуть выше предыдущего за счет наличия гистерезиса), сигнал сброса снимается и происходит запуск микроконтроллера. Комбинации битов BODLEVEL и соответствующие им пороговые значения приведены в таблице:
| Порог срабатывания схемы BOD (В) | Значение BODLEVEL2..0 |
|---|---|
| Схема BOD выключена | 111 |
| Vcc = 1.8 | 110 |
| Vcc = 2.7 | 101 |
| Vcc = 4.3 | 100 |
Теперь можно понять начальное состояние микроконтроллеров ATmega328/P, в каком они поставляются с завода: микроконтроллер сконфигурирован на работу с внутренним RC генератором на 8МГц, при этом прошитый бит CKDIV8 обеспечивает деление частоты генератора на 8; внешний сброс (по низкому уровню на выводе Reset) не запрещен; разрешено программирование по интерфейсу SPI; для загрузчика отведена область памяти 2048 слов; стартовый адрес программы 0x0000; схема контроля питания отключена.
В Ардуино Уно фьюзы микроконтроллера изменены таким образом, чтобы он был настроен на работу с экономичным кварцевым генератором без делителя частоты; для загрузчика отводится 256 слов; прошитый бит BOOTRST назначает стартовым адресом адрес начала секции загрузчика; порог срабатывания схемы BOD составляет 2.7В.
Разобравшись с назначением фьюзов можно перейти от теории к практике: попробуем прочитать и записать фьюзы Ардуино.
Чтение фьюзов Ардуино
В предыдущей публикации я рассказал о том, как превратить Ардуино в ISP программатор. И сейчас он нам пригодится для работы с фьюзами. Поэтому готовим программатор и подключаем к нему плату, из которой будем считывать фьюзы.
В среде разработки Ардуино нет инструментов для чтения/записи фьюзов. Разве что процедура записи загрузчика включает в себя установку фьюзов, значения которых берутся из упомянутого ранее файла Boards.txt. Но в состав IDE входит программа Avrdude, предназначенная для прошивки AVR микроконтроллеров, ей-то мы и воспользуемся. Avrdude — консольная программа, работать мы с ней будем через командную строку, поэтому запускаем проводник и переходим в папку с программой. У меня IDE Arduino расположена на диске D и путь к Avrdude выглядит следующим образом: D:Arduinoarduino-1.6.12hardwaretoolsavrbin.
Находясь в этой папке нужно поместить курсор в адресную строку, удалить из нее путь, ввести cmd и нажать Enter. Откроется окно интерпретатора командной строки:
После этого подключаем программатор к компьютеру и вводим в командной строке следующую команду:
avrdude -C ../etc/avrdude.conf -c arduino -p m328p -P com26 -b 19200 -U lfuse:r:-:h
Перед выполнением команды проверьте и скорректируйте ее параметры:
- -c <programmer> — в качестве <programmer> указываем псевдоним используемого программатора, в нашем случае arduino.
- -p <partno> — указывает тип микроконтроллера, m328p — это ATmega328p.
- -P <port> — указывает используемый программатором порт.
- -b <baudrate> — позволяет переопределить указанную для программатора в конфигурации программы скорость подключения по интерфейсу RS-232.
- -U <memtype>:r|w|v:<filename>[:format] — комплексная опция для указания производимой с памятью операции (чтение. запись, проверка). -U lfuse:r:-:h означает, что мы хотим прочитать содержимое младшего байта конфигурации, считанное значение выводим на экран в шестнадцатеричном виде.
Ниже приведен мой результат выполнения данной команды:
Как видно из скриншота, младший конфигурационный байт моей Arduino Uno содержит значение 0xFF. Кроме запрошенного значения avrdude показал также значения всех трех конфигурационных байт. Это произошло потому, что мы не отключили safemode, это можно сделать, добавив в команду параметр -u. Остальные два конфигурационных байта также соответствуют значениям, приведенным в файле Boards.txt. Если у кого-то возникнут сомнения по поводу соответствия дополнительного конфигурационного байта, то загляните в его описание выше — биты с 3 по 7 не используются и содержат «1», поэтому вместо 0x05 мы считываем значение 0xFD.
Запись фьюзов Ардуино
Полагаю, из приведенного выше описания фьюзов должно быть понятно, что при работе с ними нужно быть очень осторожным. В противном случае вы рискуете «залочить» микроконтроллер, т.е. привести в такое состояние, когда его уже нельзя будет перепрограммировать (без дополнительного оборудования). Поэтому будьте внимательны, изменяя фьюзы микроконтроллера.
Давайте в качестве примера попробуем запретить работу схемы BOD в Ардуино Уно. Обратившись к приведенному выше описанию конфигурационных байтов или к онлайн калькулятору Engbedded Atmel AVR® Fuse Calculator, мы видим, что за работу схемы BOD в ATmega328/P отвечают фьюзы BODLEVEL и для ее запрета нужно записать в дополнительный конфигурационный байт значение 0xFF. Это можно сделать следующей командой avrdude:
avrdude -C ../etc/avrdude.conf -c arduino -p m328p -P com26 -b 19200 -U efuse:w:0xFF:m
Из скриншота видно, что avrdude сначала выполняет запись байта efuse, после чего производит контрольное считывание и сообщает об успешном выполнении операции.
В принципе нет ничего сложного в работе с конфигурационными битами. Главное быть внимательным при их изменении, чтобы не залочить микроконтроллер.
C:avrdudeprog33>avrdude.exe -p m328p -c usbasp -P usb -U lfuse:w:0x62:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m
avrdude.exe: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude.exe: Device signature = 0x1e950f
avrdude.exe: reading input file «0x62»
avrdude.exe: writing lfuse (1 bytes):
Writing | ################################################## | 100% 0.02s
avrdude.exe: 1 bytes of lfuse written
avrdude.exe: verifying lfuse memory against 0x62:
avrdude.exe: load data lfuse data from input file 0x62:
avrdude.exe: input file 0x62 contains 1 bytes
avrdude.exe: reading on-chip lfuse data:
Reading | ################################################## | 100% -0.00s
avrdude.exe: verifying …
avrdude.exe: 1 bytes of lfuse verified
avrdude.exe: reading input file «0xD9»
avrdude.exe: writing hfuse (1 bytes):
Writing | ################################################## | 100% 0.02s
avrdude.exe: 1 bytes of hfuse written
avrdude.exe: verifying hfuse memory against 0xD9:
avrdude.exe: load data hfuse data from input file 0xD9:
avrdude.exe: input file 0xD9 contains 1 bytes
avrdude.exe: reading on-chip hfuse data:
Reading | ################################################## | 100% -0.00s
avrdude.exe: verifying …
avrdude.exe: 1 bytes of hfuse verified
avrdude.exe: reading input file «0xFF»
avrdude.exe: writing efuse (1 bytes):
Writing | | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.08s
avrdude.exe: 1 bytes of efuse written
avrdude.exe: verifying efuse memory against 0xFF:
avrdude.exe: load data efuse data from input file 0xFF:
avrdude.exe: input file 0xFF contains 1 bytes
avrdude.exe: reading on-chip efuse data:
Reading | ################################################## | 100% 0.02s
avrdude.exe: verifying …
avrdude.exe: verification error, first mismatch at byte 0x0000
0x07 != 0xff
avrdude.exe: verification error; content mismatch
avrdude.exe: safemode: efuse changed! Was ff, and is now 7
Would you like this fuse to be changed back? [y/n] y
и собственно все зависло, сигнатура теперь 000000… в общем убил свой последний живой 328, но собственно вопрос — почему? пытался прошить дефолтные фьюзы, но она в efuse почему-то записала 07 вместо ff, или я чет не понимаю?
если кварц отрубить то сигнатура меняется каждый раз
Очень редко программирование микроконтроллеров AVR обходится без настройки фьюзов.
Однако ошибки при настройке фьюзов могут погубить контроллер, и восстановление его станет возможным только с помощью специальных знаний, а иногда и специального оборудования. Поэтому, желательно понять назначение всех фьюзов и настраивать их правильно.
Вкладка настройки фьюзов в AVRDude выглядит следующим образом:
Для ATMega328:
Для ATMega8:
Как можно заметить, фьюзы для разных контроллеров имеют ряд различия. Отличается и их настройка, однако среди них очень много общего, а порядок настройки фьюзов определяется даташитом на каждый микроконтроллер.
В статье мы изучим назначение фьюзов, а так же особенности определения порядка настройки фьюзов, на примере даташита для ATMega8.
Все биты могут настраиваться как в прямом так и в инверсном виде. Выбор осуществляется в области Fuses.
По умолчанию, биты всегда настраиваются в инверсном виде, однако в даташит они описываются в прямом виде, поэтому решайте сами, как удобнее Вам, но если Вы настраиваете биты в инверсном виде:
— в даташите написано 0, тогда ставим голочку, если 1, тогда не ставим галочку;
для прямого вида:
— в даташите написано 1, тогда ставим голочку, если 0, тогда не ставим галочку.
Теперь непосредственно к фьюзам.
CKSEL
Пожалуй, самые опасные фьюзы, и при этом, очень важные.
Неправильная настройка фьюзов CKSEL приведет к сложностям его дальнейшего использования. Он может перестать определяться программатором, и работать не будет.
Именно поэтому, будьте внимательны, и не настраивайте этот фьюз, если не уверены в том, что делаете это правильно.
НАЗНАЧЕНИЕ фьюза CKSEL — настройка частоты и источника тактирования контроллера.
Если вы настроите тактирование от кварцевого резонатора, а резонатор не подключите, контроллер перестанет определяться, пока кварц не будет подключен в соответствие с требуемой схемой.
Настройка фьюзов CKSEL определяется по даташиту. Для этого, в даташит следует изучить раздел SYSTEM CLOCK AND CLOCK OPTIONS.
Рассмотрим последовательность действий, для настройки тактирования контроллера ATMega8 от встроенного тактового генератора на частоте 4 МГц:
Первая табличка, на которую в даташите следует обратить внимание:
Здесь для нашей настройки следует обратить внимание на строку Calibrated Internal RC Oscillator — работа от встроенного RC генератора. При этом фьюзы CKSEL3… CKSEL0 будут определены в промежутке 0100 — 0001. Пока из этого можно сделать однозначный вывод, что фьюз CKSEL точно равен 0 (для инверсного режима, напротив него следует поставить галочку, для прямого — нет).
Следуем далее к подразделу Calibrated Internal RC Oscillator в данном разделе можно определить какие фьюзы как следует настроить для работы контроллера на частоте 4 МГц от встроенного генератора. Смотрим таблицу из даташит:
По таблице видно, что для работы на частоте 4 МГц от встроенного генератора фьюзы следующие: CKSEL3 — 0; CKSEL2 — 0; CKSEL1 — 1; CKSEL0 — 1.
А окно AVRDude с инверсной настройкой фьюзов выглядит для работы контроллера ATMega8 от встроенного осциллятора, так:
Это настройки именно для ATMEGA8!!! Для другого контроллера смотрите Даташит.
Ну и для разнообразия, рассмотрим настройку тактирования от ВНЕШНЕГО кварцевого генератора контроллера ATMEGA328 на частоте 8 МГц.
Открываем даташит на контроллер ATMEGA328 и переходим в раздел System Clock and Clock Options.
Сперва обращаем внимание на схему подключения кварцевого резонатора
Далее смотрим таблицу настройки фьюзов CKSEL3-CKSEL1. Здесь же отмечены емкости необходимых для схемы конденсаторов
В нашем случае для фьюзов CKSEL3…CKSEL1 в инверсном режиме настройки галочки не ставим (последняя строка для 8 МГц.)
Ну и так же настраиваем фьюзы CKSEL0 и SUT0 — SUT1 по таблице из даташита, приведенной ниже:
Здесь кратенько поясню. По данной таблице настраивается время, через которое контроллер перейдет в рабочий режим, а питание установится на должном уровне. 2 столбец показывает, что до перехода в рабочий режим контроллер будет ждать 16 тактов. Третий столбик, говорит, что контроллер подождет ещё 14 тактов и 65 миллисекунд (по последней строке). Что это значит? Что контроллер не начнет выполнять работы программы, пока не пройдет какое-то количество тактов, которое необходимо, для стабилизации питающего напряжения. Я думаю, что его стоит ставить по максимуму. Это обеспечит максимально стабильный старт контроллера. Таким образом, напротив фьюзов CKSEL0, SUT1, SUT2 галочки не ставим (для инверсного режима, для прямого ставим галочки!!!).











































