Как сделать попеременное включение

Добавил пользователь Владимир З.
Обновлено: 03.09.2024

Данная статья является первой в планируемом цикле статей по изучению программирования микроконтроллеров. Изучая различные материалы я отметил, что практически все они начинаются с того, что новичку предлагается скачать (или использовать идущую со средой разработки) библиотеку для работы с периферийными устройствами и использовать ее для написания своей первой программы (обычно мигание светодиодом).

Выбор микроконтроллера

Многие могут сказать, что начинать изучение микроконтроллеров лучше с AVR, PIC, 8051 или чего-то еще. Вопрос многогранный и спорный. Я знаю достаточно примеров, когда люди изучив Cortex-M, программировали AVR, ARM7 и т.д. Сам же я начинал с Cortex-M3. Если перед вами стоит определенная задача, в интернете достаточно много информации со сравнением различных типов микроконтроллеров и решаемых с их помощью задач. На хабре этот вопрос тоже поднимался, например тут.

Будем считать, что с типом микроконтроллера мы разобрались. Но на рынке представлен огромнейший спектр различных модификаций от разных производителей. Они отличаются по множеству параметров — от размера флеш памяти до количества аналоговых входов. Для каждой задачи выбор стоит производить индивидуально. Ни каких общих рекомендаций тут нет и быть не может. Отмечу лишь, что стоит начинать изучение с МК производителей имеющих как можно больший ассортимент. Тогда, при выборе МК для определенной задачи достаточно велик шанс, что из представленного ассортимента вам что-нибудь да подойдет.

Я остановил свой выбор на STM32 (хотя и считаю, что лучше начинать изучение с МК от TexasInstruments — очень грамотно составлена документация), потому что они широко распространены среди российских разработчиков электроники. При возникновении проблем и вопросов вы сможете без труда найти решения на форумах. Еще одним плюсом является богатый выбор демонстрационных плат как от производителя, так и от сторонних организаций.

Что необходимо для изучения?

К сожалению, для начала программирования МК не достаточно одного лишь ПК. Придется где-то раздобыть демонстрационную плату и программатор. Хотя это и уменьшает конкуренцию на рынке труда.

Сам я использую демонстрационную плату STM3220G-EVAL и программатор J-Link PRO. Но для начала, будет вполне достаточно STM32F4DISCOVERY, которую можно купить без особых проблем за небольшую сумму.

Все примеры будут именно для отладочной платы STM32F4DISCOVERY. На данном этапе нам будет совершенно не важно, что этой плате стоит МК на базе ядра Cortex-M4. В ближайшее время мы не будем использовать его особенности и преимущества над Cortex-M3. А как там будет дальше — посмотрим.

Если у вас есть в наличии любая другая плата на базе STM32F2xx/STM32F4xx, вы сможете работать с ней. В изложении материала я постараюсь максимально подробно описывать почему мы делаем именно так, а не иначе. Надеюсь ни у кого не возникнет проблем с переносом примеров на другое железо.

Среда разработки


Как уже неоднократно упоминалось, для ARM микроконтроллеров существует достаточное количество сред разработки, как платных так и не очень. И снова хочется опустить полемику по этому поводу. Я использую IAR Embedded Workbench for ARM 6.60. Все примеры будут именно в этой среде. Если вам по душе (или в вашей организации используется) что-то другое (Keil, Eclipse, CCS, CooCoc и т.д.) то это вам тоже не очень помешает. На особенности, связанные именно со средой разработки, я буду обращать отдельное внимание.

Возможно, кто-то будет не совсем доволен тем, что я предлагаю использовать платную среду разработки, но в IAR есть возможность получить временную лицензию без ограничения функционала, либо безлимитную лицензию с ограничением по размеру кода (32КБ для МК это очень много).
Помимо этого, сразу замечу, что для некоторых МК не существует бесплатных сред разработки. И к сожалению эти МК в некоторых областях незаменимы.

Процесс установки я описывать не буду.

С чего начать?

Создание проекта

