Практика показывает, для создания прошивки микроконтроллера есть несколько вариантов. В этой статье простой и наглядный метод — графический. Начнём с простого , включим — выключим светодиод. Так же проверим полученную прошивку в «железе». Написание алгоритма программы будет среде FLOWcode5 для микроконтроллера PIC16F628.
На момент написания статьи есть версия FLOWcode9 , но принципиальных отличий для нашего примера нет. Выбор микроконтроллера обозначен тем что было под рукой, сменить микроконтроллер не сложно при создании проекта, а перенос проекта на микроконтроллер AVR тоже, в большинстве случаев для небольших проектов, не составит труда
Простой алгоритм.
Простым алгоритмом можно посчитать выполнение набора последовательных действий в бесконечном цикле. Итак, поехали .
После запуска среды разработки FLOWcode5 для контроллеров Microchip PIC16, выбираем интересующий нас для проекта микроконтроллер ( в нашем случае PIC16F628) , жмем ОК и на главной странице видим пустой алгоритм как на рисунке ниже.
Пишем первый код для ATMEGA32 в Атмел студио и мигаем светодиодом
Алгоритм по умолчанию FLOWcode5.
Первым делом необходимо проставить значения базовых настроек микроконтроллера, для этого заходим в меню ЧИП — ПАРАМЕТРЫ ПРОЕКТА, как на фото ниже. Выставляем тактовую частоту 4 000 000 Гц — от нее зависят все временные параметры работы микроконтроллера. Выбираем внутренний генератор тактовой частоты INTRC I/O, для простоты реализации нашего примера в «железе», особая стабильность по тактовой частоте в проекте не нужна.
Основные параметры проекта.
Теперь нам необходимо указать в проекте к какому выводу микроконтроллера будет подключен светодиод. Для этого в строчке с компонентами выбираем светодиод.
Добавление компонента.
В свойствах компонента (выбирается на правой панели свойств компонентов) указываем , что светодиод подключен к порту PORTB5.
Cветодиод подключен к порту PORTB5
Указав среде разработки что у нас в проекте по материальной составляющей (какой микроконтроллер и где подсоединён светодиод), начнем описание требуемого алгоритма поведения микроконтроллера. Сперва указываем бесконечный цикл — переносим в дерево алгоритма цикл WHILE с левого меню, как на картинке ниже , условия не меняем.
Добавление бесконечного цикла в алгоритм программы.
В тело цикла добавляем необходимые модули — Макрос Компонента и Задержка. В модуле Макрос Компонента необходимо выбрать модуль нашего светодиода (LED(0)) и необходимое действие сначала включить , затем выключить. В модуле задержка указываем паузу для включенного и выключенного состояния по одной секунде. Получившийся алгоритм представлен ниже на рисунке.
Созданный алгоритм.
Теперь можно запустить моделирование (нажимаем F5) и посмотреть на работу алгоритма в реальном времени. Не забудьте включить панель с компонентами — на ней визуально расположен наш светодиод. Для этого необходимо поставить отметку в меню Вид->Панель.
Алгоритм с использованием таймера.
Для более корректного написания данного примера ( на мой взгляд ) необходимо использование прерывания по таймеру . Для этого необходимо активировать отслеживание события по таймеру. Добавим с левой панели инструментов соответствующий блок и укажем что работаем по таймеру №1, событие по переполнению , счет ведется от внутреннего генератора с делителем на 4 и на 8. На рисунке ниже отображены все настройки прерывания и получившийся частота срабатывания таймера — 1,907Гц. Не забываем указать название макроса , который будет вызываться при срабатывании прерывания, в нем будем писать обработчик события.
Flowcode 9 первая программа для микроконтроллера STM32
Добавление прерывания по таймеру.
После нажатия «OK появиться область ввода алгоритма обработки прерывания. Для нашего алгоритма добавим переменную — svet- логическая переменная , два состояния. В этой переменной будем хранить состояние светодиод — включен или выключен. Добавление переменных происходит в окне проекта , как на рисунке ниже.
Добавление логической переменной .
При срабатывании прерывания будем начинать наш обработчик с опроса переменной svet и в зависимости от её состояния будем включать или выключать светодиод. Для этого добавим в алгоритм логический блог с панели слева, а условием будет наша переменная. Включение и выключение светодиода осуществляется встроенным макросом. После манипуляций со светодиодом инвертируем нашу переменную svet , добавляя блок вычисление как на рисунке ниже.
Источник: dzen.ru
Программирование микроконтроллеров для начинающих — первый шаг
Я, наверное, немного поспешил, назвав статью «Программирование микроконтроллеров AVR — первый шаг». Скорее, эта статья, как и все последующие, — маленький шажок в мир микроконтроллеров. И таких «шажков» у нас будет много, пока не дойдем до того момента, когда сможем сказать: «Микроконтроллер — последний шаг».
Но и это, скорее всего, из области фантастики — нельзя объять необъятное, — мир микроконтроллеров постоянно развивается и совершенствуется. Наша задача — сделать первый шаг, логическим итогом которого должна стать первая, самостоятельно разработанная и собранная конструкция на микроконтроллере. А дальше, -дальше каждый поплывет своей дорогой в совершенствовании полученных на сайте знаний. И тогда, завершающую статью можно будет назвать так: «Программирование микроконтроллеров — последний шажок первого шага» (надо же, как загнул!).
И так, приступаем.
Три условия для желающих освоить микроконтроллер
1. Желание и настойчивость в достижении поставленной цели
Этот пункт, на мой взгляд, — самый главный. Не будет желания, а еще хуже — настойчивого желания, то и не будет результата. Главное не пасовать и не останавливаться, проявите настойчивость — и все получится (и не только в деле освоения микроконтроллеров).
2. Знание устройства микроконтроллера.
Немаловажный фактор. Ведь, согласитесь, не зная как устроен микроконтроллер, что он имеет в своем распоряжении, как это все работает, — мы не сможем использовать все возможности микроконтроллера, выжать из него все, на что он способен.
Возможно и не стоит очень глубоко копаться во «внутренностях» микроконтроллера, но основное, так сказать — азы, мы знать должны (этим мы и будем заниматься на страницах сайта — изучать азы работы с микроконтроллером).
3. Знание команд управления микроконтроллерам.
Микроконтроллер, как собака (такое вот интересное сравнение), будет смотреть на нас умными глазами и вилять своим хвостом, пока не подадим ему команду на выполнение каких-то действий.
В отличие от умной собаки, микроконтроллер понимает намного больше команд — более 130 штук.
Так вот, чтобы микроконтроллер не только вилял хвостом, но и выполнял нужную нам работу, — необходимо знать команды управления им.
Сразу хочу сказать, для начала не надо зубрить все 130 команд, достаточно будет знания и половины (и даже меньше). К тому же, многие команды дублируют друг-друга. Но чем больше команд мы будем знать, тем эффективней мы сможем управлять микроконтроллером и тем красивее и элегантнее будут выходить из-под нашего пера программы.
Итого, если у вас есть настойчивое желание освоить микроконтроллер, тогда продолжаем.
Что такое программа
Какие задачи вы возлагаете на микроконтроллер, и как он будет их выполнять, определяется заложенной в него программой – программой которую для микроконтроллера составляете вы сами.
Программа (в переводе это слово означает – “предписание”) – предварительное описание предстоящих событий или действий.
К примеру, мы хотим, чтобы микроконтроллер помигал светодиодом. Довольно простая задача, но тем не менее, для того, чтобы микроконтроллер выполнил ее, мы, предварительно, должны шаг за шагом описать все действия микроконтроллера — написать программу, которую он должен выполнить для получения нужного нам результата – мигающий светодиод.
Что-то вроде такого:
♦ Зажечь светодиод:
— настроить вывод микроконтроллера,к которому подключен светодиод, для работы на вывод информации
— подать на этот вывод логический уровень, который позволит зажечь светодиод
♦ Подождать некоторое время:
— перейти к подпрограмме формирующей паузу (которую тоже нужно “прописать”)
— по выполнению подпрограммы паузы вернуться в основную программу
♦ Погасить светодиод:
— подать на вывод микроконтроллера логический уровень, гасящий светодиод
и так далее.
С термином Программа неразрывно связан другой термин – Алгоритм.
Что такое алгоритм
Алгоритм – набор инструкций, описывающих порядок действия для достижения нужного результата.
Если в программе мы подробнейшим образом прописываем все действия микроконтроллера, то в алгоритме, — мы определяем порядок действий микроконтроллера, на основе которых мы потом создадим программу. По аналогии с вышеприведенном примером:
♦ Зажечь светодиод
♦ Подождать некоторое время
♦ Погасить светодиод
и так далее.
Таким образом, алгоритм – это предшественник программы. И чем тщательно и продумано будет создан алгоритм, тем проще будет создавать программу.
Язык программирования
К сожалению, если любимой собачке мы можем подавать команды на человеческом языке, то общение с микроконтроллером должно происходить на языке, который понятен ему — языке микроконтроллерных команд.
Команды для микроконтроллера имеют вид набора единичек и нулей, типа:
00110101 011000100
так называемые – коды команд, а коды команд – это язык который понимает микроконтроллер. А для того, чтобы перевести наш язык общения на язык микроконтроллера – в эти самые наборы нулей и единичек, существуют специальные программы.
Эти программы позволяют описать порядок работы для микроконтроллера на более-менее понятном для нас языке, а затем перевести этот порядок на язык понятный микроконтроллеру, в результате чего получается так называемый машинный код – последовательность команд и инструкций (те самые нули и единички) которые только и понимает микроконтроллер. Текст программы, написанный программистом, называется исходным кодом. Перевод программы с языка программирования (исходного кода) на язык микроконтроллера (машинный код) производится трансляторами. Транслятор превращает текст программы в машинные коды, которые потом записываются в память микроконтроллера.
В таких программах порядок работы микроконтроллера описывается специальным языком – языком программирования.
Язык программирования – это способ передачи команд, инструкций, чёткого руководства к действию для микроконтроллера.
Из множества языков программирования можно выделить два типа :
– языки программирования низкого уровня
– языки программирования высокого уровня
Чем они отличаются. А отличаются они своей близостью к микроконтроллеру.
На заре зарождения микропроцессорной техники, программы писали в машинных кодах, то есть весь алгоритм работы последовательно прописывали в виде нулей и единичек. Вот так, примерно, могла выглядеть программа:
01010010
01000110
10010011
Трудно, даже профессионалу, разобраться в такой комбинаций из двух цифр. Для облегчения своей жизни, программисты стали создавать первые языки программирования. Так вот, чем ближе язык программирования к такому набору нулей и единиц тем больше он “низкого уровня”, а чем дальше от них – тем больше “высокого уровня”.
Самые распространенные языки программирования для микроконтроллеров:
— язык низкого уровня – Ассемблер
— язык высокого уровня – С (Си)
Давайте посмотрим на примере их различия (эти примеры абстрактные).
Допустим нам надо сложить два числа: 25 и 35.
В машинных кодах эта команда может выглядеть так:
00000101 1101001
На языке низкого уровня:
ADD Rd, Rr
На языке высокого уровня:
25+35
Различие языков низкого и высокого уровня видны невооруженным глазом.
Но давайте копнемся в этих примерах поглубже. Пример машинного кода разбирать не будем, так как он идентичен примеру на Ассемблере. По своей сути, Ассемблерные команды это те же машинные коды (команды) которым просто, чтобы не заблудиться в нулях и единицах, присвоены буквенные аббревиатуры.
Ассемблерной командой ADD Rd, Rr мы ставим микроконтроллеру задачу сложить два числа, которые находятся (а для этого мы должны их туда предварительно записать) – первое в Rd, второе в Rr, а результат сложения поместить в Rd. Как видите мы ставим очень конкретную задачу микроконтроллеру: где взять, что с этим сделать и куда поместить результат. В этом случае мы работаем напрямую с микроконтроллером.
Команда на языке высокого уровня: 25+35, привычная для нас математическая запись, радующая наш глаз. Но в этом случае мы не работаем напрямую с микроконтроллером, мы просто ставим ему задачу сложить два числа. Результат и последовательность действий в данном случае будет тот-же, что и при выполнении ассемблерной команды: сначала эти два числа будут куда-то записаны, затем сложены а результат куда-то помещен.
И вот тут кроется главное отличие языков высокого уровня и низкого уровня. Если в Ассемблере мы контролируем весь процесс (хотим мы того, или нет): мы знаем где записаны эти два числа, и мы знаем где будет находиться результат, то в языке высокого уровня мы процесс не контролируем. Программа сама решает куда предварительно записать числа и куда поместить результат.
В большинстве случаев нам это и не надо знать, ведь для нас главное итог – число 60 на выходе. Как результат, программы на языках высокого уровня более читаемы (спорный вопрос), приятны для глаза (спорный вопрос) и меньше по размеру – ведь нам не приходится “лезть во все дыры” и расписывать каждый шаг микроконтроллера, программа это делает потом за нас, когда компилирует ее – переводит в машинные коды. Но тут есть и минус. Два одинаковых алгоритма написанных на Ассемблере и на Си, после преобразования их в машинные коды будут иметь разный размер: программа написанная на Ассемблере будет на 20-40% короче программы написанной на Си – черт его знает, каким путем идет Си для достижения нужного нам результата. И бывают случаи, когда нет доверия к языку высокого уровня и в программе на Си делают вставки кода, написанные на Ассемблере.
Продвинутые программисты, как правило, знают несколько языков программирования, творчески соединяя их возможности и преимущества в одной программе. Ну а нам, любителям, надо знать хотя бы один язык (для начала), и начинать надо (а я в этом твердо уверен)с языка низкого уровня – Ассемблера.
(28 голосов, оценка: 4,82 из 5)
Источник: microkontroller.ru
4 Разработка алгоритма работы управляющей программы для микроконтроллера
На рисунке 3 изображена блок-схема основной программы микроконтроллера.
Настройка портов вывода
Процедура подключения устройства к компьютеру
Ожидание входящих блоков данных
Рисунок 3 – Блок-схема основной программы
Основная программа начинается с настройки порта PB1 на вывод, остальные на ввод. Затем идет процедура подключения устройства к компьютеру которая состоит из функций usbDeviceDisconnect(), паузы и usbDeviceConnect(), которые служат для отключения и подключения микроконтроллера к компьютеру соответственно.
Следом идет бесконечный вызов функции usbPoll(), которая служит для инициализации устройства на компьютере. Эта функция должна вызываться не менее чем через каждые 50 мс. Иначе устройство не будет распознано. Так же в последний блок включаются прерывания, а именно функции usbFunctionWrite() и usbFunctionRead(), которые служат для приема и отправки микроконтроллером блока данных соответственно.
5 Функции и переменные основной программы для микроконтроллера
Прототипы функций и их описание:
– usbFunctionRead() вызывается когда хост запрашивает порцию данных от устройства
– usbFunctionWrite() вызывается когда хост отправляет порцию данных к устройству
– usbFunctionSetup(uchar data[8]) – инициализация класса устройства HID
– usbInit() – Эта функция должна быть вызвана перед разрешением прерываний и заходом в основной цикл main.
– usbDeviceDisconnect() – Эта функция не соединяет устройство с шиной USB хоста.
– usbDeviceConnect() – Эта функция соединяет устройство с шиной USB хоста.
– usbPoll() – Эта функция должна быть вызвана через регулярные интервалы внутри главного цикла main. Максимальная задержка между вызовами должна быть несколько меньше 50 мс (таймаут USB для принятия сообщения Setup). Иначе устройство не будет распознано.
– uchar b1 — без знаковый символьный тип, в нем хранится блок данных.
– static uchar currentAddress — без знаковый символьный тип. Эта переменная отвечает за адрес чтения и записи данных.
– static uchar bytesRemaining — без знаковый символьный тип. Эта переменная отвечает за количество оставшихся байт данных.
– uchar len — без знаковый символьный тип. Эта переменная отвечает за длину текущего сообщения.
– uchar *buffer – указатель на без знаковый символьный тип. Указывает на начала области буфера.
– uchar *data — указатель на без знаковый символьный тип. Указывает на начала области данных.
Источник: studfile.net