Ранее производил прошивку МК средствами Arduino IDE, на эту тему есть отдельная статья Прошивка ATmega через USBasp и Arduino IDE. Время идет, пора переходить на более тонкие инструменты, в частности C и avrdude. Программируем, собираем, прошиваем.
Задача
Тестовую программу мигания светодиодом на C, скомпилировать в файл прошивки и загрузить результат в МК ATmega 328 P.
Решение
Разработку, прошивку и дальнейшее описание буду вести на Debian 9, но все необходимые компоненты есть и под Windows.
Подготовка окружения
Первым делом подготовим окружение, как писал выше: разработка на C, компиляция прошивки средствами avr-gcc, загрузка прошивки средствами avrdude, через программатор USBasp.
Для установки необходимого собрал следующий набор:
# apt-get install avr-libc gcc-avr binutils-avr avrdude
В Debian драйвера для USBasp устанавливать не надо, они есть в составе ядра. Для Windows необходимо скачать и установить драйвер с сайта разработчика fischl.de.
Подключение оборудования
На данном этапе не должно вызвать вопросов, но для порядка опишу подключение. Подключаем микроконтроллер к программатору USBasp: выводы SCK, MISO, MOSI, RESET, VCC. Так же не забываем к выходу D0 через резистор 220 Ом подключить анод светодиода, катод к GND.
Написание кода
На данный момент нет разницы в чем будет написан код, для себя выбрал Atom. Создаем файл с расширением .c, например main.c, в котором напишем код мигания светодиодом:
#define F_CPU 16000000UL // Частота работы МК от внешнего кварца #include <avr/io.h> #include <util/delay.h> void main() { DDRD = 0xFF; // Все выводы порта D как выход PORTD = 0x00; // На всех выводах установим 0 while (1) { PORTD |= (1 << PD0); // Включаем светодиод _delay_ms(1000); // Ждем 1 секунду PORTD &= ~(1 << PD0); // Выключаем светодиод _delay_ms(1000); // Ждем 1 секунду } }
Первой строкой явно указываю частоту с которой должен работать МК, т.к. у меня подключен внешний кварцевый резонатор на 16 МГц. Остальное ясно из комментариев.
Компиляция кода
Для компиляции будем пользоваться двумя командами(полного описания команд и их ключей приводить не буду, ибо каждая из них повод для отдельных статей и они легко находятся в интернете):
avr-gcc — производит компиляцию C в объектный файл.
К данной команде используем ключи:
- -mmcu для указания типа МК, в данном случае ATmega 328P;
- -DF_CPU для указания частоты с которой работает МК.
avr-gcc -g -Os -mmcu=atmega328p -DF_CPU=16000000UL main.c -o main.o
После выполнения команды в каталоге появится файл main.o
avr-objcopy — производит преобразование объектного файла в hex.
avr-objcopy -O ihex main.o main.hex
После выполнения команды в каталоге появится файл main.hex. Файл прошивки готов, необходимо загрузить его на МК.
Ссылки ни на какие статьи не привожу, т.к. просмотренные не содержат полного описания, только отрывочные сведения.
Загрузка прошивки в МК
!!! Внимание Настоятельно рекомендую перед выполнением команды avrdude ознакомиться с описанием ключей и все операции производить только после проверки написанного, во избежание окиричивания МК. Все дальнейшие расчеты на свой страх и риск!
Воспользуемся утилитой avrdude, к данной команде используем ключи:
- -c для указания программатора, в данном случае USBasp;
- -p для указания типа МК, в данном случае ATmega 328P;
- -U ключ для указания с каким типом памяти мы работаем, что именно делаем, и указываем файл источник/приемник. В данном случает производится запись во flas-память МК из файла main.hex.
Мне понравилось описание ключей и примеров на сайте ph0en1x.net.
avrdude -c usbasp -p atmega328p -U flash:w:main.hex
После выполнения команды МК оживает и начинает выполнять заложенные в код алгоритмы.
Изменение FUSE-битов
!!! Внимание Настоятельно рекомендую перед выполнением команды avrdude ознакомиться с описанием ключей и все операции производить только после проверки написанного, во избежание окиричивания МК. Все дальнейшие расчеты на свой страх и риск!
Но не все так гладко. В коде между включением и выключением указана задержка в 1 секунду, а на практике светодиод горит более 10 секунд. Вооружился секундомером, замер показал 16 секунд. Получается МК работает на частоте 1 МГц, вместо 16 МГц.
Чтение документации показало, что необходимо МК указать на какой частоте он должен работать при подключении внешнего кварцевого резонатора. Для ATmega 328P указывается 3 байтами: lock, lfuse, hfuse.
Для расчета значений этих байтов есть калькуляторы фьюзов, обязательно необходимо проверить получившиеся значения с документацией! Для себя собрал следующую команду:
avrdude -c usbasp -p atmega328p -U lock:w:0xFF:m -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m
После выполнения команды МК начал работать на положенной ему частоте.
здравствуйте. можете показать пример как писать в еепром. смысл в том что у меня код постоянно работает с еепром, но при прошивке либо весь стирается. либо не пишется туда ги чего. я думаю что стирается. мне надо чтоб не стирался при перепрошивке. можите мне помоч?
Тарас, с данным вопросом еще не готовился. При первой возможности постараюсь изучить
Спасибо большое за урок, но хотел бы узнать, я вроде бы все сделал как надо но почему то со временем дилея беда, я поставил 100 вместо 1000 и то явно не секунда а больше, в чем может быть проблема ?
Владимир, рад что пригодилось!
У меня с первого раза тоже получилось 16 секунд вместо 1. Причина была в FUSE-битах, по умолчанию высталена частота 1 Мгц. Об этом описано в последнем разделе статьи, проверьте значение FUSE-битов
Спасибо большое, помогло, но потом я захотел перепрошить контролер, даже новый купил, выдает avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: error: program enable: target doesn’t answer. 1
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.
avrdude done. Thank you.
Не подскажете, что может помочь решить эту проблему ?