Для начала создадим пустой проект. IAR позволяет создать проекты на ASM, C и C++. Мы будем использовать C.


Перед нами появится пустой проект с main файлом.



При выборе целевого программируемого процессора происходит загрузка его описания, что дает широкие возможности для отладки (об этом будет идти речь ниже). Кроме того, автоматически присоединяется конфигурационный файл с описанием доступного адресного пространства для линкера. Если будет необходимо, мы затронем тему конфигурационного файла линкера в следующих статьях.

Теоретически, IAR позволяет отлаживать программы с использованием симулятора. Но я ни разу на практике не встречал его использования.

Теперь проект готов для работы (программирования, заливки и отладки).

Подведем промежуточный итог: МК и отладочная плата выбраны, проект подготовлен. Пора определиться с задачей.

Прежде чем приступать к программированию, или немного теории

Прежде чем приступить к реализации нашего ТЗ, необходимо понять как производится управление МК.

Начнем с того, что любой МК включает ядро, память и периферийные блоки. Думаю, что с памятью пока все понятно. Упомяну лишь, в STM32 есть флеш память в которой хранится программа МК (в общем случае это не верное утверждение, программа может храниться во внешней энергонезависимой памяти, но пока это опустим) и другие данные, в том числе и пользовательские. Так же есть SRAM — оперативная память.

Ядро — часть микроконтроллера, осуществляющая выполнение одного потока команд. В нашем МК тип ядра — Cortex-M4. Ядро МК можно сравнить с процессором в ПК. Оно умеет только выполнять команды и передавать данные другим блокам (в этом сравнении не учитываются процессоры с интегрированными графическими ускорителями).
При этом производитель МК не разрабатывает ядро. Ядро покупается у компании ARM Limited. Главное отличие между различными МК — в периферии.

Взаимодействие ядра с периферийным блоком

Взаимодействие ядра МК с периферийным блоком осуществляется с помощью спецрегистров (есть еще взаимодействие через механизм прерываний и DMA, но об этом в следующих постах). С точки зрения ядра это просто участок памяти с определенным адресом, вот только на самом деле это не так. Запись данных в спецрегистр эквивалентна передаче команды или данных периферийному блоку. Считывание — получение данных от блока или считывание его состояния. Описание периферийных блоков и их спецрегистров занимает львиную долю описания МК.

ВАЖНО: После записи данных в спецрегистр и последующем чтении вы можете получить совершенно иные данные. Например, передача данных блоку UART для отправки, и считывание данных, полученных блоком от внешнего устройства, осуществляется с помощью одного и того же регистра.

Спецрегистры обычно разделены на битовые поля. Один (или несколько) бит управляют определенным параметром периферийного блока, обычно независимо. Например, разные биты одного регистра управляют состоянием разных выходов МК.

Вспоминаем С

Если вы гуру в языке C, то можете смело пропускать данный раздел. Он предназначен в первую очередь для тех, кого учили (или ктоучился сам) программировать для ПК. Опыт показывает, что люди часто не помнят важных команд. Здесь я вкратце напомню про побитовые операции и работу напрямую с памятью по ее адресу.

Запись данных по адресу в памяти

Предположим, что читая описание периферийного блока, мы поняли, что для его корректной работы необходимо записать в него число 0x3B. Адрес спецрегистра 0x60004012. Регистр 32-битный.
Если вы сразу не знаете как это сделать, попробую описать цепочку рассуждений для получения правильной команды.

Значение 0x60004012 есть не что иное, как значение указателя на ячейку памяти. Нужно именно это и указать в нашей программе, тоесть сделать преобразование типов согласно синтаксису языка C:

Таким образом, у нас есть указатель на элемент. Теперь нужно в этот элемент записать необходимое значение. Делается это разыменовыванием указателя. Таким образом получаем правильную команду:

Установка произвольных бит в 1

