• - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!
подписаться на RSS-ленту

Arduino/CraftDuino и WinAVR - программируем на чистом С

Здесь упоминалось, что Arduino/CraftDuino/Freeduino можно программировать не только на Wiring-е, но и на других языках программирования.
Попробуем разобраться как это можно сделать — написать программу на обычном С/C++.
Для этого воспользуемся компилятором WinAVR.
WinAVR — это интегрированная среда разработки; она включает мощные компиляторы Си и ассемблера, программатор AVRDUDE, отладчик, симулятор и множество других вспомогательных программ и утилит.

Скачать WinAVR можно на странице проекта:
http://sourceforge.net/projects/winavr/
однако, в комплекте Arduino IDE уже идёт WinAVR (\hardware\tools\avr\), поэтому можно воспользоваться им.

Для работы с исходными текстами подойдёт компонент WinAVR – Programmers Notepad (\hardware\tools\avr\pn\pn.exe) — удобный редактор программиста и интегрированная среда разработки (IDE):


Для более подробного знакомства со средой разработки WinAVR рекомендую статьи
Среда разработки WinAVR.
Makefile и компиляция программы.

Возьмём пример из второй статьи и адаптируем его для Arduino:

Создаём файл avrblink.c

/************************************************

ПРИМЕР МИГАНИЯ СВЕТОДИОДАМИ :: MYROBOT.RU
, адаптированный RoboCraft.ru для Arduino
*************************************************/ 


   #include <avr/io.h>
   #include <avr/delay.h>
   #define F_CPU 16000000UL    // 16 MHz
   
   int main(void)              // начало основой программы
   {
   
	DDRD = 0xff;   // все выводы порта D сконфигурировать как выходы

        while (1) {                     // Бесконечный цикл

			PORTD = 0xff;   // установить "1" на всех линиях порта D

			_delay_ms(1000);// Ждем 1 сек.

			PORTD = 0x00;   // установить "0" на всех линиях порта D

			_delay_ms(1000);// Ждем 1 сек.

		}    
   } 


— адаптировали, изменив частоту на 16МГц и время задержки ;) Однако, как видно в исходнике – сейчас МК мигает всем портом D! Т.е., если посмотреть Arduino Pin Mapping – цифровыми выходами, начиная с digital pin 0 и заканчивая digital pin 7.

В WinAVR исходный текст программы компилируется при помощи утилиты make.exe, которая находится в папке WinAVR\utils\bin. Make.exe контролирует генерацию исполняемых файлов из исходного кода программы. Для управления работой этой утилиты используют make-файлы. Make-файл сообщает компилятору, какие команды запускать, какие файлы компилировать и линковать, какой выходной код генерировать и т. д.


Копируем в директорию с нашим .c-файлом Makefile–образец (\hardware\tools\avr\sample\ Makefile)
и вносим требуемые изменения:

указываем тип микроконтроллера
# MCU name
MCU = atmega8
Либо atmega168


Далее указываем частоту
F_CPU = 16000000


название нашего проекта
# Target file name (without extension).
TARGET = avrblink


Уровень оптимизации s – можно заменить на 0, чтобы отключить оптимизацию
# Optimization level, can be [0, 1, 2, 3, s]. 
#     0 = turn off optimization. s = optimize for size.
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s


Тип и порт программатора
AVRDUDE_PROGRAMMER = stk500v2

# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1    # programmer connected to serial device


Сохраняем изменения и пробуем скомпилировать (Tools – Make All)

Но, получаем сообщение об ошибке, т.к. Programmers Notepad не знает где искать компилятор и утилиту make.exe

Прописываем пути к нужным директориям:
c:\utils\arduino-0016\hardware\tools\avr\utils\bin\
c:\utils\arduino-0016\hardware\tools\avr\bin\
c:\utils\arduino-0016\hardware\tools\avr\avr\bin\
в переменную среды PATH, перезагружаемся и пробуем снова
В ОС Windows это делается через Мой Компьютер — Свойства — Дополнительно — Переменные среды. Выбираете PATH, щёлкаете изменить и через точку с запятой добавляете нужные пути.


Получилось!
А в директории рядом с нашим avrblink.c и Makefile появилось много интересного:
— .dep/avrblink.o.d
— avrblink.eep
— avrblink.elf
— avrblink.hex
— avrblink.lss
— avrblink.lst
— avrblink.map
— avrblink.o
— avrblink.sym

Самый важный из этих файлов — это avrblink.hex. В нем хранится шестнадцатиричный код для загрузки в память программ (Flash ROM) микроконтроллера.

