RadioHata.RU
Портал радиолюбителя, начинающему радиолюбителю, Arduino, Raspberry Pi, книги по радиотехнике и электронике, простые схемы, схемы, радиотехнические журналы, видео, программы для радиолюбителя.
Download magazines: AudioXpress, Circuit Cellar, CQ Amateur Radio, Electronics For You, Elektronika dla Wszystkich, Elektorlabs, Elektor Magazine DVD, Elektronika Praktyczna, Elettronica In, ELV Journal, Funkamateur, Hi-Fi World, Klang+Ton, Nuts and Volts, Prakticka Elektronika A Radio, Practical Electronics, Practical Wireless, QST, Servo Magazine, Silicon Chip, Swiat Radio, The MagPi.
Скачать: Журнал Радио, Журнал Радиомир, Журнал Радиоаматор, Журнал Радиолоцман, Журнал Радиоконструктор, Журнал Радиосхема, Журнал Радиохобби, Журнал Ремонт и сервис, Журнал Компоненты и технологии, Журнал Электронная техника.
Скачать книги: Начинающему радиолюбителю, Телевидение и Радио, Источники питания, Для дома и быта, Прием-передача, Автолюбителю, Аудиотехника, Справочники, Учебники, Микроконтроллеры, Arduino, Raspberry Pi, Электроника, Электрика
Flowcode 9 первая программа для микроконтроллера STM32
Скачать: Программы для радиолюбителя, Видеокурсы.
Источник: radiohata.ru
Простейшие программы для микроконтроллера!
Программы для микроконтроллеров по факту ничем, кроме способа взаимодействия с пользователем и окружением, не отличаются от обычных программ. И тем, что они бесконечны, конечно.
Любая программа начинается с инициализации: настройка кода и всей аппаратной составляющей контроллера в тот режим, который требуется для работы программы. А дальше идёт бесконечный цикл и реагирование на события.
Но не будем погружаться в дебри, как реализовываются отдельные действия, и посмотрим на простых примерах, как же устроены могут быть программы для приборов в целом. Напряжения и названия условны. От контроллера к контроллеру они могут различаться.
Пример 1. Моргание светодиодом.
Цель : светодиод на плате моргает с заданной частотой и видом сигнализации. Например, секунду потушен и 500 миллисекунд светится.
Ресурсы контроллера : вывод A, который подключён к светодиоду, ядро.
Примерная схема подключения светодиода к выводу микроконтроллера.
Примерный вид программы :
1. Включаем блок управления цифровыми выводами (подаём питание, тактирование — согласно документации).
2. Задаём режим работы вывода А на выход. То есть управляем его напряжением напрямую. В состоянии 0 там будет напряжение 0 и светодиод будет светиться, в состоянии 1 там будет порядка +5 В и свечения не будет.
PinA. Output();
3. Сразу же ставим его в состояние, когда светодиод светиться не будет, то есть в высокий уровень.
Инициализация завершена, можно и начать работать!
4. Выставляем состояние вывода в высокий уровень. Светодиод гаснет. Сюда будем возвращаться после окончания цикла и начинать всё по-новой.
Как просто научиться программировать микроконтроллеры PIC и AVR / Бегущие огни за 8 минут!
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);
- Мигание светодиодом на ATMega16/32 (AVR);
- Мигаем светодиодом (AVR, Arduino);
- 8L-Курс, Часть 1 — Hello светодиод! (STM8);
- STM8 мигаем светодиодом (STM8, не совсем похоже, но почти);
- Курс «Штурмуем STM32». Моргаем светодиодом (STM32F1);
- STM32 + EmBlocks — мигаем светодиодами (STM32F1);
- STM32F0. Моргание светодиодом (STM32F0);
- STM32F4. Урок 1 — управление светодиодами (STM32F4);
- Уроки MSP430 LaunchPad. Урок 04: Застреваем в цикле (MSP430);
- Начало работы с PSoC® (Cypress PSOCx).
И подобных статей даже на русском языке не одна сотня под разные контроллеры, среды разработки, языки. Непонятна одна — можно открыть другую и продолжить!
Источник: dzen.ru
Архитектура программы для микроконтроллера
Существует два принципиально разных подхода к построению программной архитектуры микроконтроллера — однопоточная архитектура (пример — рис. 8) и многопоточная архитектура (пример — рис. 9).
Рис. 8. Вариант однопоточной архитектуры построения программы для микроконтроллера
Общая структура программы для микроконтроллера, написанной без использования ОС, обычно включает следующие программные модули:
- • модуль инициализации;
- • модули обработки прерываний;
- • модули управления периферийными устройствами;
- • модуль управления программными потоками (для многопоточной архитектуры);
- • модуль основного программного цикла (для однопоточной архитектуры).
Однопоточная архитектура ПО. Программа имеет единственный основной цикл, который реализует весь алгоритм программы. Из этого единственного цикла производится обращение к программным модулям управления периферийными устройствами по мере необходимости. В свою очередь, модули управления периферийными устройствами могут обмениваться данными с процедурами обработки прерываний.
Рис. 9. Вариант многопоточной архитектуры построения программы для микроконтроллера
Многопоточная архитектура ПО. В этом случае после инициализации необходимых программных и аппаратных ресурсов запускается модуль управления программными потоками, который в свою очередь запускает первый программный поток. В процессе выполнения алгоритма программные потоки могут добавляться и удаляться.
Каждый из программных потоков может производить обращение к программным модулям управления периферийными устройствами по мере необходимости. В свою очередь, модули управления периферийными устройствами могут обмениваться данными с процедурами обработки прерываний. Кроме того, потоки могут обмениваться данными между собой.
Каждый из представленных вариантов архитектуры имеет свои преимущества и недостатки.
Однопоточная архитектура ПО представляет собой, по сути, цикл обработки событий, в котором по очереди проверяется возникновение определенных событий, таких как срабатывание таймера, появление определенного логического уровня на входной линии микроконтроллера, получение данных от какого-либо периферийного устройства, окончание передачи данных и т. п.
При обнаружении какого-либо события, программа принимает решение о дальнейших действиях и переходит к проверке возникновения следующего события.
Цикл «проверка возникновения события — принятие решения», как правило, является бесконечным.
Прерывания с точки зрения основного цикла являются просто источником событий.
Например, прерывание, вызываемое при получении данных по последовательному порту, помещает данные из порта в буфер приема и выставляет специальный флаг, обозначающий «в буфере приема есть данные». С точки зрения основного цикла не имеет значения, как данные появились в буфере приема. Единственное, что «интересует» алгоритм основного цикла, — это флаг «в буфере приема есть данные» и сами принятые данные.
Достоинства однопоточной архитектуры — это простота реализации алгоритма и минимально возможное использование ресурсов памяти.
К недостаткам однопоточной архитектуры можно отнести абсолютно негибкое распределение ресурса процессорного времени.
Многопоточная архитектура гораздо более сложна в реализации, чем однопоточная, и требует гораздо больших ресурсов оперативной памяти (или, что то же, памяти данных в семействе микроконтроллеров AVR). Однако такая архитектура позволяет гибко распределять ресурс процессорного времени, запуская программные потоки в случае необходимости и останавливая их после выполнения нужных задач.
Попробуем дать оценку того, какие ресурсы необходимы для реализации многопоточной архитектуры на микроконтроллерах семейства AVR. Для этого определим, что мы называем «программным потоком» применительно к программам для микроконтроллеров.
Программный поток — это одна из функций, которая выполняется одновременно с другими в режиме разделения времени. Каждый поток имеет отдельный программный стек и стек возвратов, а также отдельный контекст потока.
Контекст потока — это данные о состоянии потока, позволяющие полностью восстановить состояние этого потока. Для микроконтроллеров семейства AVR контекст потока состоит из регистров общего назна чения R0-R31, регистра-указателя стека SP, регистра-счетчика команд PC и регистра состояния (или флагов) SREG. Кроме того, каждому потоку нужен программный стек и стек возвратов. Размер программного стека потока определяет максимальный размер автоматических переменных, которые можно создать в этом потоке. Размер стека возвратов определяет глубину вызова функций из данного потока.
Оценим, какой расход памяти данных требуется на каждый программный поток микроконтроллера семейства AVR. Как нетрудно подсчитать, размер контекста равен для AVR 37 байт — 32 байта РОН R0-R31, 2 байта регистр-указатель стека SP, 2 байта программный счетчик PC и 1 байт регистр состояния SREG.
Пусть суммарный объем стека возвратов и программного стека равен 32 байтам. Этого достаточно, чтобы вызвать функции с параметрами на несколько уровней вложенности.
Таким образом получаем, что оценочно для организации одного потока на микроконтроллере семейства AVR необходимо 32+37=69 байт памяти данных.
Это, казалось бы, небольшая величина. Однако, во-первых, объем памяти данных в микроконтроллерах семейства AVR, даже в старших моделях, измеряется единицами килобайт. И, во-вторых, реализация более или менее сложного алгоритма в каком-либо потоке может потребовать гораздо большего размера стека для этого потока.
Поскольку микроконтроллер в один момент времени может выполнять только одну машинную команду, то слово «одновременно» не совсем верно отражает суть многопоточного выполнения программы.
Модуль управления потоками по определенному событию (например, по прерыванию от таймера) сохраняет контекст одного потока, восстанавливает контекст другого потока и передает этому потоку управление. Иными словами, модуль управления потоками периодически выполняет переключение потоков. Переключение потоков выполняется прозрачно. С точки зрения функции-потока, она выполняется так, как если бы была единственной и не прерывалась.
К достоинствам многопоточной архитектуры относится гибкость распределения ресурсов микроконтроллера.
К недостаткам многопоточной архитектуры можно отнести гораздо большие требования к ресурсам микроконтроллера, таким как память, по сравнению с однопоточной. Следует помнить, что переключение потоков также требует процессорного времени.
Вопрос выбора архитектуры ПО является одним из главных вопросов, на которые необходимо ответить на стадии проектирования ПО.
Неверный выбор архитектуры влечет за собой массу трудноразрешимых проблем.
На основе практического опыта можно сказать, что если алгоритм имеет статическую структуру (в том смысле, что все программные компоненты задействованы всегда во время выполнения программы), то обычно лучше подходит однопоточная архитектура.
Если структура алгоритма динамическая, т. е. некоторые программные компоненты могут быть не задействованы при определенных условиях, то более подходит многопоточная архитектура. Поясним на примерах.
Допустим, мы проектируем ранее упомянутый полностью автономный интеллектуальный термометр. Нетрудно предположить, что алгоритм его работы будет сводиться к опросу датчиков температуры и выводу информации на индикатор. Разумеется, что для такого устройства лучше всего подходит однопоточная архитектура.
Теперь предположим, что нам необходимо снабдить проектируемый интеллектуальный таймер тремя каналами связи — RS485, радиоканалом и беспроводным каналом Wi-Fi. Причем эти каналы не могут использоваться одновременно — из всех каналов связи в каждый момент используется только один, по желанию пользователя. В этом случае, программную поддержку каждого из каналов связи будет логично оформить в виде отдельного потока выполнения и запускать только один, требуемый, поток из трех. В данном случае многопоточная архитектура позволит сэкономить память данных и ресурс процессорного времени, который в случае однопоточной архитектуры тратился бы для обслуживания неиспользуемых устройств.
Как видим, изменение функциональных возможностей устройства кардинально влияет на соображения выбора архитектуры.
Приведем пример структуры программного обеспечения микропроцессорного устройства (рис. 10).
Данное МПУ предназначено для работы в составе РМПС, поэтому имеются интерфейсы передачи данных Ethernet и RS232, программные модули маршрутизации и обработки протоколов передачи данных.
Кроме того, имеются программные модули, реализующие интерфейс пользователя.
Заметим, что сам по себе состав программных модулей ничего не говорит о типе архитектуры ПО — однопоточной или многопоточной.
Показанная на рис. 10 структура ПО МПУ может быть реализована как на базе однопоточной, так и на базе многопоточной архитектуры. Все зависит от возможностей микропроцессорной системы и решаемых этой системой задач.
Управление каналами связи
Рис. 10. Пример структуры программного обеспечения МПУ
Источник: bstudy.net