Обратите внимание на 2 факта. Биты считаются с нулевого, а не с первого. Данная операция на самом деле занимает неменее 3 тактов — считывание значения, модификация, запись. Иногда это не допустимо, поскольку между считыванием и записью значение одного из бит, которые нам запрещено изменять, могло быть изменено периферийным блоком. Незабывайте про эту особенность, иначе могут полезть баги, которые крайне сложно отловить.

Установка произвольных бит в 0

Или его более простою запись (не переживайте за лишнюю операцию, компилятор все заранее посчитает даже при минимальной оптимизации):

Некоторые особенности программ для МК

Приступаем к работе!

В первую очередь необходимо определиться с какими блоками предстоит работать. Для это достаточно изучит разделы Introduction и Main features.

Непосредственное управление состоянием пинов МК осуществляется с помощью блока GPIO. Как указано в документации в МК STM32 может быть до 11 независимых блоков GPIO. Различные периферийные блоки GPIO принято называть портами. Порты обозначаются буквам от A до K. Каждый порт может содержать до 16 пинов. Как мы отметили ранее, светодиод подключается к пину PD13. Это означает, что управление этим пином осуществляется периферийным блоком GPIO порт D. Номер пина 13.

Ни каких других периферийных блоков на это раз нам не понадобится.

Управление тактированием периферийных блоков

Теперь необходимо разобраться с тем, как узнать адрес самого регистра RCC_AHB1ENR.

Замечание: Описание системы тактирования МК STM32 достойно отдельной статьи. Если у читателей возникнет желание, я подробнее освещу этот раздел в одной из следующих статей.

Определение адресов спецрегистров


Определение адресов спецрегистров необходимо начинать с чтения раздела Memory map в Reference manual. Можно заметить, что каждому блоку выделен свой участок адресного пространства. Например, для блока RCC это участок 0x4002 3800 — 0x4002 3BFF:

Перейдя по ссылке к Register map блока RCC находим строчкку с интересующим нас регистром RCC_AHB1ENR:


Для получения адреса регистра, необходимо к начальному значению адресного пространства блока RCC прибавить Addr. offset нужного регистра. Addres offset указывается и в описании регистра (см. скриншот выше).

В итоге, мы определили адрес регистра RCC_AHB1ENR — 0x4002 3830.

Блок GPIO

Для общего ознакомления с блоком GPIO я настоятельно рекомендую полностью прочитать соответствующий раздел Reference Manual. Пока можно не особо обращать внимание на Alternate mode. Это оставим на потом.

Сейчас же наша задача научиться управлять состоянием пинов МК. Перейдем сразу к описанию регистров GPIO.

Режим работы

В первую очередь необходимо установить режим работы 13 пина порта D как General purpose output mode, что означает что блок GPIO будет управлять состоянием пина МК. Управление режимом работы пинов МК производитсяс помощью регистра GPIO port mode register (GPIOx_MODER) (x = A..I/J/K):


Как видно из описания для совершения требуемой нам настройки необходимо записать значение 01b в 26-27 биты регистра GPIOx_MODER. Адрес регистра можно определить тем же методом, что описан выше.

Настройка параметров работы выходных пинов порта GPIO
  • GPIO port output type register (GPIOx_OTYPER) — задается тип выхода push-pull или open-drain
  • GPIO port output speed register (GPIOx_OSPEEDR) — задается скорость работы выхода
Установка значения на пине МК

Наконец-то мы подошли к моменту управления состоянием выхода МК. Для утановки выходного значения на определенном пине МК есть два метода.

Используем регистр GPIO port bit set/reset register (GPIOx_BSRR)


GPIO port bit set/reset register (GPIOx_BSRR)


Зажигаем светодиод!

Найдя адреса всех необходимых регистров, можно написать программу, которая включает светодиод:

Можно компилировать (Project->Compile) и заливать (Project->Download->Download active application). Или запустить отладку (Project->Dpwnload and Debug) и начать выполнение (F5).
Светодиод загорелся!

Мигаем светодиодом

Мигание светодиода есть ни что иное, как попеременное включение и выключение с задержкой между этими действиями. Самый простой способ — поместить включение и выключение в вечный цикл, а между ними вставить задержку.

