Монк - Программируем Arduino. Профессиональная работа со скетчами.
- Название:Программируем Arduino. Профессиональная работа со скетчами.
- Автор:
- Жанр:
- Издательство:Издательский дом Питер
- Год:2017
- Город:СПб.
- ISBN:978-5-496-02385-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Монк - Программируем Arduino. Профессиональная работа со скетчами. краткое содержание
Простые проекты на основе Arduino не вызывают сложностей в реализации. Но, вступив на территорию, не охваченную вводными руководствами, и увеличивая сложность проектов, вы быстро столкнетесь с проблемой нехватки знаний — врагом всех программистов.
Эта книга задумана как продолжение бестселлера «Programming Arduino: Getting Started with Sketches». Несмотря на то что эта книга включает краткое повторение основ из книги «Programming Arduino», она познакомит читателя с более продвинутыми аспектами программирования плат Arduino.
Программируем Arduino. Профессиональная работа со скетчами. - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Тип uint_8 намного точнее определяет диапазон допустимых значений, потому что вообще в языке C тип int может представлять значения с разрядностью от 16 до 64 битов в зависимости от конкретной реализации C. Имя типа uint_8 читается так: символ u говорит, что это беззнаковый (unsigned) тип, int сообщает, что это целочисленный тип, и, наконец, число после символа подчеркивания (_) сообщает количество битов. То есть тип uint_8 представляет 8-битные целые числа без знака в диапазоне между 0 и 255.
Вы свободно можете использовать в своих скетчах эти более строгие типы, что некоторые и делают. Но помните, что это сделает ваш код чуть труднее для понимания теми, кто не искушен в программировании для Arduino.
Возможность использования обычного типа int, представляющего 16-битные целые числа со знаком, вместо типа unit_8, например, объясняется способностью компилятора автоматически выполнять необходимые преобразования. Использование переменных типа int для хранения номеров контактов приводит к напрасному расходованию памяти. Поэтому вам придется искать компромисс между объемом памяти для хранения данных и удобочитаемостью кода. Как правило, в программировании предпочтение отдается простоте чтения кода, если только вы не собираетесь создать нечто очень сложное, способное превысить ограничения микроконтроллера.
Здесь можно провести аналогию с грузовиком, который вы собираетесь использовать для доставки чего-то кому-то. Если требуется перевезти большой объем груза, вам придется подумать, как упаковать и расположить его, чтобы он уместился весь. Если груз занимает лишь малую часть площади кузова, нет смысла тратить много времени на его упаковку и размещение.
Также в папке arduino можно найти файл main.cpp. Открыв его, вы увидите кое-что интересное.
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
Если прежде вам доводилось программировать на языке C, C++ или Java, вы должны быть знакомы с идеей функции main. Эта функция автоматически вызывается в момент запуска программы. Функция main — это главная точка входа в программу. Это утверждение справедливо и для программ Arduino, только скрыто от глаз разработчиков скетчей, которые обязаны реализовать в своих скетчах две функции — setup и loop.
Если вчитаться в файл main.cpp, пропустив пока первые несколько строк, можно заметить, что функция main вызывает setup() и затем входит в бесконечный цикл for, где вызывает функцию loop.
Команда for(;;) — это, пусть и малопонятный, способ записи while (true). Обратите внимание на то, что кроме вызова функции loop внутри цикла for имеется также команда if, которая проверяет поступление сообщений в последовательный порт и обслуживает их.
Вернувшись в начало файла main.cpp, можно увидеть, что в первой строке находится команда include, подключающая все определения из заголовочного файла arduino.h, о котором я говорил прежде.
Далее находится определение функции main, которая начинается с вызова функции init(). Если поискать, ее можно найти в файле wiring.c, она вызывает функцию sei, разрешающую прерывания.
Строки
#if defined(USBCON)
USBDevice.attach();
#endif
являются еще одной директивой препроцессора C. Данный код действует подобно команде if, которую вы можете использовать в своих скетчах, но выполняется она не тогда, когда скетч уже работает в Arduino. Проверка условия в директиве #if происходит во время компиляции скетча. Данная директива дает отличную возможность включать и выключать фрагменты кода в зависимости от конкретного типа платы. В данном случае, если Arduino поддерживает интерфейс USB, в программу включается код, подключающий (инициализирующий) его, в противном случае нет никакого смысла компилировать его.
Из скетча в Arduino
Теперь, когда вы узнали, откуда берется весь этот магический код, когда пишется даже самый простой скетч для Arduino, можно посмотреть, как этот код попадает во флеш-память микроконтроллера на плате Arduino, когда вы щелкаете на кнопке Upload (Загрузить) в Arduino IDE.
На рис. 2.4 показано, что происходит после щелчка на кнопке Upload (Загрузить).
Рис. 2.4.Комплект инструментов Arduino
Скетчи для Arduino хранятся в виде текстовых файлов с расширением .ino в папке с тем же именем, но без расширения.
Когда пользователь пытается выгрузить скетч в плату, в дело включается среда разработки Arduino IDE, которая управляет множеством вспомогательных программ, выполняющих основную работу. Сначала компонент Arduino IDE, который я (за неимением лучшего названия) называю препроцессором ( Arduino IDE preprocessor ), собирает файлы, составляющие скетч. Обратите внимание на то, что обычно скетч состоит из единственного файла. При желании в папку скетча можно добавить другие файлы, правда, при этом для их создания придется использовать другой редактор.
Если в папке присутствуют другие файлы, они также будут включены в процесс сборки. Файлы с программным кодом на языках C и C++ компилируются отдельно друг от друга. В начало главного файла скетча добавляется строка, подключающая arduino.h.
Так как существует множество разных моделей плат Arduino, использующих разные микроконтроллеры с разными наименованиями контактов, Arduino IDE должна выбрать правильные их определения. Если заглянуть в папку hard-ware/arduino/variants, можно увидеть отдельные папки для всех моделей плат Arduino, в каждой из которых хранится свой файл pins_arduino.h. Этот файл содержит имена контактов для своей платформы.
После объединения файлов вызывается компилятор GCC. Это компилятор C++, распространяемый с открытым исходным кодом и входящий в состав дистрибутива Arduino. Он принимает скетч, заголовочный файл и файлы реализации с исходным кодом на C и преобразует их в код, который может выполняться микроконтроллером на плате Arduino. Этот компилятор выполняет следующие шаги.
1. Препроцессор интерпретирует все команды #if и #define и определяет, какой код должен быть скомпилирован.
2. Затем выполняются компиляция и компоновка кода в единственный файл, пригодный для выполнения процессором на плате.
3. Когда компилятор завершит свою работу, запускается открытый программный компонент с названием avrdude, который пересылает в плату выполняемый двоичный код в шестнадцатеричном формате через последовательный интерфейс USB.
Теперь мы в царстве Arduino. В плате Arduino имеется небольшая резидентная программа, устанавливаемая в каждый микроконтроллер. Эта программа называется загрузчиком (bootloader). Загрузчик выполняется каждый раз, когда происходит сброс платы Arduino. Именно поэтому, когда происходит передача данных по последовательному интерфейсу, аппаратура связи в Arduino Uno производит принудительный сброс платы, чтобы дать загрузчику возможность проверить входящие скетчи.
Читать дальшеИнтервал:
Закладка: