Введение
Программы для микроконтроллеров по факту ничем, кроме способа взаимодействия с пользователем и окружением, не отличаются от обычных программ. И тем, что они бесконечны, конечно.
Любая программа начинается с инициализации: настройка кода и всей аппаратной составляющей контроллера в тот режим, который требуется для работы программы. А дальше идёт бесконечный цикл и реагирование на события.
Но не будем погружаться в дебри, как реализовываются отдельные действия, и посмотрим на простых примерах, как же устроены могут быть программы для приборов в целом. Напряжения и названия условны. От контроллера к контроллеру они могут различаться.
Пример 1. Моргание светодиодом.
Цель: светодиод на плате моргает с заданной частотой и видом сигнализации. Например, секунду потушен и 500 миллисекунд светится.
Ресурсы контроллера: вывод A, который подключён к светодиоду, ядро.
Примерный вид программы:
1. Включаем блок управления цифровыми выводами (подаём питание, тактирование — согласно документации).
InitGPIO();
2. Задаём режим работы вывода А на выход. То есть управляем его напряжением напрямую. В состоянии 0 там будет напряжение 0 и светодиод будет светиться, в состоянии 1 там будет порядка +5 В и свечения не будет.
PinA.Output();
3. Сразу же ставим его в состояние, когда светодиод светиться не будет, то есть в высокий уровень.
PinA.High();
Инициализация завершена, можно и начать работать!
4. Выставляем состояние вывода в высокий уровень. Светодиод гаснет. Сюда будем возвращаться после окончания цикла и начинать всё по-новой.
PinA. High();
5. Ждём 1 секунду
WaitMilliseconds(1000);
6. Выставляем состояние вывода в низкий уровень, светодиод включается!
PinA.Low();
7. Ждём 500 миллисекунд.
WaitMilliseconds(500);
8. Возвращаемся к пункту 4 и продолжаем оттуда.
В данном коде выкинута лишняя инструкция 3, так как она дублируется инструкцией 4. Но так совпало чисто случайно =)
InitGPIO();
PinA.Mode(OUTPUT);
while(true) {
PinA. High();
WaitMilliseconds(1000);
PinA.Low();
WaitMilliseconds(500);
}
Задача решена. Ничего сложного же?..
Пример 2. Включение светодиода на время по кнопке.
Цель: светодиод на плате включается на одну секунду после того, как нажали на кнопку.
Например, для игры-викторины, чтоб было видно, кто хочет отвечать.
Ресурсы контроллера: вывод A, который подключён к светодиоду, вывод Б, который подключён к кнопке, ядро.
Примерный вид программы:1. Включаем блок управления цифровыми выводами (подаём питание, тактирование — согласно документации) и задаём режим работы вывода А на выход, как в программе 1 и его начальное состояние.
InitGPIO();
PinA.Output();
PinA.High();
2. Задаём режим работы вывода Б на вход. Мы не будем влиять на состояние вывода, но будем знать, какое у него состояние: высокий там уровень или низкий.
PinB.Input();
Инициализация завершена, можно и начать работать!
3. Проверяем состояние вывода Б, если там низкий уровень, значит, кнопку нажали и идём на пункт 4! Если не нажали, то снова идём сюда же проверять. Всё равно больше делать ничего не надо.
if (PinB.Get() == false) {
4. Включаем светодиод, ждём 1000 миллисекунд и выключаем.
PinA.Low();
WaitMilliseconds(1000);
PinA. High();
5. Возвращаемся к пункту 3, чтобы снова проверить, не нажали ли на кнопку.
Итого:
InitGPIO();
PinA.Output();
PinA.High();
PinB.Input();
while(true) {
if (PinB.Get() == false) {
PinA.Low();
WaitMilliseconds(1000);
PinA. High();
}
}
Просто же?.. Да, пусть код не лучший, но задачу выполняет. Если кнопка не нажата, условие не будет выполняться и светодиод не включится. Как только нажмём, напряжение на выводе Б станет нулевым, и проверка сработает: включится светодиод на секунду.
Заключение.
Простые программы просты и начать их писать может каждый! А дальнейший прогресс уже дело опыта и желания.
Попробуйте найти в интернете аналогичный пример для своего контроллера, сопоставить его с этими и поиграться, меняя тайминги, рисунки морганий или ещё что-нибудь. Можно так морзянкой написать сообщение, правильно подобрав тайминги и написав портянкой все включения и выключения или сделав функцию для этого... Имея в арсенале всего лишь смену уровня на выводе и проверку состояния вывода можно уже сделать целую кучу устройств, комбинируя их в правильном порядке!
Пока задача одна — код может быть сколько угодно синхронным, с ожиданиями. Но всё изменится, когда надо будет выполнять параллельно несколько задач: основную функцию, индикацию, связь, например... Но к этому мы ещё придём.
Ссылки.
Приведу примеры статей, где это делается для самых разных контроллеров:
- Моргающий светодиод на AVR (AVR);
- Мигаем светодиодом (AVR, Arduino);
- STM8 мигаем светодиодом (STM8, не совсем похоже, но почти);
- Курс "Штурмуем STM32". Моргаем светодиодом (STM32F1);
- STM32 + EmBlocks — мигаем светодиодами (STM32F1);
- STM32F0. Моргание светодиодом (STM32F0);
- STM32F4. Урок 1 - управление светодиодами (STM32F4);
- Начало работы с PSoC® (Cypress PSOCx).
И подобных статей даже на русском языке не одна сотня под разные контроллеры, среды разработки, языки. Непонятна одна — можно открыть другую и продолжить!