Значение 1000000 в задержке подобрано экспериментально так, чтобы период мигания светодиода был различим глазом, но и не был слишком велик.

Оптимизируем алгоритм

Минусом выбранного подхода миганием светодиодом является то, что ядро МК большую часть времени проводит в пустых циклах, хотя мог бы заниматься чем-нибудь полезным (в нашем примере других задач нет, но в будущем они появятся).

Для того, чтобы этого избежать, обычно используется счетчик циклов, а переключение состояние пина МК происходит при прохождении программы определенного числа циклов.

Но и тут не обойдется без проблем, с изменением количества команд выполняемых внутри цикла, будет меняться период мигания светодиодом (или период выполнения других команд в цикле). Но на данном этапе мы не можем с этим бороться.

Немного об отладке

IAR позволяет осуществлять отладку приложения непосредственно в железе. Все выглядит практически так же, как и отладка приложения для ПК. Есть режим пошагового выполнения, входа в функцию, просмотр значения переменных (В режиме отладки View->Watch->Watch1/4).


Но помимо этого, присутствует возможность просмотра значений регистров ядра, спецрегистров периферийных блоков (View->Register) и т.п.
Я настоятельно рекомендую ознакомиться с возможностями дебаггера во время изучения программирования МК.

Несколько слов в заключение

  • В библиотеках от производителя иногда встречаются ошибки! Я один раз чуть не сорвал срок проекта из-за этого. Несколько раз перепаивал чип, думая, сто повредил кристалл при пайке (до этого такое случалось). А проблема заключалась в том, что в библиотеке был неверно прописан адрес спецрегистра. Обычно такое случается с МК или линейками МК только вышедшими на рынок.
  • Библиотеки для работы спериферией некоторых производителей не реализуют всех возможностей периферийных блоков. Особенно этим грешилb Luminary Micro, которых в последствии выкупили TI. Приходилось писать инициализацию периферии вручную.
  • Многие привыкают начинать программирование МК с изучения примеров. Я считаю, что сперва необходимо определиться с тем, что позволяет реализовать МК. Это можнопонять только прочитав документацию. Если чего-то нет в примерах, это не значит, что железоэто не поддерживает. Последний пример — аппаратная поддерка PTP STM32. В сети, конечно, можно кое-что найти, но это не входит в стандартный набор от производителя.
  • Драйверы периферийных блоков некоторых производителей настолько не оптимизированы, что на переключение состояния пина средствами библиотеки тратится до 20 тактов. Это непозволительная роскошь для некоторых задач.

Спасибо всем, кто прочитал мой пост, получилось значительно больше чем я ожидал в начале.
Жду ваших комментариев и аргументированной критики. Если у прочитавших возникнет желание — постараюсь продолжить цикл статей. Возможно у кого-то есть идеи по поводу тем, которые стоило бы осветить — я был бы рад их услышать.

Автор: Артюгина Ольга Анатольевна

Населенный пункт: Московская область, г. Ивантеевка

Ребёнок с интересом познаёт окружающий мир. Его волнует множество вопросов: Что такое лампочка, которую можно включить, когда нам нужно. Детям интересно от чего же все, таки загорается лампочка.

Навыки, умения, приобретенные ребенком в дошкольный период, будут служить фундаментом для получения знаний и развития способностей в старшем возрасте – в школе.

Мой путь в педагогике – это постоянный поиск, это счастливые находки и желание поделиться педагогическим опытом с другими. Поэтому большое внимание уделяю изучению инновационных технологий, нетрадиционных форм работы и современных методов обучения и воспитания. Все свои знания, умения и навыки, весь свой талант я отдаю своим воспитанникам, и вместе с ними частичка меня остается в каждом ребёнке.


А так почитайте инструкции по этим помпам и контроллерам, чтобы понять отличие.

Во многих темах, если не во всех, советуют помпы Тюнз, а других словно не существует.

Тюнз настолько лучше остальных или. просто раскрученный бренд?

А кто на втором месте по качеству, если Тюнз на первом? (если это вообще так..)

В настоящем море, насколько я знаю, течение не постоянное (как мы часто делаем в банках своих), а имеет волновой тип, т.е. почти спокойствие сменяется очень сильным течением. Ни то ни другое не подходит в аквариуме, поэтому подбирается среднее течение и делается постоянным.

Следует ли заморачиваться и устраивать волновое течение? Если стОит, то как это сделать? Можно ли поставить несколько помп и воткнуть их в таймер, таймер установить на вкл/выкл=5минут. Т.е. то одна помпа работает, то другая, каждая по 5 минут. Если так неправильно, то как правильно.

На самом деле, помп довольно большое количество. Есть из чего выбрать. Тюнзовские помпы почти в каждой банке потому что это самое лучшее соотношение цена/качество. Относительно не дорогие, различных модификаций, без шумные, долго работающие. При помощи них есть возможность моделировать любое течение. Не надо ничего мудрить с таймерами. Для тюнзовских помп есть тюнзовские же контроллеры, при помощи которых помпу можно заставить работать на постоянной, любой мощности. Либо настроить в режиме волны, или задать по переменное включение.

Если чем то помпы тюнз не устраивают, можно выбрать любые другие.

Все началось в океане

Какого размера у вас аквариум?

120х55х55 моя баночка

Быстро в море происходит только плохое, для хорошего нужно время и терпение.

Второй частью своего поста Вы сами ответили на свой вопрос.

На самом деле, помп довольно большое количество. Есть из чего выбрать. Тюнзовские помпы почти в каждой банке потому что это самое лучшее соотношение цена/качество. Относительно не дорогие, различных модификаций, без шумные, долго работающие. При помощи них есть возможность моделировать любое течение. Не надо ничего мудрить с таймерами. Для тюнзовских помп есть тюнзовские же контроллеры, при помощи которых помпу можно заставить работать на постоянной, любой мощности. Либо настроить в режиме волны, или задать по переменное включение.

Если чем то помпы тюнз не устраивают, можно выбрать любые другие.

Это тот самый контроллер, который почти 20 т. р. стоит?))) Именно поэтому я и выдвинул желание заморочиться с таймерами, получается намного дешевле) Но. дешевизна кажущаяся поначалу зачастую оборачивается грустными последствиями потом.

А чем принципиально этот контроллер, который делает попеременное включение помп, отличается от попеременного включения с помощью таймеров?

Допустим, имеется помпа 6045, она только в ручную регулируется на блоке - регуляторе мощности. Я так понимаю, что контроллер для помп тюнз можно купить, который регулирует и попеременное их включение и при этом может мощность их (в определённое время или как?) изменять? Или это уже разные контроллеры?


Новый год уже скоро, поэтому самое время подумать о праздничном освещении. Сегодня я хочу показать, как с помощью дешевого микроконтроллера и хитрой прошивки можно сделать веселее даже самую скучную статичную светодиодную гирлянду.

Исходные данные

У меня скопилось великое множество самых разных гирлянд, среди них есть как простые советские на лампочках, так и модные нынче на адресных светодиодах. Когда играться с режимами последних мне надоело, я пришел к выводу, что это все баловство, и самый оптимальный вариант гирлянды — это та, которую включил один раз и забыл. Самыми удобными мне показались USB гирлянды на 30-40 лампочек длиной 4-6 метров. Они недорого стоят, их удобно хранить за счет небольшой длины и можно воткнуть куда угодно, т.к. потребление у них мизерное. Единственный минус — такие гирлянды в основном абсолютно статичны, т.е. при работе просто светятся и не имеют никаких спецэффектов. Еще в прошлом году я заказывал сразу кучу разных USB гирлянд, среди них мне больше всего понравились такого типа:

Заказывал здесь. Это примитивная гирлянда на 30 светодиодов длиной 4.5 метра, которая питается от любого USB порта и во время работы просто светится по всей длине:

В ней чередуются светодиоды 4х цветов: красного, желтого, зеленого и синего. Есть и варианты с просто белыми/теплыми вариантами светодиодов:

На странице лота есть и вариант с батарейным питанием, причем он отличается наличием мигающего режима (мигает просто вся гирлянда). Такая у меня тоже есть, и у нее имеется большой минус: она очень быстро теряет яркость по мере просадки батареек. При всей своей тупой примитивности в техническом плане эти гирлянды все же имеют свой некий шарм за счет интересных рассеивателей:

Они сделаны из прозрачной эпоксидки и наполнены пузырьками, на которых красиво рассеивается свет, создавая эффект шара со снежинками:


В техническом плане гирлянда ничего сложного и интересного не представляет, на конце обычный USB разъем со встроенной в него парочкой гасящих резисторов:

А все светодиоды подключены параллельно, на всю длину гирлянда имеет всего 2 провода:

Потребляет это поделие всего 90мА, поэтому его можно питать от любого подвернувшегося USB порта:

Я, например, втыкаю свои в порты телевизора, ТВ приставки, в старые ненужные зарядники от телефонов — везде работает отлично.

Теория


Несмотря на то, что провода в данной гирлянде всего 2, мы с помощью хитрости можем заставить ее мигать двумя группами светодиодов независимо друг от друга. Хитрость эта называется Charlieplexing, и ей уже сто лет в обед. Заключается она в том, что можно подключить светодиоды разной полярностью к общей шине и управлять ими отдельно с помощью изменения полярности на шине:

Особенно легко это делать при помощи микроконтроллера: подаем на вход X1 логическую единицу, на X2 — ноль, в итоге горит LED1. Инвертируем (X1 — ноль, X2 — единица) — горит LED2, таким образом мы имеем возможность по всего двум проводам независимо управлять двумя отдельными светодиодами. Если переключать выходы с большой частотой, по визуально будут гореть оба светодиода, причем с помощью изменения длины периода можно менять и яркость, т.е. это фактически обычный двухполярный ШИМ. На самом деле Чарлиплексинг не ограничивается двумя светодиодами, это для него вообще самый примитивный случай. Обычно в реальности эта техника используется для управления всякими матрицами светодиодов с использованием сильно меньшего количества пинов микроконтроллера. Но у такого подхода есть существенный минус: мерцание и падение яркости с ростом количества коммутируемых светодиодов, от этого никуда не деться.

Практика


Для управления светодиодами будем традиционно использовать микроконтроллер ATiny13, причем питать светодиоды мы будем напрямую с пинов контроллера, а для повышения максимального отдаваемого тока мы запараллелим по паре пинов. О допустимости такого подхода ходят споры, но на деле лично я проблем никогда не замечал, по моему опыту этот МК вообще нереально убить практически ничем. Каждый пин t13 может отдавать до 20мА, для двух пинов получаем до 40мА, чего должно быть достаточно для питания половины гирлянды почти без потери яркости (т.к. вся она потребляет 90мА, см. выше). Общая схема:

Здесь C1 — конденсатор на 0.1-1 мКф, R1 — резистор на 10-20 Ом. Питать напрямую от МК можно гирлянду длиной 15-30 светодиодов, не больше. Для гирлянд большей длины придется городить усилитель на полевиках, что-то типа такого:

Результат

  • Автоматический — в нем все мигающие режимы переключаются по кругу через определенный интервал времени
  • Статический — горят все диоды одновременно, как было изначально
  • 9 видов мигалок, у каждой из которой есть 3 скорости (медленно, средне, быстро)

Итак, предлагаю посмотреть, как работают всякие мигалки.
Самая первая — просто мигание всеми светодиодами одновременно:

Далее идет поочередная мигалка:

Плавная мигалка всеми светодиодами:

Плавная поочередная мигалка:


Описанным образом можно оживить практически любую статичную гирлянду, если в ней не очень много светодиодов. Хотя на рынке в наши дни полно готовых гирлянд и контроллеров к ним, на сделанную своими руками смотреть гораздо приятнее)

Читайте также: