Зачем нужны функции begin() для инициализации оборудования (если они есть)?
Я пишу программу для микроконтроллера ATmega, используя платформу Arduino.
При реализации класса, связанного с оборудованием (один для управления светодиодами), я поместил в конструктор класса некоторый код инициализации оборудования, такой как pinMode(OUTPUT)
. Затем я понял, что во всех известных мне библиотеках Arduino аппаратная инициализация выполняется в begin()
или init()
, поэтому я также создал один для своего класса Led и переместил туда pinMode()
.
Теперь мне интересно, действительно ли я должен определять такие функции инициализации, т.е. зачем они нужны, а если нет, то почему они есть во многих библиотеках. Я немного поигрался и обнаружил, что, например, этот код работает на ATmega1284 (загорается светодиод на контакте 28).
struct Test {
Test() {
pinMode(28, OUTPUT);
digitalWrite(28, HIGH);
// другие вещи
}
// ...
};
Test test;
void setup() {
}
void loop() {
}
Я предполагаю, что этот код какой-то непродуманный, не говоря уже о том, что он зажигает светодиод без какого-либо кода в основной функции (или, может быть, именно в этом проблема?), но если это так, я не понимаю, почему . Что я не учел?
Должен ли приведенный выше код быть написанным, как в следующем фрагменте, как мне кажется существование всех этих функций begin()
?
struct Test {
Test() {
// другие вещи
}
void begin() {
pinMode(28, OUTPUT);
digitalWrite(28, HIGH);
}
// ...
};
Test test;
void setup() {
test.begin();
}
void loop() {
}
@noearchimede, 👍0
Обсуждение1 ответ
Лучший ответ:
Все дело в порядке выполнения.
Конструкторы выполняются перед обычными функциями. Это включает в себя функцию main()
, которая в конечном итоге вызывает setup()
и (неоднократно) loop()
. Еще одна вещь, которую делает main()
, — это вызов init()
(или его вариант), который настраивает аппаратное обеспечение.
Поскольку это происходит после запуска любых глобальных конструкторов, все, что конструктор сделал с оборудованием, потенциально может быть отменено.
Таким образом, нормально откладывать любую настройку оборудования до тех пор, пока после main()
не выполнит настройку, и по соглашению используется begin()
для этого.
Спасибо за ответ! И что на самом деле представляет собой эта функция init()
? Где это определено? И, кстати, где функция main()
в проекте Arduino?, @noearchimede
Это все в ядре. Прочтите исходный код ядра., @Majenko
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- устаревшее преобразование из строковой константы в 'char*'
Хотя Arduino [Руководство по стилю API](https://www.arduino.cc/en/Reference/APIStyleGuide) рекомендует использовать
begin()
для настройки. Для меня и то, и другое является работой и является соображением дизайна, при условии, что вы знаете, что было настроено и инициализировано с помощьюArduino.h
и [варианты](https://github.com/arduino/ArduinoCore-avr/tree/master /variants) для конкретной платы, и то, что вы пытаетесь сделать в конструкции, не будет переопределено init() внутри Arduino Coremain()
. Например, вы видите, что многие библиотеки используют конструкцию для настройки, например, «LCD lcd (SDL, SDA);»., @hcheungНа ваш вопрос о setup() и loop() см. исходный код Arduino Core [main.cpp](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp ) для лучшего понимания., @hcheung