:1000000012C02CC02BC02AC029C028C027C026C0BF
:1000100025C024C023C022C021C020C01FC01EC0D4
:100020001DC01CC01BC011241FBECFE5D4E0DEBF25
:10003000CDBF10E0A0E6B0E0EEE8F0E002C0059031
:100040000D92A036B107D9F710E0A0E6B0E001C0EC
:100050001D92A036B107E1F702D017C0D1CF8FEFC4
:1000600081BB4FEF20E931E042BB80E197E2F9012B
:100070003197F1F70197D9F712BA80E197E2F901C8
:0E0080003197F1F70197D9F7EFCFF894FFCF42
:00000001FF


А avrblink.eep — хранит шестнадцатиричный код для загрузки в энергонезависимую память данных (EEPROM).

Попробуем загрузить наш .hex в наш proteus-кий простейший симулятор ардуины

Мигает :)
Однако, нужно привести нашу программу ближе к стандартному Blink-у и помигать одним встроенным светодиодом на digital pin13. Как видим по схеме или по Arduino Pin Mapping – это пятая линия порта B.

Читаем крайне познавательную статью
AVR GCC :: Управление портами микроконтроллера AVR.
и вносим нужные изменения в нашу программу:

/************************************************

ПРИМЕР МИГАНИЯ СВЕТОДИОДОМ от MYROBOT.RU, адаптированный RoboCraft.ru для Arduino

данный пример повторяет стандартный скетч Blink

*************************************************/ 


   #include <avr/io.h>
   #include <avr/delay.h>
   #define F_CPU 16000000UL  // 16 MHz
   
   int main(void)            // начало основой программы
   {
   
		DDRB = 0x20; // 0b00100000 конфигурируем 5-ю линию порта B, как выход - остальные - вход

        while (1) {          // Бесконечный цикл

			PORTB |= _BV(PC5);  // установить "1" на линии 5 порта B (digital pin 13)

			_delay_ms(1000);    // Ждем 1 сек.

			PORTB &= ~_BV(PC5); // установить "0" на линии 5 порта B

			_delay_ms(1000);    // Ждем 1 сек.

		}    

   }


Компилируем, загружаем в протеус – работает!
Сравним размеры файлов :)
Ардуиновский Blink.hex весит 2031 байт
Наш hex при оптимизации по размеру (OPT = s) по размеру весит 410 байт
а с отключённой оптимизацией (OPT = 0) все 3184 байта!


Теперь осталось разобраться как же в реальности прошить наш .hex в ардуину :)
Например, можно воспользоваться каким-нибудь программатором :)
Однако, у нас ведь есть загрузчик и поэтому можем просто воспользоваться родным приёмом ардуины – самопрограммированием МК.
В любом случае, нам понадобится воспользоваться утилитой AVRDUDE, которая идёт в составе WinAVR и находится внутри Arduino IDE (\hardware\tools\avr\)

AVRDUDE позволяет загружать программы и данные в память микроконтроллера, а также считывать их оттуда. AVRDUDE использует SPI-интерфейс. Существуют версии для Windows и Linux. Первоначальный код был написан Брайеном Дином (Brian S. Dean) и имел название avrprog.


При использвании ардуиновского «параллельного программатора» или популярных для LPT – пяти проводков – нужная дополнительная настройка:
В Windows 2000 и Windows XP запрещена прямая работа с параллельным (LPT) портом, поэтому для нормальной работы AVRDUDE необходимо установить драйвер giveio.sys. Для установки этого драйвера зайдите в папку WinAVR\bin и запустите файл install_giveio.bat (удалить драйвер из системы можно, запустив файл remove_giveio.bat).
В Windows 98 никаких специальных настроек не требуется.


AVRDUDE — консольная программа и для её работы ей нужно передавать кучу параметров, но для упрощения задачи, уже есть готовая программа — ArduinoUpload, которая написана на C# и которая как раз и делает – то что нам нужно — загружает в ардуину .hex-файл через утилиту avrdude.

остаётся выбрать наш .hex-файл, COM-порт к которому подключена ардуина и указать путь до avrdude (\hardware\tools\avr\bin\avrdude.exe)

Как видим, всё что делает программа — это формирует команду вида:
avrdude -F -v -pm168 -cstk500v1 -P\\.\COM4 -b19200 -D -Uflash:w:"file.hex":i


разберёмся, что значат все эти параметры:

-F: Игнорировать проверку соединения с МК. Разумеется, такая проверка желательна – поэтому использование этого флага стоит избегать.

-v: так называемый «многословный» (verbose) вывод – полезно для контроля и отладки.

-p : Указываем тип МК для программирования. Например, если бы был ATtiny2313, здесь нужно было бы написать: attiny2313. Мы же указываем нашу атмегу :)
m8 ATmega8
m16 ATmega16
m32 ATmega32

-c : Указываем тип программатора. Если используется STK500 — пишем stk500 и т.д.

-P : указывается коммуникационный порт, к которому подключён программатор. Это может быть COM1 или LPT1 или даже USB.

-b : Указывается скорость для работы с последовательным портом – нужно для программаторов, работающих через COM-порт – таких как STK500.

-D: Отключаем очистку МК перед прошивкой.

-U :r|w|v:[:format]: Самая важная команда – выполнение прошивки.
— тип памяти МК — flash или eeprom (или hfuse, lfuse, efuse для конфигурации фьюзов МК).
r|w|v – флаги определяют, что мы хотим сделать:
r (read — считать)
w (write — записать)
v (verify — проверить).
файл для записи или чтения.
[:format] флаг формата данных. Здесь всегда используется формат «Intel Hex», поэтому стоит i
Таким образом, командой -Uflash:w:«file.hex»:I – мы записываем файл file.hex в FLASH-память МК. Если нам потребуется считать eeprom-память в файл «eedump.hex» – мы напишем -Ueeprom:r:eedump.hex:i

Дополнительные параметры AVRDUDE:

-C <config-file>: указываем путь до конфигурационного файла avrdude
-e: очистка МК
-n: ничего не записывать в МК. Защита, чтобы не отправить в МК ничего лишнего :)
-u: указывает, что хотим модифицировать фьюзы МК.
-t: терминальный режим
-q: в противоположность -v – это «тихий» режим – меньше слов – больше дела :)

список параметров с их кратким описанием можно получить просто запустив avrdude без параметров или с параметром -?
А более подробную документацию можно найти здесь(\hardware\tools\avr\doc\avrdude\avrdude.pdf).

Ну что же – пробуем прошить. Жму Reset на плате и сразу кнопку “Program”

Ошибка!

AVRDUDE пишет, что не находит своего конфигурационного файла :(
Хм… попробуем ему помочь – дописываем в конец строчку:

-C"c:\utils\arduino-0016\hardware\tools\avr\etc\avrdude.conf"



И снова перезагружаю плату и жму “Program”.

Ура! Получилось! Пойду допишу об этом нюансе на сайт ардуины ;)

Вот так – научились загружать в ардуину другие программы, которые можно писать хоть на ассемблере! :)

А так же теперь становится понятно, насколько Arduino IDE упрощает процесс программирования микроконтроллеров! :)

Приложение:

Скетч WinAVR-кого Blink-а, перенесённый в Arduino IDE
#include <avr/io.h>
#include <avr/delay.h>

void setup()
{
  DDRB = 0x20; // 0b00100000 конфигурируем 5-ю линию порта B, как выход - остальные - вход
}

void loop()
{
PORTB |= _BV(PC5);  // установить "1" на линии 5 порта B (digital pin 13)
_delay_ms(1000);    // Ждем 1 сек.
PORTB &= ~_BV(PC5); // установить "0" на линии 5 порта B
_delay_ms(1000);    // Ждем 1 сек.
}


Ссылки:
http://sourceforge.net/projects/winavr/
СРЕДА РАЗРАБОТКИ WinAVR
MAKEFILE И КОМПИЛЯЦИЯ ПРОГРАММЫ
ПРОСТОЙ ПРОГРАММАТОР AVR :: AVRDUDE
http://www.arduino.cc/playground/Code/ArduinoUpload (архив с программой, исходники)
AVR Tutorial — Starting out with avrdude
  • +2
  • 28 ноября 2009, 14:10
  • admin

Комментарии (3)

RSS свернуть / развернуть
+
0
> Получилось!
У меня ничего не получилось. arduino IDE 18 версии. 17 ошибок в том числе синтаксные. ЧЯДНТ?
avatar

AlexMelyon

  • 11 августа 2010, 03:54
+
0
Причем в makefile
avatar

AlexMelyon

  • 11 августа 2010, 03:54
+
+1
Возможно у Вас WinAVR установлен в директорию, содержащую в своем имени пробелы или скобки
avatar

Lestat

  • 20 августа 2010, 20:54

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.