Теория http://myowndevice.ru Wed, 28 Aug 2024 12:10:22 +0000 Joomla! - Open Source Content Management ru-ru От идеи до прибора /index.php/theory/item/3-ot-idei-do-pribora /index.php/theory/item/3-ot-idei-do-pribora

В данной статье мы расскажем как пользоваться сайтом и зачем делать приборы самому, какие приборы мы будем делать. Также рассмотрим основные ограничения домашнего производства. Добро пожаловать в мир электроники.

Читать обязательно!

{index}

В наше время очень много информации в интернете посвящено «Arduino» и другим подобным платам. Для Arduino выпускаются много различных готовых модулей. Мы же будем учиться делать приборы из самых хороших модулей — микросхем!


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

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



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

Если у вас есть собственные приборы — присылайте нам - мы сделаем их доступными всем. Наш девиз — не покупай не нужную электронику — лучше сделай сам. Opensource в программирование — open hardware в приборостроении.

Как пользоваться сайтом

Сайт делится на два больших раздела: Теория и Приборы.

Раздел Теория обязателен к прочтению. Сведения приведённые в этом разделе не повторяются в статьях о приборах и предполагается, что вы освоили необходимые статьи теории.

Раздел Приборы содержит все приборы размещённые на сайте. Каждый прибор содержит ссылки на разделы теории, которые необходимы для его реализации. Рекомендуется прочитать их еще раз перед изготовлением прибора. Везде, где это возможно прилагается открытый исходный код — который вы можете модернизировать под свои нужды. Все чертежи, схемы, платы можно скачать. В каждой статье про прибор есть самостоятельные задания - очень рекомендуем их сделать — это повысит ваш уровень знаний — ЛУЧШЕ самостоятельной практики ничего нет.

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

Зачем делать приборы самому?

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

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

На текущий момент более 60% всех электронных устройств которые нас окружают можно произвести в домашних условиях. Имея компьютер, в них можно заложить необходимые функции путем программирования. Грамотно подбирая компоненты можно получить более качественные устройства чем есть на рынке, более дешевые, обладающие нужными функциями.

Таким образом, первый ответ на вопрос — чтобы получить прибор с нужными параметрами.

Для того чтобы сделать прибор необходимо обладать многими навыками — уметь программировать, уметь паять, уметь читать и составлять электрические схемы, уметь разрабатывать печатные платы, быть дизайнером.

Второй ответ на ответ вопрос - научится всем этим навыкам. Знания — сила.

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

Третий ответ на вопрос — лучше разбираться в предлагаемых на рынке изделиях и делать правильный выбор при покупке готовых изделий.

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

На этой позитивной ноте начнём погружение.

Какие приборы мы будем делать?

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

Все приборы, которые мы будем делать достойны производства и выглядят как законченные изделия - имеют корпус, кнопки, современную начинку — li-ion аккумуляторы, различные высокоточные датчики, современный функционал. Делая каждый прибор, вы постигаете различные навыки, методики и осваиваете разные стороны приборостроения. Пользуясь ими, вы видите все их минусы и недостатки. Только так можно сделать качественную вещь.

Каждый прибор мы будем разбирать максимально подробно — от идеи и его основных функций - до конечного вида. Именно в этом направлении должны идти и ваши мысли. Читая статьи, у вас будет складываться правильная модель мышления, и этот процесс в дальнейшем позволит вам реализовывать самые смелые идеи — быстро, качественно, эффективно.

Каждый прибор — это опыт. Каждый необходимо сделать — пощупать, увидеть, попробовать на зуб. Собирая устройство — вы проходите весь цикл от идеи до конечного вида. Понимаете как удобнее делать плату в будущем, где размещать разъёмы, как правильно организовать питание. Пройти этот путь только в теории невозможно. Только когда вы сами начнёте пользоваться прибором — придут мысли как его сделать лучше. Даже если предложенный прибор кажется не интересным, не нужным — все равно его надо сделать, и например, подарить другу (подруге) — мало ли применений можно найти. Опыт, который вы получите — стоит очень дорого — его нельзя купить — его надо заработать.

Ограничения домашнего производства

В настоящее время электронные приборы достигли очень высокой сложности. Например процессор в ноутбуке имеет более 1000 выводов и при этом размер 3х3 см. Работать с такими элементами в домашних условиях не возможно.

Основное ограничение домашнего производства — это печатная плата. Конечно его можно обойти — и заказать печатные платы на заводе. Но к сожалению сделать печатные платы в России очень дорого, в Китае — долго ждать. Так что, мы ограничимся домашними печатными платами. Какую же печатную плату можно сделать дома:

  • двух сторонние платы

  • толщина дорожек — 0.2 мм

  • расстояние между дорожками — 0.2 мм

  • диаметр переходного отверстия — 1.4мм - а лучше 1.6мм

  • расположение переходных отверстий не под компонентами

Второе не маловажное ограничение — это размер компонент и корпуса микросхем. В домашних условиях можно паять паяльником следующие корпуса элементов:

  • SSOP

  • QFP

  • резисторы и кондецаторы лучше не меньше 0603 — хотя можно 0402

  • все выводные компоненты - DIP корпуса

  • естественно корпуса большего размера

С помощью паяльного фена можно запаять корпуса:

  • QFN

  • LGA (однорядные)

Практически не реально паять корпуса:

  • BGA

  • многорядные LGA

Итак, практически все можно паять кроме многорядных корпусов. Вот наши «враги»:


А это наши друзья (их гораздо больше) :


Таким образом можно паять практически все однорядные копоненты. Например очень легко запаивается датчик УФ (он у нас будет в приборах) размером 2х3 мм VEML6075, увеличенно смотрится ничего так себе

а вот его размер на плате:

когда его берёшь в руки немного страшно — зато когда он работает — дух захватывает.

Также хочется отметить, что практически не реально в домашних условиях делать высокочастотные платы — с частотой больше 1 ГГц. Это как правило радио передатчики и приемники на частоте 2.4 ГГЦ например (можно только брать готовые модули). Также все возможные ТВ приставки, тюнеры, радио усилители и частотные фильтры, работа с памятью DDR2 и т.д.. Все это требует специального оборудования для настройки, сложного расчёта при проектировании плат — необходимо учитывать емкости и импеданс переходных отверстий и дорожек.

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

Какие микроконтроллеры мы будем использовать

Так как мы будем учиться делать приборы, то важно сразу усвоить простую истину — не надо ни в коем случае себя ограничивать каким то одним микроконтроллером. Многие пишут — ATMEGA от ATMEL — лучшие микроконтроллеры. Другие — STM32 — самые мощные и дешевые. Наша основная задача сделать прибор — дешевый, компактный и т. д. И мы будем выбирать микроконтроллер под прибор. В каких то приборах лучше использовать ATMEGA, в каких то STM32, где то NPC, где то NUVOTON.

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

  • Stm8

  • ATMEGA

  • Nuvoton

  • Stm32

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

Начнём мы с самых недорогих и довольно мощных микроконтроллеров — STM8S003. Первые проекты будут именно на этом микроконтроллере. Почему именно он?

  • Цена — он очень дешевый, не жалко испортить

  • У него отличный для ручной пайки корпус — TSSOP20

  • Минимальная обвязка для работы — пару конденсаторов и все

  • Он имеет отличный программатор, отладчик — который мы сами сделаем (STLink)

  • Среда программирования имеет симулятор — что иногда очень полезно

  • У него не плохие параметры — широкий выбор напряжения — от 3в до 5в, высокая частота — до 24Мгц, широкая периферия UART, SPI, I2C, ADC

  • Различные режимы энергопотребления — в том числе спящий режим с потреблением 5мкА

В дальнейшем в более сложных приборах — будут очень мощные микроконтроллеры. Например в Квадрокоптере будем использовать STM32F405 — 1024kB FLASH, 192kb RAM, частота 168Мгц, FPU модуль.

Основные стадии разработки прибора

При разработке любого прибора мы будем проходить следующие основные стадии. Перечислим их здесь и разберём для чего они нужны.

Стадия

Зачем нужна

Функциональное ТЗ

Самая главная стадия — необходимо составить перечень требований к прибору. Выделить его основные функции, второстепенные.

Подбор датчиков и модулей (например GPS GSM RF BlueTooth)

Выбор основных датчиков. Моделирование работы датчиков на макетных платах и т. д. Итог — выбранные датчики.

Разработка интерфейса

Выбор интерфейса взаимодействия. Кнопки, Выключатели, Экран, светодиоды, пищалки, bluetooth и другие варианты взаимодействия.

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

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

Выбор источников и схемы питания

Выбор питания — аккумулятор или БП, выбор основных уровней питания, подбор LDO или DC\DC микросхем, подбор схема защиты по питанию, модель согласования уровней.

Разработка схемы

Сведение в общую схему всем подобранных компонент с учетом требований datasheets.

Подбор разъёмов и кнопок и размера платы

По сути тут необходим подбор всех посадочных мест компонентов — они определяют размер платы. Необходимо выбрать все кнопки, выключатели, определится с их местоположением. Подобрать все разъемы.

Корпус

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

Разработка платы под выбранный корпус

Трассировка платы. На этом этапе важно учесть все ограничения корпуса. Крепежные отверстия, расположение выключателей и кнопок. Расположение индикаторов и дисплея.

Изготовление

На этом этапе можно считать конструкторская часть закончена — осталось все запять и собрать.

Исправление мелких ошибок

Проверка прибора. Тут могут обнаружиться мелкие недоработки. Заменить резистор, забыли дорожку, добавить резистор — это можно смело делать — необязательно все переделывать.

Программирование

Первым делом необходимо проверить, что все датчики отвечают на запросы, выдают результаты. Ну и потом уже пишем полный код, постепенно проверяя результаты — пока не получится версия 1.0

Тестирование и доработка

Версия 1.0 есть — пора ее использовать в деле. Ну и как обычно писать версию 2.0

 

Ну что же - теперь мы можем начать. Пройдём все эти стадии на практике.

]]>
(Super User) Теория Sat, 08 Jul 2017 18:42:00 +0000
Составляем требования к прибору /index.php/theory/item/21-sostavlyaem-trebovaniya-k-priboru /index.php/theory/item/21-sostavlyaem-trebovaniya-k-priboru

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

{index}

Функциональные требования

Еще когда прибор только родился в голове возникает много мыслей — какой он будет красивый, маленький, удобный и столько всего уметь. Вот сразу на этом моменте надо начать записывать эти самые мысли. Чем больше вы сразу запишите, тем проще потом будет в разработке. Рассмотрим какие могут возникать требования к будущему прибору.

Все требования можно разделить на следующие категории:

  • Основные функции

  • Питание

  • Интерфейс общения

  • Чем будем управлять

  • Измеряемые показатели, используемые датчики

  • Расширение функций (шины данных, разъемы)

  • Корпус

  • Прочее


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

Основные функции

Представьте, что вы пытаетесь продать прибор — что вы про него расскажите. Вы перечислите ключевые функции, которые он умеет делать, ну и конечно его ключевые преимущества относительно существующих аналогичных приборов. Вот эти ключевые функции и надо перечислять в этом пункте. Это должны быть именно простые слова, через запятую например:

  • измерение скорости;

  • хранение измерений за год;

  • замер расстояния;

  • ведение лога на компьютере;

  • работа с программой XYZ;

  • точность +/- 0.1градус

Если вы делаете сложный прибор, выполняющий много функций — то это могут быть названия готовых существующих приборов:

  • кухонный таймер;

  • телефон;

  • будильник.

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

Питание

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

От сети

  • Домашняя сеть 220в.

  • Генератор в машине

  • Бензиновый генератор

  • 380В трехфазное напряжение

Автономное питание

Какой тип автономного питания:

  • батарейка, если определена типоразмер, например 2 батарейки AAA

  • аккумлятор, если это определено — типа аккумулятора

  • солнечные батареи

  • химическая реакция

Все, что связано со сменой питания или поддержание его в рабочем состоянии:

  • Будет ли заряжаться аккумулятор

  • От чего будет заряжаться, какой разъем или прибор

  • Как быстро он должен заряжаться

Как долго должен работать прибор на одном заряде (одном комплекте батареек).

Наличие анализатора разряда батарейки.

Смешанное

Система с резервным питание от акумулятора — бесперебойная работа устройства.

Особое

  • Питание от радиоимпульсов.

  • От тела человека.

Интерфейс общения

Это довольно объемный и самый сложный раздел. Здесь необходимо описать все схемы взаимодействия прибора с внешним миром.

Взаимодействие с человеком

  • Первое что тут необходимо описать - собственно все кнопки, рычажки, крутилки

  • Звуковое воздействие — пищалки, динамики, пьезодинамики, микрофоны

  • Зрительное — светодиоды, индикаторы цифры, различные дисплеи — LCD, TFT и другие

Необходимо максимально подробно продумать какие будут элементы. Как они будут работать. Сколько будет кнопок и зачем они будут нужны. Какая информация будет выводиться на экран. Что будет выводиться на индикаторы. Когда и зачем будет пищать динамик. Что будет говорить прибор.

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

Взаимодействие с другими приборами

Здесь необходимо перечислить какие внешние протоколы будет поддерживать прибор. Какие внешние модули будут к нему подключаться. Например, это может быть возможность подключения любого количества датчиков температуры по протоколу 1 wire. Или работа с датчиками I2C. Например наличие внешних портов — UART, SPI , I2C, CAN. Что планируется подключать по этим протоколам, какие модули.

Чем будем управлять

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

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

Измеряемые показатели, используемые датчики

Как правило, во всех приборах есть какие-то датчики. Здесь необходимо их описать. Какая точность вам от них нужна. Какое энергопотребление данных датчиков. С какой частотой они должны передавать данные.

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

Безусловно датчик определяет ваш прибор. К его выбору надо относится очень серьезно. Не правильный выбор датчика приведет к переделке всего прибора.

На этапе выбора датчика очень помогает макетирование на различных платах вида Arduino и других.

Корпус

Корпус самая сложная часть вашего прибора. Если вы посмотрите на все продаваемые приборы, то они имеют уникальный корпус. Над ним очень долго работал дизайнер, его отдельно выпускают на заводе под данную серию прибора. К сожалению, при домашнем производстве это невозможно (или не рентабельно). Остается выбор — подобрать корпус из готовых, которые широко продаются на рынке, или распечатать его на 3D принтере. К сожалению прочность корпуса на 3D принтере не высокая, а также бывает необходимость сделать корпус из металла, силикона и других материалов — их нельзя распечатать.

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

Обязательно необходимо продумать ключевые требования к корпусу:

  • герметичный

  • размеры

  • материал

  • разборный или нет

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

Прочее

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


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

]]>
(Super User) Теория Mon, 11 Sep 2017 19:56:15 +0000
Kicad - программа трассировки плат /index.php/theory/item/13-kicad-programma-trassirovki-plat /index.php/theory/item/13-kicad-programma-trassirovki-plat

В данной статье мы подробно рассмотрим как работать в Kicad — замечательной программе для трассировки плат. Рассмотрим вариант ручной и автоматической трассировки. Подробно рассмотрим основной цикл работы в этой программе.

Читать обязательно!

{autotoc}

Зачем нужна эта программа?

KiCad — распространяемый по лицензии GNU GPL программный комплекс класса EDA с открытым исходным кодом, предназначенный для разработки электрических схем и печатных плат.

Кроссплатформенность компонентов KiCad обеспечивается использованием библиотеки wxWidgets. Поддерживаются операционные системы Linux, Windows NT 5.x, FreeBSD и Solaris.

KiCad состоит из следующих компонентов:

  • kicad — менеджер проектов;

  • eeschema — редактор электрических схем;

  • встроенный редактор символов схем (библиотечных компонентов);

  • pcbnew — редактор печатных плат;

  • встроенный редактор образов посадочных мест (библиотечных компонентов);

  • 3D Viewer — 3D-просмотрщик печатных плат на базе OpenGL (часть pcbnew);

  • gerbview — просмотрщик файлов Gerber (фотошаблонов);

  • cvpcb — программа для выбора посадочных мест, соответствующих компонентам на схеме;

  • wyoeditor — текстовый редактор для просмотра отчётов.

 

eeschema обеспечивает:

  • создание однолистовых и иерархических схем,

  • проверку их корректности ERC (контроль электрических правил),

  • создание списка электрических цепей netlist для редактора топологии платы pcbnew или для Spice-моделирования схемы,

  • доступ к документации на используемые в схеме электронные компоненты (datasheet).

pcbnew обеспечивает:

  • разработку плат, содержащих до 16 слоёв меди и до 12 технических слоёв (шелкография, паяльная маска и т. п.),

  • выход на внешние трассировщики соединений посредством генерации описания платы на Specctra Design Language (on-line FreeRoute и др.),

  • генерацию технологических файлов для изготовления печатных плат (Gerber-файлы для фотоплоттеров, файлы сверловок и файлы размещения компонентов),

  • послойная печать схем и чертежей печатных плат на принтере или плоттере (в форматах PostScript, HPGL, SVG и DXF), с рамкой формата или без неё.

gerbview позволяет просматривать Gerber-файлы.

В составе KiCad поставляются библиотеки электронных компонентов (как обычных выводных, так и поверхностно монтируемых SMD). Для многих библиотечных компонентов есть 3D-модели, созданные в Wings3D.

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

Какие есть альтернативы? Почему Kicad?

Очень распространены следующие программные продукты:

  • Sprint Layout

  • EagleCAD

  • EasyEDA

  • Proteus

  • DipTrace

  • Altium

Сейчас активно начинается использоваться на десктопе Linux. Хотелось выбрать софт, который бы работал и в linux и в windows. Под linux работают Kicad и Eagle. Kicad больше понравился. Он более компактный, быстрее работает, симпатишный — по домашнему. Все схемы и платы на этом сайте будут в Kicad. Рекомендуем вам его освоить и пользоваться им. Продукт полностью бесплатный, легкий в освоении, имеет документацию на русском (ссылка) и английском языках. В интернете очень много различных видео уроков.

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

Как делается плата с помощью компьютера?

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


назначается посадочное место — отображение контактов к которым припаивается компонент.

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

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

В Kicad очень большая стандартная библиотека, а также очень много дополнительных библиотек в интернет. То что найти не удалось не сложно сделать самостоятельно в специальном редакторе.

Порядок работы в Kicad

Мы будем использовать следующий порядок работы в этом программном продукте:

  1. В редакторе схем чертим необходимую схему, если нет каких то компонентов — то делаем их и заносим в библиотеку.

  2. Назначаем посадочные места — если каких то нет, чертим и заносим в библиотеку.

  3. Формируем файл соединений

  4. Загружаем файл в редактор печатной платы

  5. Автоматически размещаем компоненты, чтобы их было все видно рядом

  6. Создаем привязки к корпусу (если он выбран и уже есть его чертеж)

  7. Растаскиваем ключевые компоненты — разъемы, выходы питания и т.д — те места которые заранее определены

  8. Растаскиваем сложные компоненты — микроконтролллеры и другие микросхемы

  9. Соединяем дорожками обязательные компоненты — цепи питания,кварцы

  10. Соединяем ножки микроконтроллера и других многоногих микросхем — тут как правило возникают перестановки ног — их отражаем на схеме — обновляем плату и соединяем финально

  11. Удаляем все соединения и рисуем заново начистую — или удаляем часть соединений

  12. Периодически можно пользоваться автороутером — чтобы понять основные маршруты.

  13. Финально размечаем полигоны — как правило земляные.

 

Рассмотрим подробнее каждый пункт. Если вы еще не читали документацию, то самое время ее прочитать.

Чертим схему прибора

Первым делом необходимо убедится, что все необходимые элементы схемы у нас есть в библиотеках. Как правило, при создании проекта подключены не все имеющиеся библиотеки. Нужно добавить необходимые. Делается это через меню Настройки-Библиотеки компонентов — Добавить — ну и выбираем нужные компоненты.

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


Если элемента все таки нет — надо его нарисовать. Для этого надо вернуться в менеджер приложений и выбрать Редактор библиотеки компонентов:


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


При нажатии по этой кнопке создается файл библиотеки с новым элементом внутри — лучше это сразу сделать в специальной папке, например C:\KikcadLib. После создания новой библиотеки, ее надо подключить к проекту через настройки — библиотеки компонентов — Добавить созданный файл.

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

задаем его название (лучше как в datasheet), и далее добавляем нужные выходы:

В конце можно нарисовать рамку границы элемента — красивый квадратик. На этом все — элемент готов. Жмем Обновить текущий компонент в текущей библиотеке (или сохранить текущий компонент в новой библиотеке)

После этого сохраняем текущую бибилиотеку. Теперь элемент можно использовать в схемах. Вот пример новоиспеченного элемента:


Все элементы найдены или созданы — рисуем схему. Проще всего сразу подготовить базовые компоненты — резисторы, транзисторы, кондецаторы, которых будет много. Настроить их посадочные места по кнопке E. Потом просто надо будет их копировать и все. Лучше сразу запомнить горячие кнопки — их не много.

  • C — копировать компонент — в процессе копирования можно сразу вращать элемент и использовать другие горячие кнопки

  • R — повернуть компонент на 90 градусов

  • M — передвинуть компонент, G — передвинуть сохраняя связи проводов (на самом деле лучше не использовать, провода начинают жутко накладываться, проще их перерисовать)

  • Y, X — отразить компонент зеркально

Все они также доступны по правой кнопке мыши.

Соединять схемы проводами особенно нет смысла, лучше всего это использовать только для небольших соединений, которые однозначно понятны. Во всех остальных случаях лучше использовать метки. Меткам лучше давать понятные имена — при трассировке платы их также будет видно. Метки очень удобно переносить на другие выводы разъема или микроконтроллера - быстро меняя схему. Для питания лучше использовать не метки, а стандартные элементы питания (порт питания), хотя опять же разницы тут нет — все это элементы оформления. С точки зрения схемы важно какие номера выводов элементов с какими другими номерами соединены. Kicad также умеет проверять корректность схемы(инструменты — проверка электрических правил), но для этого надо правильно описывать выходы, для небольшой схемы это не нужно.

Если вдруг в библиотеке нет какого – то разъема, то тоже не беда — используем стандартный разъем из библиотеки conn — conn_(нужное количество выводов):


Им можно отображать любой разъем — по сути важна только нумерация выходов.Но если есть готовый — например USB, лучше использовать его.

Если вдруг вам не хватает места — просто надо изменить размер листа на А3 например, вряд ли вы будете печатать схему. По сути схема нам нужна только для корректных связей на печатной плате. Конечно лучше ее чертить красиво — но это не обязательно. Пример готовой схемы:

 

 

 

Назначаем посадочные места

Прежде чем назначать посадочные места надо проверить все ли у вас они есть в библиотеках. Для этого надо познакомися с базовыми библиотеками — открываем редактор посадочных мест и там нажимаем просмотр — и смотрим какие есть библиотеки и т. д.

Если нужного элемента нет — можно попробовать найти его в интерент — набираете название модуля, микросхемы, корпуса и если такой есть, скачиваете файл формата «.Kicad_mod». Чтобы добавить его в проект надо создать библиотеку посадочных мест — в kicad это просто папка которая в названии имеет «.pretty». Создаем такую папку (лучше в нашей папке C:\Kicadlib), кладем туда скачанный файл и добавляем папку в глобальный список библиотек в редакторе посадочных мест по кнопке Настройки — Мастер библиотек посадочных мест.

Если в инернет ничего не нашли, то можно нарисовать самостоятельно. Сложного тут ничего нет — по сути обычный редактор плат, только рисуем не плату — а размещаем выводы — контактные площадки — задаем их номера и тип (SMD или нет), круглые, квадратные и т. д.

Запускаем редактор посадочных мест. Нажимаем для создания нового места:


И создаем новый элемент. Далее нажимаем добавить контактную площадку:


Задаем ее тип, размеры, координаты по кнопке E. Следующие площадки будут созданы как копия предыдущей. Для точного размещения надо пользоваться координатами центра площадки. Соответственно, если вы разместите первую площадку в координатах 0,0 — то будет не сложно расчитать нужные размеры.

По окончанию — выбираем Файл — Экспорт посадочного места - и сохраняем файл посадочного места в папке нашей библиотеки.

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

Теперь когда все посадочные места определены необходимо их назначить всем элементам схемы. Проще всего это сделать в специальной форме. В редакторе схем нажимаем Инструменты — «Назначить посадочные места компонентам». Здесь будут видны все компоненты схемы и сопоставленные им места. После сопоставления мест вы попадаете обратно в схему — ВАЖНО сохранить схему — потому что все соответствия мест хранятся в СХЕМЕ. Можно назначять места сразу по мере создания схемы по кнопке E на элементе, подсветить в таблице Посадочное место — и далее нажать кнопку назначить посадочное место:

В Kicad процесс работы всегда идет ОТ Схемы к ПЛАТЕ! Это значит, что если при трассировке платы вы решили поменять посадочное место, то надо это сделать в схеме, а потом перенести изменения на плату! Несмотря на то, что в редакторе платы это тоже можно сделать — эти изменения не перенесуться в схему и потом можно запутаться! В этой программе нет обратного переноса изменений с платы в схему!

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

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

Резисторы и кондцеторы для поверхностного монтажа имеют много различных размеров. Для простоты во всех проектах мы будем использовать один размер. Для резисторов — 0603, для кондцеторов меньше 1uf — 0603, для кондцеторов больше 1uf — 0805. Kicad имеет посадочные места с добавкой в названии «_Handsoldering» - специально разработанные для ручной пайки — мы будем использовать их. Если использовать обычные посадочные места 0603 — то будет сложно подлезть паяльником. Также всегда смотрите на плате сможете ли вы подлезть паяльником.

Все посадочные места типовых библиотек хранятся в интернет на Github. Чтобы можно было работать локально необходимо их загрузить на локальный компьютер. Делается это в редакторе плат по команде Настройки — Мастер библиотек посадочных мест — надо выбрать github репозитарий и поставить галку сохранять локальную копию — и нажать далее — далее и т. д. Если этого не сделать, то при работе с посадочными местами будет нужен интернет.

Переносим данные из схемы на плату

Эта процедура будет выполняться довольно часто. Поэтому нужно сразу правильно научится это делать. Любые изменения в процессе трассировки сначала надо отразить в схеме, а потом перенсти на плату. Обычная ситуация - трассируем вывод микроконтроллера и понимаем, что надо поменять выходы ног местами. Надо переключится в схему, там поменять выходы. И перенести изменения на плату и продолжить трассировку.

Очень хорошо, что этот процесс не деструктивен и выполняется быстро. Делается это так:

  • из редактора схемы нажимаем «Инструменты — сформировать список цепей»

  • переключаемся в редактор платы и там нажимем «Инструменты — Список цепей»

Тут важно отметить параметры загрузки списка цепей на плату. По кнопке прочитать текущий список цепей происходит загрузка данных.


  • Переключатель Замена посадочных мест позволяет отразить изменения в посадочных местах если они были изменены на схеме. Если он останется в положении «Оставить» - то замена не произойдет!

  • Дополнительные посадочные места — Оставить или Удалить — если мы добавляли руками какие-то посадочные места — например корпус — то если выбрать удалить — то все добавленное вручную на плату в редакторе — будет УДАЛЕНО! С другой стороны — если мы на схеме удалили много элементов — то их придется удалять руками в редакторе плат.

  • Холостой код — галка позволяет просто посмотреть окно сообщений и проверок ничего не делая.

  • Тестировать посадочные места — произойдет тестирование на соотв мест схеме.

  • Перестроить связи — позволяет только перестроить связи без загрузки посадочных мест

Попробуйте в качестве тренировки: добавить на схеме элемент — перенести изменения — удалить элемент — перенести изменения — изменить посадочное месте на схеме — перенести изменение.

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


Разные версии Kicad могу иметь различные названия библиотек и при загрузке проектов из вне могут возникать такие ошибки. Как правило ничего страшного в этом нет, обычно просто меняются названия библиотек, старые элементы никто не удаляет.

Создаем привязки к корпусу

При создании платы очень важно учесть конкретный корпус. Корпус имеет определнные размеры, может имет технологические отверстия и т. д. Это все нужно видеть при размещении элементов. Конечно можно замерить расположение нужных отверстий и учесть это на плате. Можно использовать специальные посадочные места Mounting point для обозначения крепежных отверстий. Но есть метод гораздо лучше!

Как правило, на каждый корпус в интернет есть datasheet с чертежами, или его можно просто отсканировать. Важно чтобы у нас был пропорциональный чертеж. Например такой:


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


Это будет размер 64х64мм. Далее в Kicad есть специальный инструмент — Bitmap2Component:

Эта программа позволяет перевести рисунок в компонент на плате!! Далее этот компонент можно кинуть на любой слой и он будет ориентиром на плате!

Запускаем программу — загружаем наш Bitmap. И подгоняем размер под известный, за счет разрешения.


Мы должны получить размер 64х64мм:


Если у нас сканер — то этого делать не придется — там сразу известно DPI.

Далее жмем Экспорт и получаем наш новый элемент — сохраняем его в нашей библиотеке посадочных мест. Остается в редакторе платы добавить посадочное место вручную по кнопке Разместить — Посадочное место — наш корпус — и получаем такую красоту:

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

Размещаем компоненты

После того как мы загрузили все связи — на схеме в одном месте в куче появляются все наши компоненты:

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


и нажимаем правой кнопкой мышки в пустом пространстве — в меню выбираем Глобальное перемещение и размещение объектов — Расположить все посадочные места. В результате этой команды все посадочные места будут размещены рядом стройно:


Теперь необходимо начертить границы платы и начать размещать основные элементы на будущей плате. Обычно это разъемы, точки подключения дисплея, динамик, антены и другие внешние крупные элементы, по сути требующие особого места на плате — их подвигать особенно не получится.

Далее нужно прикинуть где будет микроконтроллер и как он будет размещен (повернут и т. д.). После того как микроконтроллер размещен необходимо разместить зависимые элементы — кондецаторы питания, кварцевые резонаторы. Тут важно правильно делать разводку. С питанием все очень просто — питание должно сначала входить в кондецатор, а только потом в ножку МК. Правильное размещение кондцаторов питания:


а вот не правильное размещение кондецатора, питание сначала заходит в ногу микросхемы, а только потом идет на кондецатор.


Очень важно размещать кондцеаторы питания на каждой ножке питания как можно ближе. Кварцы тоже должны располагаться рядом с выводами подключения.

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

Процесс ручной трассировки условно можно разделить на 2 больших этапа — первый проработка расположения компонентов и трассировка платы. Этап расположения компонентов обычно делается так:

  1. Располагаем основные компоненты, потом зависимые

  2. Пробуем проложить дорожки, если не выходит — то двигаем компоненты и опять пробуем проложить дорожки.

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

  4. Когда дорожки более-менее легли — то можно занятся уже трассировкой. Тут рекомендуется все дорожки удалить и начать заново.

     

 

Трассировка платы вручную

Ваша задача соединить все необходимые выводы согласно схеме. Программа всячески пытается вам помочь. Для удобства трассировки лучше отключить лишние слои:


Если что, в любой момент можно нажать на компоненте E и посмотреть что это такое. Убрав эти слои вы сразу убираете кучу мусора. Также работая с определенной стороной лучше убирать «Посадочные места спереди или сзади», чтобы не видеть лишние компоненты и убирать видимость лишних медных слоев.

Для измерения расстояния при трассировке очень удобно использовать клавишу пробел. При нажатии обнуляются dx dy внизу окна и по ним можно измерить любое расстояние. При трассировке удобно использовать сетку 0.1 мм.

Основные правила ручной трассировки:

  1. все компоненты максимально должны быть на плате! Выключатели, кнопки, светодиоды — избегайте подключения их проводами!

  2. каждая ножка питания должна иметь кондецатор, как можно ближе к ножке

  3. раставляя компоненты представляйте как вы их будете паять — при очень плотной застройке жалу паяльнику влезть некуда

  4. дорожки не должны иметь острых углов — максимум 90 градусов — а лучше 135

  5. сразу определитесь с толщиной дорожки — лучше использовать 0.25 или 0.3 — если не требуется больше

  6. сразу установите диаметр переходного отверстия — лучше 1.8 отв 0.8 — можно 1.6 — меньше не стоит!

  7. не размещайте переходные отверстия под микросхемами

  8. если на плате есть модули с антеннами — то под антенами не должно быть дорожек, меди и т. д. - соотв сразу ставьте области запрета на таких местах

  9. если есть корпус - сразу ставьте монтажные отверстия

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

  11. В разъемах проверяйте чтобы был запас меди — например отверстие диаметр 0.8мм требует площадку 1,8мм — а лучше 2мм, если будет 1.4мм то будет очень тоная нитка вокруг отверстия — большая вероятность порвать при сверлении. Если такое есть лучше переделать посадочное место разъема.

  12. Если у вас будут выводы под запайку провода, то дорожки должны подходить только с одной стороны — с той где будет запаиваться провод, использовать провод как переходное отверстие очень сложно

  13. Если у вас есть разъемы то имейте ввиду, что вы не сможете припаять его с двух сторон! Например у вас разъем PIN, при запайке он закрывает одну сторону платиковой втулкой и там припаяться не получится! Хотя программа будет считать что это можно использовать как переходное отверствие — вам придется добавить новое рядом!

Автотрассировка в Topor

Если схема очень сложная, то можно воспользоваться автотрассировщиком. Это магическая программа, которая сама все сделает за вас — расположит компоненты и проведет все дорожки. На выходе сразу готовая плата. К сожалению это большое заблуждение!

К сожалению автотрассировщик может не так уж много, тем не менее в опредленных сложных платах он может очень помочь. Вы должны четко понимать — это инструмент, помогающий в трассировке платы, а не делающий работу за вас! Простые платы и вовсе лучше делать вручную.

Kicad умеет работать с любым внешним трассировщиком понимающим формат DSN — Specctra Deisgn. Самый лучший трассировщик на данный момент — это TOPOR 6. Версия light позволяет трассировать небольшие платы бесплатно. В домашнем радиолюбительстве этого достаточно. Только он умеет прокладывать кривые дорожки:


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

Подготовка платы для работы в Topor

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

  1. разместить все компоненты

  2. начертить границы корпуса на слое EDGE

  3. начертить все области запрета, желательно под микросхемами области запрета переходных отверстий

  4. определиться примерно с выводами на разъемах и перекинуть если нужно местами ножки (см раздел размещение компонентов)

  5. на этом этапе не надо рисовать земляные полигоны! Если они есть — лучше удалить!

  6. Развести основные цепи — кондецаторы питания, кварцы, линии питания, другие важные цепи. Лучше полностью развести цепи питания.

Процедура автотрассировки

Процедура автотрассировки выглядит так:

  1. в Kicad в редакторе плат нажимаем Инструменты — FreeRoute.

  2. Там нажимаем — Экспорт в файл Spectrs DSN, если будут ошибки - исправляем

  3. Переключаемся в Topor

  4. Выбираем Файл — Импорт — формат Spectra DSN — и выбираем файл из папки проекта Kicad

Теперь мы видим в Topor нашу плату. Элементы там уже расположены как надо, дорожки питания разведены. Чтобы Topor не перекладывал эти дорожки надо выделить все элементы платы — CTRL-A и зафиксировать их F. Все теперь можно переходить к автотрассировке. Нажимаем Дизайн — Редактор параметров. Там задаем параметры переходных отверстий, Ширину проводников и зазор между проводниками. Topor в отличие от Kicad умеет динамически менять толщину проводника и зазор — так что задаем желаемый и минимальный размеры. Все готово для трассировки. Запускаем — Трассировка — автотрассировка — Запустить. Теперь ждем пока Topor не напишет, что можно завершить процесс или можно прервать раньше - по кнопке остановить.


Topor предлагает сразу несколько варианто — их все сохранить, можно выбрать один. Если встать на вариант, то можно предварительно его просмотреть на плате:


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


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

Также можно подвигать сами элементы - кнопка в виде Руки позволяет задать новое место элемента — все проводники будут проложены заново. Если вы будете пользоваться этим продуктом — обязательно посмотрите видео в YouTube, там показаны основные приемы перепрокладки проводников — это очень мощная функция Topor. Работать в Topor одно удовольствие — очень мощный продукт, но все таки он не бесплатен, а также постоянный импорт экспорт утомляет. В итоге лучше его использовать для сложных плат.

Обратный импорт

В Topor выбираем Файл - экспорт и формат Spectra (файл .ses) и переключаем обратно в Kicad. Там нажимаем - Инструменты — FreeRoute — Обратный импорт. Все дорожки должны перерисоваться. Далее подправляем нужные детали и плата готова.

Размечаем земляные полигоны

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

Для этого выбираем меню — Разместить — Зоны и обводим зону больше нашей платы.

При начале рисования области — нас спросят что это будет за зона и ее параметры — выбираем слой F.cu и цепь GND.


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

Зону рисуем например так, нет необходимости рисовать ее точно:

Такую же зону надо добавить на слой B.cu. Это можно сделать также выбрав слой B.cu, а можно нажать правой кнопкой на зоне и выбрать из меню — зоны — добавить дубликат зоны на слой.

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

Подготовка файлов к изготовлению платы

Итак, плата готова. Для дальнейшей работы необходимо создать файлы медных слоев. Если вам необходимо подготовить файлы для производства — то скорее всего будет нужен формат Gerber. Выбираем файл — чертить — там выбираем формат Gerber. После этого нажимаем там же — подготовить файлы сверловки.

Нам же нужен другой формат. Нам необходимо подгтовить медные слои в формате SVG. Нажимаем Файл — Чертить. Выбираем формат SVG и ставим соответсвующие настройки. Жмем Чертить. В каталоге проекта появляется два файла — F.cu.svg и B.cu.svg. Это файлы верхнего и нижнего слоев платы.

Так как мы их чертили не зеркально, то надо иметь ввиду, при изготовлении платы при печати— слой F.cu надо отразить зеркально, а вот B.cu — не надо!

Полезные ссылки по программе

Документация по Kicad на русском языке

Как делать посадочные места автоматом

Программа для он лайн рисования многовыводных элементов схемы

Форум по кикад

Тут можно найти библиотеки отдельных элементов и их посадочные места

]]>
(Super User) Теория Tue, 29 Aug 2017 08:30:39 +0000
Делаем печатную плату /index.php/theory/item/12-delaem-pechatnuyu-platu /index.php/theory/item/12-delaem-pechatnuyu-platu

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

{index}

Что такое печатная платa

Печа́тная пла́та (англ. printed circuit board, PCB, или printed wiring board, PWB) — пластина из диэлектрика, на поверхности и/или в объёме которой сформированы электропроводящие цепи электронной схемы. Печатная плата предназначена для электрического и механического соединения различных электронных компонентов. Электронные компоненты на печатной плате соединяются своими выводами с элементами проводящего рисунка обычно пайкой.

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

В зависимости от количества слоёв с электропроводящим рисунком, печатные платы подразделяют на:

  • односторонние (ОПП): имеется только один слой фольги, наклеенной на одну сторону листа диэлектрика.

  • двухсторонние (ДПП): два слоя фольги.

  • многослойные (МПП): фольга не только на двух сторонах платы, но и во внутренних слоях диэлектрика. Многослойные печатные платы получаются склеиванием нескольких односторонних или двухсторонних плат.

По мере роста сложности проектируемых устройств и плотности монтажа, увеличивается количество слоёв на платах.

Основой печатной платы служит диэлектрик, наиболее часто используются такие материалы, как стеклотекстолит, гетинакс. Также основой печатных плат может служить металлическое основание, покрытое диэлектриком (например, анодированный алюминий), поверх диэлектрика наносится медная фольга дорожек. Такие печатные платы применяются в силовой электронике для эффективного теплоотвода от электронных компонентов. При этом металлическое основание платы крепится к радиатору. В качестве материала для печатных плат, работающих в диапазоне СВЧ и при температурах до 260 °C, применяется фторопласт, армированный стеклотканью (например, ФАФ-4Д), и керамика. Гибкие платы делают из полиимидных материалов, таких как каптон.

Какой материал будем использовать для изготовления плат

Самые распространненые, доступные материалы для изготовления плат — это Гетинакс и Стеклотекстолит. Гетинакс-бумага пропитанная бакелитовым лаком, текстолит стекловолокно с эпоксидкой. Однозначно будем использовать стеклотекстолит!

Стеклотекстолит фольгированный представляет собой листы, изготовленные на основе стеклотканей, пропитанных связующим на основе эпоксидных смол и облицованные с двух сторон медной электролитической гальваностойкой фольгой толщиной 35 мкм. Предельно допустимая температура от -60ºС до +105ºС. Имеет очень высокие механические и электроизоляционные свойства, хорошо поддается механической обработке резкой, сверлением, штамповкой.

Стеклотекстолит в основном используется одно или двухсторонний толщиной 1.5мм и с медной фольгой толщиной 35мкм или 18мкм. Мы будем использовать односторонний стеклотекстолит толщиной 0.8мм с фольгой толщиной 35мкм (почему будет подробно рассмотрено далее).

Методы изготовления печатных плат дома

Платы можно изготавливать химическим методом и механическим.

При химическом методе в тех местах где должны быть дорожки (рисунок) на плате на фольгу наносится защитный состав (лак, тонер, краска и т.д.). Далее плата погружается в специальный раствор (хлорное железо, перекись водорода и другие) который «разъедает» медную фольгу, но не действует на защитный состав. В итоге под защитным составом остается медь. Защитный состав в дальнейшем удаляется растворителем и остаётся готовая плата.

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

Фрезерные станки довольно дорогое удовольствие, а также сами фрезы дороги и имеют небольшой ресурс. Так что, этот метод мы не будем использовать.

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


Следующий метод изготовления плат — с помощью фоторезиста. Это очень распространненая технология (на заводе платы делаются как раз этим методом) и она часто используется в домашних условиях. В интернет очень много статей и методик изготовления плат по этой технологии. Она дает очень хорошие и повторяемые результаты. Однако это тоже не наш вариант. Основная причина — довольно дорогие материалы (фоторезист, который к тому же портится со временем), а также дополнительные инструменты (УФ ламка засветки, ламинатор). Конечно, если у вас будет объемное производство плат дома — то фоторезист вне конкуренции — рекомендуем освоить его. Также стоит отметить, что оборудование и технология фоторезиста позволяет изготовливать шелкографию и защитные маски на платы.

С появлением лазерных принтеров радиолюбители стали активно их использовать для изготовления плат. Как известно, для печати лазерный принтер использует «тонер». Это специальный порошок, который под температурой спекается и прилипает к бумаге — в итоге получается рисунок. Тонер устойчив к различным химическим веществам, это позволяет использовать его как защитное покрытие на поверхности меди.

Итак, наш метод состоит в том, чтобы перенести тонер с бумаги на поверхность медной фольги и потом протравить плату специальным раствором для получения рисунка.

В связи с простотой использования данный метод заслужил очень большое распространение в радиолюбительстве. Если вы наберете в Yandex или Google как перенести тонер с бумаги на плату — то сразу найдёте такой термин как «ЛУТ» — лазерно утюжная технология. Платы по этой технологии делаются так: печатается рисунок дорожек в зеркальном варианте, бумага прикладывается к плате рисунком к меди, сверху данную бумагу гладим утюгом, тонер размягчяется и прилипает к плате. Бумага далее размачивается в воде и плата готова.

В интернет «миллион» статей о том как сделать плату по этой технологии. Но у данной технологии есть много минусов, которые требуют прямых рук и очень долгой пристройки себя к ней. То есть ее надо почувствовать. Платы не выходят с первого раза, получаются через раз. Есть много усовершенствований — использовать ламинатор (с переделкой — в обычном не хватает температуры), которые позволяют добиться очень хороших результатов. Даже есть методы построения специальных термопрессов, но все это опять требует специального оборудования. Основные недостатки ЛУТ технологии:

  • перегрев — дорожки растекаются — становятся шире

  • недогрев — дорожки остаютяся на бумаге

  • бумага «прижаривается» к плате — даже при размокании сложно отходит — в итоге может повредится тонер. Очень много информации в интернете какую бумагу выбрать.

  • Пористый тонер — после снятия бумаги в тонере остаются микропоры — через них плата тоже травится — получаются изъеденные дорожки

  • повторяемость результата — сегодня отлично, завтра плохо, потом хорошо — стабильного результат добиться очень сложно — нужна строго постоянная температура прогрева тонера, нужно стабильное давление прижима платы.

К слову, у меня этим методом не получилось сделать плату. Пробовал делать и на журналах, и на мелованной бумаге. В итоге даже платы портил — от перегрева вздувалась медь.

В интернет почему-то незаслуженно мало информации про еще один метод переноса тонера — метод холодного химического переноса. Он основан на том факте, что тонер не растворяется спиртом, но растворяется ацетоном. В итоге, если подобрать такую смесь ацетона и спирта, которая будет только размягчать тонер — то его можно «переклеить» на плату с бумаги. Этот метод мне очень понравился и сразу дал свои плоды — первая плата была готова. Однако, как оказалось потом, я нигде не смог найти подробной информации, которая давала бы 100% результат. Нужен такой метод, которым плату мог сделать даже ребёнок. Но на второй раз плату сделать не вышло, потом опять и пришло долго подбирать нужные ингридиенты.

В итоге после долгих была разработана последовательность действий, подобраны все компоненты, которые дают если не 100% то 95% хорошего результата. И самое главное процесс настолько простой, что плату может сделать ребенок полностью самостоятельно. Вот этот метод и будем использовать. (конечно его можно и далее доводить до идеала — если у вас выйдет лучше — то пишите). Плюсы данного метода:

  • все реактивы недорогие, доступные и безопасные

  • не нужны дополнительные инструменты (утюги, лампы, ламинаторы — ничего, хотя нет - нужна кастрюля)

  • нет возможности испортить плату — плата вообще не нагревается

  • бумага отходит сама - видно результат перевода тонера — где перевод не вышел

  • нет пор в тонере (они заклеиваются бумагой) — соответственно нет протравов

  • делаем 1-2-3-4-5 и получаем всегда один и тот же результат — почти 100% повторяемость

Прежде чем начать, посмотрим какие платы нам нужны, и что мы сможем сделать дома данным методом.

Основные требования к изготовленным платам

Мы будем делать приборы на микроконтроллерах, с применением современных датчиков и микросхем. Микросхемы становятся все меньше и меньше. Соответственно необходимо выполнение следующих требований к платам:

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

  • дорожки должны быть толщиной 0.2мм — такого размера вполне достаточно — 0.1мм было бы еще лучше — но есть вероятность протравов, отхода дорожек при пайке

  • промежутки между дорожками — 0.2мм — этого достаточно практически для всех схем. Уменьшение зазора до 0.1мм чревато сливанием дорожек и сложностью в контроле платы на замыкания.

Мы не будем использовать защитные маски, а также делать шелкографию — это усложнит производство, и если вы делаете плату для себя, то в этом нет нужды. Опять же в интернет много информации на эту тему, и если есть желание вы можете навести «марафет» самостоятельно.

Мы не будем лудить платы, в этом тоже нет необходимости (если только вы не делаете прибор на 100лет). Для защиты мы будем использовать лак. Основная наша цель — быстро, качественно, дёшево в домашних условиях сделать плату для прибора.

Вот так выглядит готовая плата. сделанная нашим методом — дорожки 0.25 и 0.3, расстояния 0.2

 

Как сделать двухстороннюю плату из 2-ух односторонних

Одна из проблем изготовления двухсторонних плат — это совмещение сторон, так чтобы переходные отверстия совпадали. Обычно для этого делается «бутерброд». На листе бумаги печатается сразу 2 стороны. Лист сгибается пополам, на просвет точно совмещаются стороны с помощью специальных меток. Внутрь вкладывается двухсторонний текстолит. При методе ЛУТ такой бутерброд проглаживается утюгом и получается двухсторонняя плата.

Однако, при методе холодного переноса тонера сам перенос осуществляется с помощью жидкости. И поэтому очень сложно организовать процесс смачивания одной стороны одновременно с другой стороной. Это конечно тоже можно сделать, но с помощью специального приспособления — мини пресса (тисков). Берутся плотные листы бумаги — которые впитывают жидкость для переноса тонера. Листы смачиваются так, чтобы жидкость не капала, и лист держал форму. И дальше делается «бутерброд» - смоченный лист, лист туалетной бумаги для впитывания лишней жидкости, лист с рисунком, плата двухсторонняя, лист с рисунком, лист туалетной бумаги, опять смоченный лист. Все это зажимается вертикально в тиски. Но мы так делать не будем, мы поступим проще.

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


В итоге из одной двухсторонней платы толщиной 1.5мм получаем две односторонние половинки.


Далее делаем две платы, сверлим и все — они идеально совмещены. Ровно разрезать текстолит не всегда получалось, и в итоге пришла идея использовать сразу тонкий односторонний текстолит толщиной 0.8мм. Две половинки потом можно не склеивать, они будут держаться за счет запаяных перемычек в переходных отверстиях, кнопок, разъемов. Но если это необходимо без проблем можно склеить эпоксидным клеем.

Основные плюсы такого похода:

  • Текстолит толщиной 0,8мм легко режется ножницами по бумаге! В любую форму, то есть очень легко обрезать под корпус.

  • Тонкий текстолит — прозрачный — посветив фонарем снизу можно легко проверить корректность всех дорожек, замыкания, разрывы.

  • Паять одну сторону проще — не мешают компоненты на другой стороне и легко можно контролировать спайки выводов микросхем— соединить стороны можно в самом конце

Минусы:

  • Сверлить надо в два раза больше отверстий и отверстия могут чуть-чуть не совпасть

  • Немного теряется жёсткость конструкции если не склеивать платы, а склеивать не очень удобно

  • Односторонний стеклотекстолит толщиной 0.8мм трудно купить, в основном продается 1.5мм, но если не удалось достать, то можно раскроить ножем более толстый текстолит.

Перейдем к деталям.

Необходимые инструменты и химия

Нам понадобятся следующие ингридиенты:

  • стеклотекстолит 0.8мм 1-сторонний

  • губка пружинка для мытья посуды

  • фейри или другая жидкость для мытья посуды

  • ацетон (Не забывайте что его пары ядовиты! Работайте в хорошо провертриваемом помещении!)

  • жидкость для снятия лака без ацетона (например ЛАСКА, она точно подходит). Обязательно проверьте жидкость. сейчас очень много подделок, в которые добавлен ацетон. Для проверки надо смочить распечатку на бумаге этой жидкостью, тонер не должен поплыть!

  • спирт технический (ИЗОПРОПАНОЛ — Изопропиловый спирт абслолютированный 99.7% безводный), можно и медицинский, но его сейчас трудно купить

  • туалетная бумага мягкая двух-слойная (например Zewa)

  • шприц пластиковый на 2-3мл

  • фото бумага LOMOND 0102145 85gsm InkJet Photo Paper

  • принтер лазерный чернобелый с высоким разрешением — больше 600dpi. Например HP LaserJet P1102. Картридж можно использовать неоригинальный. Например — Profline отлично подходит.

  • Ножницы, лучше швейный для раскроя ткани

  • сверла 0.6, 0.8, 1мм

  • маркер для корректировки плат Edding 140S

  • минидрель из моторчика (ниже будет рассказано как ее сделать)

  • гидроперит (приобретается в аптеке)

  • лимонная кислота (в хозяйсвтенном магазине или супермаркете)

  • соль каменная (без йода)

  • емкость для травления — например пластиковый контейнер


Теперь когда все это есть, делаем по шагам.

1. Компоновка слоев платы на листе бумаги для печати c помощью InkScape

Inkscape - это высококачественный профессиональный инструмент для работы с векторной графикой для Windows, Mac OS X и Linux. Он широко используется любителями и профессионалами по всему миру для создания иллюстраций, иконок, логотипов, диаграмм, карт, а также веб-графики. Inkscape использует открытый стандарт SVG (Scalable Vector Graphics) от W3C в качестве формата по-умолчанию, а также сам является свободным и открытым программным обеспечением.

Эта программа очень хороша для компоновки рисунка будущей платы. На выходе программы трассировки платы Kicad (или другой) мы получаем рисунок каждого слоя в формате svg или pdf. С помощью этой программы можно импортировать на один лист каждый слой (то есть несколько svg файлов), если необходимо отразить их зеркально и разместить их на листе в нужном количестве. Получившийся рисунок можно сохранить в pdf формате или сразу распечтать.

Давайте посмотрим как это делается.

  1. Создаем новый документ в InkScape

  2. Выбираем «Файл — Импортировать» и выбираем наши файлы svg слоев платы. ОБЯЗАТЕЛЬНО делать импортирование, иначе можно измениться геометрия рисунка! В итоге получается 2 объекта (можно импортировать по одному):

  3. Далее растаскиваем два чертежа и необходимый слой платы (если в Kicad делали оба слоя не зеркальные — то F.Cu слой надо сделать зеркальным) делаем зеркальным (кнопка V — вертикально или H — горизонтально, все равно как, больше для наглядности). Располагаем их рядом, чтобы можно было разрезать — достаточно зазора 2-3мм. Для большей точности можно использовать поля с милиметрами в панели инструментов:

  4. Если нам надо поместится в печатную плату определенного размера — то можно сделать прямоугольник нужного размера и внутри его располагать наши рисунки. !Перед печатью нужно удалить все лишние элементы!, если оставить то может в итоге выйти не черный цвет.

  5. Лучше сразу печатать 2 копии — чтобы сразу посмотреть какая вышла лучше или если не выйдет с первого раз то останется вторая. В этом редакторе легко можно скопировать и сделать второй экземпляр.

  6. Выбираем Файл — сохранить Как — формат PDF и сохраняем. Если вы будете печатать непосредственно из Inkscape, то обязательно проверяйте геометрию, диагональные расстояния сверьте линейкой, иначе плата не выйдет. При печати лучше выбирать Тип печати - ВЕКТОРНЫЙ.

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

Небольшие советы:

  • Старайтесь оставить отступы от краев, потому что принтер может плохо печатать ближе к краю.

  • Если плата небольшая, то лучше разместить так, чтобы рисунок занимал пол страницы, тогда можно лист фотобумаги разрезать на 2 части при печати и использовать 2 раза.

  • На печати не должно быть никаких серых областей — все только черно-белое!

  • Обязательно проверяйте посадочные места перед изготовлением платы — приложите микросхемы к распечатанным областям на обычном листе бумаги, или прямо к монитору

  • Внимательно следите за зеркальным слоем — проверить очень легко — после печати — переверните лист и на просвет убедитесь, что все соответсвует рисунку в Kicad.

  • Перед началом изготовления выберите лучшую копию — где больше тонера, где он лучше лежит и т. д.

  • Старайтесь, чтобы сама плата была не большой — не больше 10см х 10 см, иначе ее будет сложно равномерно прижать чертеж к плате. То есть если плата большая, лучше сделать каждую сторону за отдельный заход.

  • Если что-то пошло не так, не переживайте, все можно повторить заново.

  • Оставьте небольшой отступ по длинной стороне итогового чертежа, например 2см, чтобы держать вырезанный рисунок руками.

  • Сама плата должно быть хотя бы на 3мм больше с каждого края чертежа

Вот идеальный вариант:


Еще раз напишу — все добавленные прямоугольники необходимо удалить! Оставить только рисунки платы!

2. Печатаем на принтере рисунок платы

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

  • Она должна быть легко доступна

  • Недорогая

  • Тонкая, и в то же время не рвущаяся при размачивании

  • Бумага с глянцевым слоем

  • Хорошо и быстро впитывающая влагу (наш раствор), и при этом не коробящаяся при намокании

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

Итак, наш выбор — это бумага фотобумага Lomond (см выше точное название).

Печатать нужно на максимальном расходе тонера. В Windows идем в принтеры, находим нужный принтер и на нем нажимаем правой кнопкой мышки — свойства. Идем на закладку «Параметры устройства» и выбираем плотность печати — максимальная (например 5). В linux такой настройки в драйверах нет, пришлось ставить виртуальную машину с Windows.

Без этой настройки перевод может не получится, и тонер может быть более пористым. При печати также выбираем свойства и чернобелую печать и максимальное разрешение:

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

!При печати PDF файла - обязательно следите за тем, чтобы масштаб был 100% или реальный размер. Adobe PDF любит автоматически размещать на листе меняя масштаб! В этом случае ничего не выйдет.

Теперь вырезаем ножницами рисунок который получился лучше всего. С одного края оставляем 2см бумаги, чтобы держать листок руками (лучше по длинной стороне платы). Режем близко к рисунку 2-3 мм от самого рисунка, чтобы видеть границы рисунка. Кладем его рядом, и он ждет своей участи.

3. Готовим раствор для химического перевода

Сам рецепт очень простой. Берем 2 части жидкости для снятия лака и 1 часть ацетона (например 10мл жидкости и 5мл ацетона). Отмерить можно как угодно — шприцом, мерным стаканчиком. На одну плату 100х50мм идет 2-3мл раствора, так что обычно 30мл хватает на долго, тоесть можно все сразу не смешивать. Хранить такой раствор надо обязательно в плотно закрытой емкости. Очень удобно использовать бутылки стеклянные от физраствора из аптеки с резиновыми крышками:


Ацетон более летучий, так что при длительном хранении может нарушится пропорция. Лучше раствор готовить сразу, и очень долго не хранить. Смешали, немного поболтали и все готово.

4. Готовим стеклотекстолит

На этом этапе лучше сразу подготовить рабочее место где вы будете переводить рисунок на плату. Подойдет стол или табуретка. Сверху лучше положить широкую доску толщиной 2 см или мебельный щит — нужна ровная массивная поверхность. В центр доски кладем 1 лист двухслойной туалетной бумаги.

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


После этого капаем каплю Фейри в центр платы и хорошо вспениваем руки и саму плату. Моем, трем прямо 2-3 минуты. После этого промываем холодной водой. Держим строго за края платы. Никаких следов от рук остаться не должно. После этого плата готова для перевода. Стряхиваем воду и кладем нашу плату на лист туалетной бумаги, которую мы подготовили. Из шприца выдавливаем пару больших капель нашего раствора на плату и протираем ее куском туалетной бумаги на сухо. На этом этапе следим, чтобы на плату не попали ворсинки, пыль, волосы и т. д. Если у вас грязное помещение, то надо сначала навести порядок.

5. Переводим рисунок

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

Переводим рисунок (прежде чем делать — прочитайте несколько раз, делать надо все строго последовательно и быстро).

  1. Набираем в шприц наш приготовленный раствор — достаточно около 2-3мл.

  2. Кладем нашу подготовленную плату на туалетную бумагу медной поверхностью вверх. На медь наносим с помощью шприца много-много капелек, покрывая всю плату тонким слоем раствора. Шприц здесь очень помогает экономить раствор и равномерно наносить его на плату. Лучше чтобы это была цельная лужа без промежутков.


  3. Теперь быстро кладем вырезанный чертеж рисунка платы самим рисунком ВНИЗ и белой стороной бумаги вверх на смоченную раствором плату. Класть лучше держа за тот кусочек, который мы специально оставили. Бумага должна лечь ровно по плате и сразу начнем промокать. Двигать ее в этот момент нельзя! Так что лучше потренироваться с водой, чтобы она ложилась ровно по границе платы.


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

  5. Теперь начинаем считать до 10, кладем сверху 2 куска туалетной бумаги и через 10 секунд придавливаем нашу плату грузом весом около 3кг. Можно использовать кастрюлю с ровным дном, налив туда воды (лучше теплой) или что-то похожее. Дно должно быть очень ровным. Поставили кастрюлю на плату — и надавали на нее половиной своей массы на секунд 5. Теперь ждем 5 минут.

  6. Через 5 минут снимаем кастрюлю и достаем нашу плату. Бумага должна стать практически белой, рисунка почти не видно. Это значит, что она высохла. Если это не так, то пусть полежит досохнет. На ощупь она должна стать полностью сухой.

Очень важно чтобы обе поверхности пресса были ровные без выступов и дырок. У нас должен получится ровный гладкий пресс. Большую массу тут нельзя применять. Я пробовал делать это с грузом в 10кг — дорожки расплывались. Вес груза 3-4 кг является идеальным. Вы можете попробовать разные варианты, пока не набьете руку, но в принципе этот этап получается обычно сразу и легко.

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

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

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

В итоге у вас в руках должна остаться бумага БЕЗ ТОНЕРА. А на плате остаться ТОНЕР. Бумага здесь является контрольным инструментом — если часть тонера отвалится, то он останется на БУМАГЕ! То есть вы сразу увидите, как получилось перевести тонер. Например черная точка — это часть дорожки. Бумага должна быть абсолютно без тонера.


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

Если у вас небольшие куски тонера отвалились, то проще не переделывать плату, а воспользоваться маркером. Он отлично подкрашивает нужные участки. Красить лучше как бы ставя много точек с небольшим нажимом. Оставленный рисунок должен быть плотный и видным как наплыв черного лака. Красить надо минимум в 2 слоя. Вот на дорожке видим отвалился тонер:


На бумаге тоже это будет видно:

А вот так выглядит плата после реставрации (маркер просто идеальный, в конце фото платы после травления):

Плата готова для травления. На этом этапе вы можете еще раз проверить все хорошо. Возьмите яркий источник света и посветите на плату, и наклоняйте ее из стороный в сторну как бы ловя солнечный зайчик. Если в тонере есть поры, или где-то он плохо прилип, то вы без сомнения увидите отблески меди обычно на полигонах. Это говорит скорее всего о том, что у вас сел картридж или низкое разрешение принтера. Можно оставить — плата скорее всего получится, но дорожки могут быть пористыми или переделать.

В нашем методе после высыхания тонер будет иметь белый налет, на нем остается фото слой — он дополнительно защищает поры тонера. Осталось протравить плату.

Если вдруг у вас не получается этот этап, то все равно плату можно сделать — сняв слой бумаги обычным методом как в ЛУТ технологии — размочив в теплой воде, плата получится хорошо — но будет не так идеально на полигонах.

Внимание! Прежде чем травить плату, еще раз проверьте рисунок, там ли находятся отверстия, те ли корпуса под микросхемы, нет ли разрывов на дорожкам. Тут еще можно все переделать. После того как вы протравите плату, придется только работать ножом и проводками. !При переносе тонера, если сдвинуть бумагу или сильно давить картой при выравнивании, может измениться геометрия рисунка. Обязательно проверьте линейкой по диагональным точкам расстояние!

6. Травим плату

В интернет рассмотрено очень много травильных растворов. Самый известный — хлорное железо. Но так как мы занимаемся платами дома, будем использовать самый чистый и безопасный раствор — перекись водорода. Абсолютно безвредная жидкость, можно выливать в раковину, конечно нельзя ПИТЬ.

Минус у нашего раствора один — его нельзя хранить. То есть готовится он на раз. Но с другой стороны его плюс — недорогая стоимость и доступность всех ингридиентов.

Готовим раствор для травления, лучше это делать например в обычной литровой банке, удобно помешивать.

  1. Наливаем в банку 50мл теплой воды.

  2. Кладем туда 3 таблетки Гидроперита (1 таблетка 1.5г в упаковке 8 таблеток) и помешиваем круговыми движениями, пока она полностью не растворится! Должен получится 3% раствор перекиси водорода.

  3. Кладем 15 грамм Лимонной кислоты (можно 20) и 5 гр (чайную ложку) НЕ ЙОДИРОВННОЙ СОЛИ. Все это опять помешиваем круговыми движениями до полного растворения.

Теперь выливаем этот раствор в плоскую емкость, контейнер, и в него кладем нашу плату. Лучше класть плату дорожками вниз! В этом случае процесс будет идти быстрее. Иначе на поверхности платы будет образовываться нерастворимый осадок, который будет мешать травлению. Сразу должен пойти процесс — вся плата должна покрыться пузырьками. Ждем где-то около 20-30 минут и все должно быть готово. Иногда немного дольше — 40минут. Контролировать процесс очень легко — светим фонариком снизу контейнера, и мы должны увидеть рисунок платы. В процессе травления раствор становится сначала зеленый, а потом, когда вся кислота уже прореагировала и стала солью — синий. Если раствор пенится и пузырится, вы перебрали с солью. Капните туда еще немного перекиси и воды. Сильное пузырение может повредить тонер. Когда пузырение прекратится - плата готова.

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

7. Сверлим отверстия

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

Посмотрим какие свёрла нам могут понадобиться:

  • Сверло диаметр 0.6мм — тоньше сверла не нужны, это самое тонкое которое нужно. Чем тоньше сверло, тем более точно вы попадаете в разметку, поэтому этим сверлом можно сверлить ответсвенные переходные отверстия там где нужна особая точность. Потом отверстие можно рассверлить любым нужным сверлом. Такая двухэтапная сверловка будет гораздо точнее, чем сразу сверлить нужным сверлом. Если брать тонкую проволку на переходные отверстия, то оно подойдет для них (например из витой пары).

  • Сверло диаметр 0.7мм — самое ходовое сверло, под все выводные компоненты можно сверлить им — резисторы, конденсаторы, кварцы, монтажные провода, переходные отверстия.

  • Сверло диаметр 0.8мм — можно использовать для отверстий под монтажные провода и некоторые разъемы.

  • Сверло диаметр 1мм — подходит для разъемов типа PIN 2.54 — штыри. Можно конечно попробовать 0.8 — но его чуть-чуть не хватает.

  • Сверло диаметр 2мм — хорошо подходит для монтажных отверстий под маленькие шурупы — крепление платы к корпусу

  • Сверло диаметр 3мм — монтажные отверстия под болты М3

Чтобы упростить себе работу, сверлить надо только те отверстия где подходит дорожка, и второе отверстие просверлить уже потом, когда запяете переходные отверстия. Чтобы не склеивать плату, для обеспечения жесткости, можно добавить неоходимые переходы по земляным полигонам по краям платы.

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

Делаем мини дрель

Для того чтобы сделать мини дрель нужен только моторчик и цанговый патрон для маленьких сверл. Мотор лучше выбрать с высокими оборотами — около 10тыс оборотов в минуту. Отличный мотор R380-2580. При 12в питании выдает 14тыс оборотов. Диаметр вала — 2.3мм.

Цанговый патрон бывает двух видов — набор цанг на фиксированный диаметр сверла:

Автоматический цанговый набор:

Мы рекомендуем первый вариант — он дешевле. Далее необходимо к мотору припаять провода и выключатель (лучше кнопку). Кнопку лучше разместить на корпусе, чтобы удобнее было быстро включать и выключать моторчик. Остается подобрать блок питания, можно взять любой блок питания на 7-12в током 1А (можно и меньше), если такого блока питания нет, то может подойти зарядка по USB на 1-2А или батарейка Крона (только надо пробовать — не все зарядки любят моторы, мотор может не запустится).

Дрель готова, можно сверлить. Но вот только необходимо сверлить строго под углом 90градусов. Можно соорудить мини станок — в интернет есть различные схемы:

Но есть более простое решение.

Кондуктор для сверления

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

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

Такой вариант тоже подойдет, срезать сверху часть пластика и срезать уголок снизу.

Вот как производится сверление с его помощью:


Зажимаем сверло так, чтобы оно торчало на 2-3мм при полном погружении цанги. Ставим сверло на место где надо сверлить (при травлении платы у нас будет оставаться метка где сверлить в виде мини отверстия в меди — в Kicad мы специально ставили галку для этого, так что сверло будет само вставать туда), прижимаем кондуктор и включаем мотор — отверстие готово. Для подстветки можно использовать фонарик, положив его на стол.

Как уже мы писали ранее, сверлить можно только отверстия с одной стороны — там где подходят дорожки — вторую половину можно досверлить уже без кондуктора по направляющему первому отверстию. Это немного экономит силы.

8. Лужение платы

Зачем лудить платы — в основном для защиты меди от корозии. Основной минус лужения — перегрев платы, возможная порча дорожек. Если у вас нет паяльной станции — однозначо — не лудите плату! Если она есть, то риск минимальный.

Можно лудить плату сплавом РОЗЕ в кипящей воде, но он дорого стоит и его сложно достать. Лудить лучще обычным припоем. Чтобы сдеалать это качественно, очень тонким слоем надо сделать простое приспособление. Берем кусочек оплетки для выпайки деталей и одеваем ее на жало, прикручиваем проволокой к жалу, чтобы она не соскочила:

Плату покрываем флюсом — например ЛТИ120 и оплетку тоже. Теперь в оплетку набираем олово и ей водим по плате (красим)— получается отличный результат. Но по мере использования оплетка расподается и на плате начинают оставаться ворскинки медные - их обязательно надо убрать, а то будет замыкание! Увидеть это очень легко посветив фонарем с обратной стороны платы. При таком методе хорошо использовать или мощный паяльник (60ват) или сплав РОЗЕ.

В итоге, платы лучше не лудить, а покрывать лаком в самом конце— например PLASTIC 70, или простой акриловый лак купленный в автозапчастях KU-9004:

Тонкий тюнинг метода переноса тонера

В методе есть два момента, которые поддаются тюнингу, и могут не получиться сразу. Для их настройки, необходимо в Kicad сделать тестовую плату, дорожки по квадратной спирали разной толщины, от 0.3 до 0.1 мм и с разными промежутками, от 0.3 до 0.1 мм. Лучше сразу распечатать несколько таких образцов на одном листе и провести подстройку.

Возможные проблемы, которые мы будем устранять:

1) дорожки могут менять геометрию - растекаться, становится шире, обычно очень не значительно, до 0.1мм - но это не хорошо

2) тонер может плохо прилипать к плате, отходить при снятии бумаги, плохо держаться на плате

Первая и вторая проблема взаимосвязаны. Решаю первую, вы приходите ко второй. Надо найти компромисс.

Дорожки могут растекаться по двум причинам - слишкой большой груз прижима, слишком много ацетона в составе полученной жидкости. В первую очередь надо попробовать уменьшить груз. Минимальный груз - около 800гр, ниже уменьшать не стоит. Соответственно груз кладем без всякого прижима - просто ставим сверху и все. Обязательно должно быть 2-3 слоя туалетной бумаги для хорошего впитывания лишнего раствора. Вы должны добиться того, что после снятия груза, бумага должна быть белая, без фиолетовых подтеков. Такие подтеки говорят о сильном расплавлении тонера. Если грузом отрегулировать не получилось, дорожки все равно расплываются, то увеличиваем долю жидкости для снятия лака в растворе. Можно увеличить до 3 части жидкости и 1 часть ацетона.

Вторая проблема, если нет нарушения геометрии, говорит о недостаточном весе груза или малом количестве ацетона. Начать опять же стоит с груза. Больше 3кг смысла не имеет. Если тонер все равно плохо держится на плате, то надо увеличить количество ацетона.

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

Плата готова

Если вы не будете сразу запаивать плату, то ее необходимо защитить. Самый простой способ сделать это — покрыть спиртоканифольным флюсом. Перед пайкой это покрытие надо будет снять например изопропиловым спиртом.

Альтернативные варианты

Вы также можете сделать плату:

  • методом ЛУТ

  • методом фоторезиста

Дополнительно, сейчас набирает популярность сервис изготовления плат на заказ — например Easy EDA. Если необходима более сложная плата (например 4-х слойная) — то это единственный выход.

]]>
(Super User) Теория Sun, 27 Aug 2017 16:04:21 +0000
Микроконтроллеры /index.php/theory/item/24-mikrokontrollery /index.php/theory/item/24-mikrokontrollery

В данном статье мы расскажем как устроен микроконтроллер, какие они бывают, чем отличаются. И самое главное как правильно выбирать микроконтроллер под проект.

{index}

Данная статья является обзорной, более подробную информацию по всем разделам можно найти в datasheet на конкретный микроконтроллер (далее МК). Основная цель этой статьи дать общее представление об основных модулях микроконтроллера, ответить на вопрос «Какие параметры МК являются ключевыми при выборе МК под проект?».

Мы будем осваивать все возможности МК сразу на приборах, начиная с простых и постепенно переходя к более сложным схемам. В каждом приборе мы будем подробно разбирать программу, и вы научитесь работать с МК на практике, сразу наблюдая результат своей работы. Также во всех приборах оставлено место для самостоятельной работы. Такой подход более продуктивный и интересный, чем работать с отладочной платой (например, Arduino или STM Discovery board). В этой статье мы не будем подробно рассматривать программирование МК (программированию посвящена отдельная статья Приемы программирования микроконтроллеров). Вам важно только запомнить название и назначение каждого модуля, его возможности и основные параметры. Статья является общей для всех видов МК, и не нацелена на какого то одного производителя.

Что такое микроконтроллер

Вы скорее всего хорошо представляете как устроен персональный компьютер. Рассмотрим его основные компоненты:

Микропроцессор (в англоязычной литературе MPU — Micro Processor Unit) содержит функционал компьютерного центрального процессора, или ЦП (CPU — Central Processing Unit) на одном полупроводниковом кристалле (ИМС — интегральная микросхема или на западный манер — Integrated Circuit). Он обрабатывает данные, поступающие с входных периферийных устройств и передаёт обработанные данные на выходные периферийные устройства.

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

Разработать и сделать какое-либо устройство на современном микропроцессоре довольно сложно. В домашних условиях нереально. Шина данных, адресная шина требует много выводов. Их количество у микропроцессора в настоящее время доходит до 1000 выводов. Чтобы развести такое количество ножек нужна как минимум 6-ти слойная плата, а также необходимо использовать микропереходные отверстия — диаметром 0.1 мм. Ну и конечно такая система будет стоить не дёшево.

Микроконтроллер был специально изобретён, чтобы иметь возможность использоваться в самых маленьких устройствах. Это было сделано за счёт объединения в одной микросхеме всех элементов компьютера. Рассмотрим это на схеме:

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

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

Как устроен любой микроконтроллер, основные модули

Практически все микроконтроллеры имеют следующие основные модули:

  • CORE (ядро) — основной вычислительный модуль

  • Memory (память)

    • Flash memory (ПЗУ) — память для хранения программы

    • RAM (ОЗУ) — оперативная память для проведения вычислений

    • EEPROM (ПЗУ) — память для хранения данных

  • Clock and Supply management — модуль управления частотой работы микроконтроллера и питанием

  • Interrupt manager - менеджер управления прерываниями

  • Timers — различные таймеры для генерации ШИМ, управления сном и т. д.

  • Comunications interfaces — периферия для связи с другими микросхемами

    • UART

    • SPI

    • I2C

    • CAN

    • USB

  • ADC (analog to digital converter) — аналого-цифровой преобразователь

  • DAC (digital to analog converter) — цифро-аналоговый преобразователь

  • DMA (direct memory access) — прямой доступ к памяти, без использования процессора

  • GPIO (generak port input output) — порты ввода вывода — управление «ножками»

  • Development support — модуль разработчика — интерфейс программирования и отладки микроконтроллера

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

Core and memory

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

Мы планируем программировать обычные микроконтроллеры (не DSP) на высокоуровневом языке программировать СИ, и в связи с этим, нам не важно какое ядро мы имеем, как оно работает внутри. Всю работу с ядром за нас делаем компилятор СИ. Именно он преобразует наши команды на языке программирования в машинный код. Какие же параметры ядра являются ключевыми для выбора микроконтроллера, и как они могут влиять на его работу?

Максимальная частота работы ядра

Для работы любого процессора необходима задающая частота — сигнал, который меняет напряжение с 0 (0 вольт) на логическую 1 (рабочее напряжение ядра). Именно в момент смены напряжения и происходят все вычисления. Момент изменения сигнала называется такт работы ядра МК, а количество тактов в секунду и есть частота работы ядра (измеряется в герцах). Можно грубо сказать, что данная частота определяет сколько простейших однотактных инструкций может выполнить микроконтроллер за 1 секунду. Например, 24Мгц — 24 миллиона инструкций в секунду. Здесь важно понимать, что речь идёт не об одной строчке кода на языке Си или операции деления, а об одной машинной операции. Все микроконтроллеры и микропроцессоры, в очень упрощённом варианте, работают примерно одинаково:

  • ядро имеет набор регистров — очень быстрых ячеек памяти определённой разрядности в битах — например, 8бит, 16бит, 32бит

  • любая программа - это последовательный набор машинных команд, которые записаны и хранятся в определённой области памяти МК (обычно FLASH памяти)

  • в процессе работы, МК загружает машинные команды из памяти на конвейер (более быстрая память) и выполняет их последовательно

  • каждая машинная команда в качестве операндов берет данные из внутренних регистров, то есть, чтобы сложить 2 числа, надо сначала их записать в разные регистры, а потом выполнить команду сложения (ADD).

Из этого описания становится понятно, что для того чтобы выполнить реальную строчку кода на СИ бывает необходимо выполнить несколько сотен машинных команд. В datasheet на МК обычно есть отдельный раздел посвящённый описанию сколько тактов занимает выполнение команд на Ассемблере, на СИ обычно эти данные не приводятся, так как очень сильно зависят от компилятора. Несмотря на такую сложность, максимальную частоту ядра все же можно считать некоторым показателем производительности ядра (Более общепризнанная единица производительности процессоров — MIPS, однако она тоже не является реальной мерой производительности). На текущий момент есть микроконтроллеры работающие на частоте 200МГц, в простых же задачах хватает и 1 МГц.

Как выбирать частоту микроконтроллера под проект? Самый простой ответ — чем больше тем лучше, однако с частотой растёт цена и энергопотребление процессора. Основной критерий выбора частоты - это необходимая частота обработки данных и сложность алгоритма их обработки. Например, если мы строим метеостанцию и будем опрашивать датчик раз в секунду, то скорее всего нам хватит 1МГц. А вот если мы делаем квадрокоптер и пересчитываем все его параметры по очень сложным алгоритмам 1000 раз в секунду, то необходимо около 100Мгц и более. Для обработки видео HD качества нужен уже процессор с частотой 1Ггц (микроконтроллер с этим не справится). Обычно этот параметр устанавливается опытным путём и берётся с запасом, чтобы была возможность поменять частоту в процессе работы и подобрать оптимальный режим загрузки МК и энергопотребления. Частоту можно программно сделать меньше максимальной. Для почти всех наших проектов частоты в 16Мгц более чем достаточно. На текущий момент практически все МК могут работать на такой частоте.

Разрядность регистров

Вы, наверное, уже слышали или читали, что например STM8 — 8-ми битный МК, а вот STM32 — 32-х битный МК. Тут как раз и идёт речь о разрядности центральных регистров МК. Разрядность регистров определяет сколько бит в одном регистре, а это в свою очередь говорит о том, сколько данных за один такт может участвовать в машинной команде. Чем больше разрядность МК, тем быстрее выполняется код для больших чисел, но тем меньше плотность машинного кода самой программы во Flash памяти МК. Что это значит?

Представим себе простую задачу, надо сложить два числа 10 и 5. Если перевести их в двоичную систему, то это будет 0b1010 и 0b101, то есть 4-х битное число и 3-х битное — результат будет не больше 5 бит. Соответственно, если у нас МК 8-ми битный, то все операнды помещаются в 8-ми битный регистр, и для сложения таких чисел будет одинаково затрачено тактов на любом МК с разрядностью больше 8-ми бит. Но вот если нам надо сложить два больших числа, например, 10 000 и 10, это уже займёт 14 бит, и на МК с разрядностью 8 бит будет выполняться за большее число тактов, будет необходим целый алгоритм (чтобы привести каждое число к 8-ми битам), а на 32-битном МК — за то же самое число тактов. Вы можете самостоятельно это все увидеть в любой среде программирования, которая показывает итоговый код на ассемблере. Таким образом, чем больше разрядность — тем быстрее можно оперировать большими числами. Однако, есть и обратная сторона медали, плотность кода. Для самой простой программы, записать 0 во внутренний регистр, надо потратить 2-е команды (2 байта) на 8‑ми битном МК и 2-е команды (8 байт) на 32-ух битном, так как все команды данные и команды имеют разрядность 32бита. Конечно, производители МК с этим борются, вводят дополнительные наборы команд меньшей разрядности и т. д.

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

Архитектура ядра ARM

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

Общее ядро даёт общие механизмы работы с памятью, отладкой, программированием, механизмом прерываний и другим свойствами ядра. Производители микроконтроллеров сосредоточились на периферийных модулях. Равные конкурентные возможности сказались не цене микроконтроллеров. В настоящее время, нижние ряды 32-х битных микроконтроллеров ARM по стоимости почти равны нижнему ряду восьми битных микроконтроллеров. Также, это позволяет, например, использовать программатор ST-Link, или другие универсальные программаторы, для программирования большинства микроконтроллеров ARM, что расширяет круг выбора процессоров для проекта. Результатом работы ARM можно считать и наличие единых сред разработки для ARM микроконтроллеров — IAR, KEIL, Mbed, Eclipse и другие.

Оперативная память

Это самая быстрая память, кроме регистров, которая есть у МК. Все данные переменных хранятся в ней, правда только когда у МК есть питание. И чем больше у нас в программе переменных, массивов данных, которые нуждаются в обработке, тем больше оперативной памяти нам необходимо. Во всех МК в качестве оперативной памяти используется SRAM память, а она очень недешево стоит. Поэтому, чем больше памяти у МК, тем он дороже. Сколько памяти необходимо под проект? На этот вопрос очень трудно ответить, основной расход памяти это массивы и глобальные переменные. Любой компилятор СИ при сборке программы показывает затраченный объем памяти, поэтому программа написана, то можно посмотреть сколько необходимо памяти, но если её нет, то остаётся примерно прикинуть. Чем меньше разрядность МК, тем меньшее её обычно нужно. Например на 8-ми битных МК можно встретить 1кбайт оперативной памяти, и его хватает для простых программ. На 32битных бывает 196кбайт ОЗУ и на сложный проект её может не хватить.

Ответ все тот же — чем больше памяти у нас есть — тем дороже МК. Для простых проектов нужен минимальный объем. Чем больше у вас массивов, различных буферов под данные, тем больше нужно памяти. Работа со строками, тоже предполагает увеличенный размер памяти.

Flash память

Это специальная область памяти, которая является энергонезависимой. То есть, она сохраняется при отключении питания МК. Обычно в ней хранится программа или данные программы, которые меняются редко. Ресурс её перезаписи обычно ограничен, хоть и измеряется тысячами раз. Чем больше у нас этого вида памяти, тем более объёмную программу можно использовать в проекте. Это ваш жёсткий диск. Но опять же ограничение - это цена. При переходе на более высокую разрядность опять же объем доступной Flash растёт, но обычно та же самая программа занимает уже больше места. Например 8-ми битные МК имеют 8кб памяти, и это очень много. А 32-ух битные начинаются, как правило, с 32кб, и это не так уж много для них. На первых проектах нам будет хватать 8-ми битных МК с 8 кб на борту.

EEPROM — память данных

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

Если вам нечего хранить, то можно об этом виде памяти не беспокоится. Если вы планируете хранить много данных в этом виде памяти, то её объем важен. Если данных совсем много, то необходимо использовать внешнюю память, в МК обычно этого вида памяти немного — до 10кб.

 

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

Как ядро взаимодействует с другими модулями

Мы познакомились с ядром микроконтроллера, кроме ядра, у МК много других модулей. Основная «сила» МК именно в широком наборе разнообразных модулей. Как же МК общается с ними? Ответ очень простой - через шину данных, ячейки памяти. Существует специальная область памяти в адресном пространстве МК, отвечающая за периферию и другие модули. Она точно так же состоит из регистров, но в данном случае - это внешние регистры, просто ячейки памяти по определенным адресам. Вот через них и производится работа с модулями.

Например, чтобы послать 1 байт данных по SPI интерфейсу необходимо записать этот байт в специальную ячейку памяти по определённому адресу, в регистр данных SPI. После этого, необходимо в другом регистре SPI установить определённый бит в 1, чтобы началась передача данных. Точно также работают все другие модули. С точки зрения нас, как разработчиков, необходимо записывать в определённый адрес памяти данные или менять биты, или считывать бит. Так, через память, производится работа с прочими модулями МК. В дальнейшем, мы будем работать с каждым модулем в реальных проектах, и подробно их изучим. Если вы собрались программировать МК, то вам просто необходимо подтянуть работу на СИ с битовыми операциями. Для экономии памяти, производители плотно набивают регистры, используя каждый бит.

Clock and power management

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

GPIO

Один из самых важных модулей МК. Остановимся на нем поподробнее.

GPIO — general port input output — порты ввода-вывода. Эта периферия отвечает за работу выводов микроконтроллера. Все выводы МК, кроме специальных (питание, GND), сгруппированы в ПОРТЫ, нумеруемые по буквам латинского алфавита PORT A PORT B PORT C. В зависимости от разрядности МК, может быть 8 выводов в одном порту, 16 или 32. За каждый порт отвечает соответствующий регистр, так, что каждый бит этого регистра отвечает за физический вывод МК. Структура регистров может отличаться у разных МК, но общее схематичное устройство выводов совпадает. Рассмотрим как оно выглядит на примере выдержки из datasheet на STM8. Вот схема одного вывода МК.


Разберём эту схему для понимания методики работы с выводами микроконтроллера. Во первых, обратим внимание на защитные диоды, как правило они есть у всех (но их может не быть). Их задача защитить вывод от отрицательного напряжения, превышения напряжения, статического напряжения и других неприятностей. К сожалению, микроконтроллеры очень маленькие, и всё внутри рассчитано на очень небольшие токи. Вы должны сразу запомнить, что выводы МК выдерживают токи не более 30 мА (точные данные смотри в datasheet), а в случае превышения напряжения больше рабочего — ещё меньше — 2 мА. Во вторых, мы видим два транзистора, которые работают в ключевом режиме, и открыт может быть только один из них. Если открыт нижний транзистор, то вывод подключается к GND, и на нем мы наблюдаем логический 0. Если открыт верхний транзистор — то к VDD, и на выводе логическая 1.

Отдельно есть транзистор, который подключает вывод к VDD через резистор (около 50кОм). Такая схема подключения называется PULL-UP. Бывает такой же вариант, но с подключением резистора к GND, тогда это называется PULL-DOWN. При таком подключении, мы имеем на выводе логическую 1, с малым током через резистор PULL-UP, пока закрыт нижний транзистор. Если же его открыть, то на выходе будет логический 0, потому что соединение к GND будет через меньшее сопротивление транзистора. Данная схема очень часто используется в схемах получения данных на выводе с кнопок или других датчиков.

Сам вывод может быть подключён к линии Analog Input - эта линия используется модулем ADC. Также, вы видите Триггер Шмитта на входе вывода. Он необходимо для того, чтобы можно было считать состояние вывода в логическом формате — 0 или 1.

Подведём итоги. Что можно получить с одного вывода МК?

  • МК может выдать (режим OUTPUT) на выводе 0 или 1, если они идут через транзисторы — то это STRONG (сильные) 0 или 1

  • МК может выдать 0 или 1 через резисторы PULL-UP-DOWN, в этом случае они называются WEAK (слабые) 0 или 1

  • МК, через триггер Шмитта, может считать (режим INPUT) логическое состояние вывода — 0 там или 1

  • МК может иметь на выводе неопределённое состояние (HIGH IMPENDANCE — Z), см. Three-state logic, когда ни один транзистор не включен.

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

Также можно заметить, что выводом можно управлять напрямую, через регистр PORTx, или выводом может управлять периферийный модуль. Например, если на вывод подключён модуль UART RX, то вывод может работать как обычный вывод или как UART RX. Это называется альтернативная функция вывода. Производители МК стараются сделать работу выводов с альтернативными функциями как можно более гибкой. Например в STM32 есть возможность подключать UART и другие модули на несколько разных выводов, что упрощает разводку плат. Для того, чтобы не запутаться с выбором альтернативных выводов, производители выпускают специальные визуальные конструкторы, где можно назначить выводы в графической среде.

Для управления выводом обычно МК имеет следующие регистры (на примере STM8):

  • ODR — output data registr — управление состояние вывода — 0 или 1 имеем на выводе

  • DDR — direction data registr — направление вывода — вход или выход.

  • CR1 CR2 — конфигурационные регистры, различные параметры выхода, PULL-UP резисторы и т.д.

  • IDR — input data registr — считывание данных состояния вывода в цифровом формате 0 или 1

Стоит отметить, что в некоторых МК, если вывод находится в OUTPUT режиме, то все равно можно считать данные на нем через IDR регистр. Это можно использовать например для общения по протоколу 1-Wire.

Что можно делать с логическим 0 или 1 на выводе? Зачем это нужно? Самое простое, что приходит в голову - можно светить светодиодом. Если собрать такую схему:

То если подать на вывод 0 — светодиод не горит, 1 — горит. Дальше мы найдём более широкое применение выводам МК.

ADC и DAC

Аналого-цифровой преобразователь АЦП, англ. Analog-to-digital converter, ADC — устройство, преобразующее входной аналоговый сигнал в дискретный код (цифровой сигнал). Обратное преобразование осуществляется при помощи цифро-аналогового преобразователя (ЦАП, DAC). Если вы знакомы с Arduino, то как раз функция AnalogRead и работает через ADC.

Основные параметры ADC

ADC очень важный периферийный модуль в МК. По своей сути, он превращает МК в цифровой вольтметр, и позволяет измерить сколько вольт у нас находится в данный момент времени на определённом выводе МК. Как правило, в МК один модуль ADC имеет несколько каналов (10-16), которые распределены по разным выводам МК, они обозначаются ADC1 ADC2 … ADC10. Также, МК может иметь несколько независимых модулей ADC (в том время как каналы являются зависимыми, сам модуль один, просто на входе стоит мультиплексор, который подключает нужный канал к модулю). Что выдаёт нам этот модуль на выходе? Как по этому значению определить сколько вольт мы имеем на выводе МК? Зачем нам надо знать сколько у нас вольт, какая от этого польза?

ADC измеряет напряжение в диапазоне от 0В до напряжения питания МК или до напряжения на специальном выводе МК — AREF — analog reference. Одним из основных параметром ADC является его разрядность, то есть максимальное количество дискретных значений, которое он может выдать на всем диапазоне входного аналогового сигнала.

Например, если разрядность ADC равна 10, напряжение питания МК равно 3В, то ADC может выдать числа от 0 до 9. Все ADC являются линейными, то есть выходное число линейно зависит от напряжения. Это значит, что одно выдаваемое деление будет соответствовать 3В/10, что составляет 0.3В. В данном примере 0.3В называется Разрешением ADC (минимальное изменение величины аналогового сигнала, которое может быть преобразовано данным ADC).

Разрядность обычно является степенью числа 2, и о разрядности принято говорить как о количестве бит в числе представленном степенью числа 2. Например, 3-х битный ADC имеет разрядность = 8. К сожалению, все ADC имеют погрешность, и это необходимо учитывать при построении программы и выборе нужного модуля по параметрам.

Ещё одним важным параметром ADC является скорость одного измерения. Чем выше разрядность, тем ниже скорость. Обычно скорость одного измерения составляет несколько микросекунд. Как мы уже сказали выше, каналы в ADC, как правило, не являются независимыми. Это все создаёт свои проблемы при проектировании схем для работы с этим модулем. Сейчас мы не будем подробно рассматривать эти сложности. Мы вернёмся к ним, когда будет делать соответствующие приборы.

Как можно использовать ADС

Основное назначение этого модуля — преобразование сигналов с аналоговых датчиков в цифровой формат. Рассмотрим простую схему.

В данной схеме мы имеем NTC-термистр R2, который подключён к выводу МК. Вместе с резистором R1 он составляет делитель напряжения. В зависимости от изменения температуры, будет меняться его сопротивление и на выводе МК будет меняться напряжение, согласно схеме делителя. Измерив получившееся напряжение с помощью ADC, можно рассчитать сопротивление резистора R2 и по нему температуру. Таким образом, мы можем узнать температуру в градусах и оперировать ей в нашей программе. Еще одно применение ADC — считать состояние переменного резистора. Он тоже является делителем напряжения. В данном случае считанное значение позволит определить сопротивление резистора, а значит, положение его ручки. Так можно использовать резистор в приборе — регулировать громкость, скорость вращения и другие параметры в нашей программе.

К сожалению, ADC встроенные в МК обладают низким разрешением (10-16 бит) и невысокой точностью. Но даже таких ADC хватает для большого количества задач связанных с получением информации с датчиков. Когда нужно более точное измерение, используется внешний ADC. Например, для измерения температуры термопары мы будем использовать очень точный внешний 24-х битный сигма-дельта ADC.

Выбирая МК в проект, надо внимательно смотреть на параметры ADC. Сейчас есть МК и с сигма-дельта ADC на борту, правда стоят они дорого.

Назначение модуля DAC

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

Timers

Без всякой скромности можно сказать, что это главный модуль МК (после ядра конечно). Таймер — это что-то связанное со временем, подумаете вы. И будете почти правы. В любой программе на МК все привязано к временным интервалам, и умение измерять время просто необходимо. С точки зрения устройства, таймер — это простой счётчик, который с каждым тактом МК (или выделенной для таймера частоты) может или расти на 1 или уменьшаться на 1. Зачем нужен этот счётчик, как этим всем воспользоваться?

Допустим частота работы МК 8МГц, значит 1 такт длится 125 наносекунд (1/8 000 000). Если в начале запуска счётчика его значение было равно 0, то когда там будет 8 000 000, то пройдёт ровно 1 секунда. Так микроконтроллер может измерять время. Таймер - это один из самых сложных модулей по возможностям настройки. Сейчас мы познакомимся лишь с общими принципами работы этого модуля.

Первый параметр таймера — это разрядность, максимальное число до которого может считать счётчик. Оно также обозначается количеством бит, которое выделено под ячейку памяти счётчика. Например, 8-ми битный таймер может считать от 0 до 256, 16-ти битный от 0 до 65536. В основном в МК вы встретите 8, 16, 32 битные таймеры. Для большей гибкости при работе с таймером производители добавили второй регистр, который называется Предделитель. Предделитель считает от заданного числа до 0, и когда достигает 0, то на 1 изменяется основное значение таймера. То есть он как бы делит частоту таймера. Таким образом, использование предделителя позволяет расширить диапазон счётчика таймера до значения РазрядностьТаймера * Предделитель. В предыдущем примере, чтобы считать секунды можно задать предделитель 8000, и тогда 1 значение счётчика таймера будет равно 1 миллисекунде, а 1000 в нашем счётчике наступит когда пройдёт 1 секунда.

Основные события при работе таймера

При работе с таймерами обычно используются прерывания. Прерывания возникают по определенным событиям. Рассмотрим какие события могут возникать при работе с таймерами.

  1. Обновление таймера, переполнение таймера

  2. Сравнение таймера с определенным числом

  3. Входящее событие — таймер может использоваться для анализа входящего сигнала, в этом случае считается время между изменениями сигнала на выводе с 0 на 1 или наоборот.

Самый просто вариант таймера — считающий вниз таймер. Работает он так. В специальный регистр настройки ARR (auto-reload-registr — регистр автообновления) записывается значение счётчика, с которого начинается таймер. По достижению счётчиком 0, срабатывает прерывание ОбновлениеТаймера, в счётчик опять записывается значение из ARR, и все продолжается дальше.

Точно также работает считающий вверх таймер, от 0 до ARR, потом срабатывает прерывание Переполнения и счётчик обнуляется.


Ещё один вариант таймера с использованием регистра ARR — выровненный по центру таймер, счётчик вверх и в низ.

Второй регистр настройки таймера CRR (capture compare registr — регистр захвата и сравнения), позволяет сформировать прерывание по сравнению значения таймера со значением регистра CRR. Используется обычный таймер считающий вверх, просто при достижении значения CCR срабатывает дополнительное прерывание.


При работе со входными событиями, при изменении состояния входа, срабатывает прерывание, и в число из регистра CRR будет соответствовать времени прошедшему от начала таймера.

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

Примеры использования таймеров

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

  • Организовать счётчик точных временных интервалов. Например мы можем завести переменную miliss, в которой будет храниться количество миллисекунд, прошедшее с включения МК. Запускаем самый просто таймер и так задаём ARR и предделитель, чтобы прерывание срабатывало 1 раз в миллисекунду. В теле прерывания добавляем 1 к переменной miliss. Теперь у нас есть счётчик миллисекунд, и мы можем мигать с нужной частотой светодиодом, и обрабатывать как нам необходимо миллисекундные интервалы.

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

  • По событиям таймера, через определённые настройки, МК может менять состояние выводов с 0 на 1. Таким образом, можно без всяких прерываний и программ можно мигать светодиодом с нужной частотой — 1 раз в секунду.

  • Таймеры можно связывать в цепочки. Событие одного таймера стартует другой таймер. Это позволяет делать сложные замеры времени между разными входными сигналами на разных выводах МК.

  • Таймеры могут инициализировать работу другой периферии. Например по событию таймеру можно проводить замер напряжения модулем ADC. Так мы получим измерения напряжения через равные интервалы времени или в нужные моменты времени.

  • С помощью таймеров можно синхронизировать разные события. После нажатия кнопки, через 3сек зажечь светодиод.


  • Используя регистр CRR можно с помощью таймера генерировать PWM (ШИМ — широтно импульсная модуляция) сигнал. Делается это очень просто. При обнулении таймера, мы на выводе устанавливаем 1, при сравнении 0. Получается такой сигнал. (Он очень важен, и позволяет получить некий аналог DAC на выводе, что в свою очередь позволяет управлять яркостью светодиода, скорость мотора, через специальный драйвер)

 

Таймер и кварцевый резонатор

В качестве генератора частоты работы МК может использоваться внутренняя RC цепочка или внешний кварцевый резонатор или кварцевый генератор. К сожалению генератор на основе RC цепочки очень неточный, погрешность составляет 10% и более. С изменением температуры она растёт. Если на основе такого генератора делать например часы, то они будут все время убегать вперёд или отставать. Получить точное измерение времени не получится. Использование кварцевого резонатора решает эту проблему. Они имеют очень высокую точность, погрешность измеряется в процентах на 1 000 000 тактов (ppm). Их точность не падает с нагревом или охлаждением.

Вы должны запомнить, что если вам необходимо точное измерение временных интервалов, то использование внешнего кварца или генератора необходимо!

Comunications interfaces

Для того, чтобы соединить вместе различные приборы, модули, микросхемы, было придумано большое количество цифровых (передаётся 0 или 1) интерфейсов, шин данных. Какие-то интерфейсы «умерли», а какие-то живут и широко используются по сей день. Некоторые из них настолько стали популярны, что производители микроконтроллеров стали добавлять их поддержку в виде отдельных периферийных модулей. В данном разделе коротко рассмотрим эти модули, что они могут, что дают, как ими пользоваться.

С точки зрения выбора микроконтроллера, вы должны понимать, что любой интерфейс можно запрограммировать в коде МК, и для этого ненужен отдельный периферийный модуль, достаточно модуля GPIO и таймеров (эта техника называется дрыгать ногами). Однако, безусловно, если вам в проекте необходим обмен по данным интерфейсам, необходимо выбирать МК, который имеет на «борту» поддержку всех необходимых шин данных. В отличие от программы в МК, работа модулей производится независимо от центрального процессора и не загружает процессор, вам остаётся только обрабатывать прерывания и пользоваться готовыми интерфейсами.

Вот самые распространённые интерфейсы, которые встречаются в МК:

  • UART - Universal Asynchronous Receiver-Transmitter - Универсальный асинхронный приёмопередатчик

  • SPI - Serial Peripheral Interface - последовательный периферийный интерфейс, шина SPI

  • I2C - Inter-Integrated Circuit — интегрированная шина

  • CAN - Controller Area Network - сеть контроллеров

  • USB - Universal Serial Bus - универсальная последовательная шина

Более подробно интерфейсы взаимодействия будут рассмотрены в других статьях. Здесь мы только приведём способы подключения каждого интерфейса и варианты использования.

UART

Это очень широко используемый интерфейс. Родился он от протокола RS-232, но в настоящее время его возможности гораздо шире. Основные линии данных в нем — RX (чтение данных) и TX (передача данных). Общение по этому интерфейсу идёт асинхронно (может и синхронно) — то есть независимо, во время приёма данных, можно их передавать и наоборот. В данном интерфейсе нет задающей линии CLOCK. Все данные передаются на согласованной частоте.

В отсутствие потока данных на линии передаётся логическая 1. Данные передаются пакетами согласованной длины. Стартовый бит всегда является логическим 0. Он обозначает начало передачи пакета данных. Далее передатчик передаёт данные через равные промежутки времени. В конце посылки может передаваться контрольный бит чётности, для проверки корректности посылки. К сожалению, временные интервалы на разных сторонах могут оказаться разными. Важно, чтобы они не разошлись сильно хотя бы в рамках одного пакета(обычно 8-9 бит). Это основной минус этого интерфейса — частота должна отличаться не более чем на 3% (а лучше 1,5%). Поэтому, если используете этот интерфейс, то лучше сразу позаботиться о кварцевом резонаторе на обеих сторонах, хотя если вы будете работать с прибором в комнате, будет работать без резонатора (основное изменение внутренней частоты происходит из-за смены внешней температуры). Частоту интерфейса принято обозначать в виде скорости отправленных байт, например 9600 байт в секунду. Плюсом интерфейса являются только 2 задействованные сигнальные линии.

Данный интерфейс часто используется для:

  • передачи данных между компьютером (например прибор USB\UART)

  • общения с GPS, GSM модулями

  • загрузки прошивки в МК через bootloader

  • отладки работы программы

С точки зрения программирования МК, для обмена по этому интерфейсу, все очень просто. Необходимо настроить интерфейс на нужную скорость, определить прочие параметры. А дальше, записываете байт в специальный регистр и включаете передачу, периферия сама сформирует пакет битов, добавит бит чётности и т. д. Точно также при получении данных. Включаете режим получения, периферия получит байт, проверит чётность и поместит его в специальный регистр, останется в МК прочитать его. В СИ есть функция для форматирования строк Printf, очень часто она используются вместе с этим интерфейсом. Таким образом, МК может передавать текст на компьютер, и общаться с вами в специальной программе «Терминал».

SPI

Последовательный интерфейс с поддержкой очень высоких скоростей передачи данных - до 30Мгц. Отметим также, что этот интерфейс прост в использовании. Он имеет 3 сигнальные линии:

  • Clock — тактовая частота — по этой линии передаётся тактовый сигнал, clock обеспечивает master, главный

  • MISO — master input slave output — вход главного модуля

  • MOSI - master output slave input — выход главного модуля

По данному интерфейсу обмен может проводится с несколькими устройствами, достигается это за счёт дополнительных выводов CS (chip select) на каждый модуль. Низкий уровень сигнала на выводе CS, означает начало работы с данным модулем. Если у нас, например, на шине SPI три устройства, то надо будет три вывода CS — по одному на устройство. Если у нас одно устройство, то вывод CS все равно нужен, так как он определяет начало и конец обмена данными, сэкономить тут не получится.


Получение данных возможно одновременно с передачей.

Большой плюс данного интерфейса - устойчивость к изменению частоты, она может меняться даже в процессе работы, и вообще может быть любой, важно только не превышать максимальные скорости обозначенные в datasheet.

Если вы выбираете какой-то датчик для проекта, то лучше выбирать датчик на шине SPI. На этой шине работает очень много датчиков, LCD экраны, микросхемы памяти.

I2C

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


Интересно то, что каждое устройство может стать мастером в любой момент времени (но это редко используется из-за сложности алгоритма интерфейса). Для построения шины используют 2 вывода — SDA (данные) и SCL (тактовая частота). Частота может быть выбрана из предопределённых — 100 кГц, 400 кГц, 3мГц (не все устройства поддерживают эту частоту). Использовать меньшую частоту можно, превышать не рекомендуется. Данный интерфейс очень сложный с точки зрения программы в МК. Даже имея готовый модуль периферии I2С, разработчики часто сталкиваются с конфликтными ситуациями при работе с этой шиной. Основной причиной этого является очень сложный алгоритм работы шины, который в идеале имеет большое количество исключений. Не все модули полностью обрабатывают нештатные ситуации, и это приводит к конфликтным ситуациям на шине.

В datasheet на МК обычно подробно описан механизм работы с шиной в режиме прерываний или при работе в основном цикле программы. Стоит отметить, что работа через прерывания гораздо проще, но требует довольно высокого приоритета прерываний на эту шину. Работа в основном цикле сложна и требует перебора различных ситуаций при получении данных.

Каждое устройство на шине должно иметь уникальный адрес. Для различных датчиков, обычно он программируется на заводе, и не подлежит изменению — имейте это ввиду, когда покупаете микросхему. Отметим также, что эта шина часто называется по-разному (из-за того, что изначально она лицензировалась компанией Phillips) — TWI, SCCB, SMBus.

Данная шина часто встречается в датчиках, так как это позволяет расширять набор датчиков за счёт одной шины. Также она встречается при работе с памятью (в основном ПЗУ), image sensors (камеры), бывает даже в датчиках GPS (хотя там в основном UART).

CAN

Данная шина была специально разработана для объединения в единую сеть различных датчиков и исполнительных устройств. Она нашла своё применение в системах «умный дом», автомобильной промышленности, в промышленной автоматизации. Передача данных идёт по двум проводам CAN RX и CAN TX.

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

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

Данную шину рекомендуем использовать только там, где это действительно требуется. Конечная реализация устройства на данной шине будет не дешёвым, за счёт драйверов, их обвязки и т. д. С другой стороны следует отметить, что данная шина на физическом уровне имеет очень высокую помехоустойчивость и ряд других преимуществ:

  • Возможность работы в режиме жёсткого реального времени.

  • Простота реализации.

  • Арбитраж доступа к сети без потерь пропускной способности.

  • Надёжный контроль ошибок передачи и приёма.

  • Широкий диапазон скоростей работы.

  • Большое распространение технологии, наличие широкого ассортимента продуктов от различных поставщиков.

USB

Этот интерфейс настолько распространён, что известен всем. На текущий момент это основной интерфейс подключения периферийных устройств к персональному компьютеру. Если вам необходимо подключать устройство к компьютеру, то вам надо выбирать МК, имеющий данный интерфейс.

Передача данных в USB осуществляется по 2 проводам D+ и D-. Используется дифференциальная сигнальная линия. Шина постоянно разливается, на текущий момент есть стандарт USB 3.0, готовится USB 3.2.

Сам протокол описывать смысла не имеет, спецификация на него очень сложная и многостраничная. Спасает положение дел наличие у производителей МК готовых библиотек для работы по этому протоколу. Как МК может использовать шину USB:

  • Для прошивки — DFU (device firmaware update) стандарт прошивки по USB все чаше встречается в МК. Наличие такой возможности у МК сильно упрощает прошивку — подключаете прибор в компьютер и видите внешний диск, просто копируете туда прошивку и все готово.

  • Для организации COM порта и передачи любых данных на компьютер.

  • Организация устройств ввода — мышка, клавиатура, джойстик, какие-то новые устройства ввода.

  • USB audio устройство — ваше устройство может проигрывать звук с компьютера или получать его.

  • Mass storage device — внешний диск — ваше устройство может давать доступ к флеш карте или внутренним данным, сразу представляя их в виде файлов.

  • USB OTG — вы можете подключать к вашему устройству флешки и другие накопители, звуковые карты и другие устройства также как к компьютеру.

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

DMA

Данная аббревиатура переводится как прямой доступ к памяти. Как мы уже писали выше, любая периферия представлена в МК как ячейка памяти, поэтому в любой программе у вас будет очень много операций копирования информация из одной ячейки в другую. Представим, что нам необходимо получить данные с одного интерфейса, например UART, и отправить их на другой интерфейс, например SPI. Вам придётся прочитать данные из регистра UART и поместить их в регистр SPI, сделать все это в момент получения данных по UART. При этом МК будет занять выполнением этой программы. Вот для того, чтобы разгрузить МК от выполнения таких операций, и была разработана периферия DMA. С помощью этого модуля вы можете настроить копирование области памяти в другую область по событию. Набор событий очень широкий. Таким образом, если за событие взять получение данных по UART, далее настроить копирование данных по адресу UART в адрес SPI, то мы решим данную задачу полностью без участия МК.

Использование данной периферии очень сильно разгружает процессор, особенно при передаче больших массивов данных. Примеры применения DMA:

  • Копирование данных полученных, с ADC или другой периферии, сразу в ячейку памяти. Вам остаётся только работать с некоей переменной в Си, там всегда будут свежие данные датчика.

  • Копирование буфера в периферию, даже с побайтным разделением. Например необходимо передать 100байт по SPI, это можно сделать с помощью DMA.

  • Получение данных с периферии с наполнением кольцевого буфера. Получаем данные с UART и кладем сразу в буфер.

  • Передача изображения на экран из буфера.

  • Копирование одного массива памяти в другой.

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

Прочая периферия

Микроконтроллеры постоянно развиваются, и их производители добавляют все новые возможности за счёт периферийных модулей. На текущий момент есть МК, которые имею цифровой видео интерфейс HDMI и позволяют подключаться к ТВ и мониторам. Есть периферия для передачи звука по интерфейсу SPDIF, I2S, AC97. Управление TFT матрицами. МК имеют специальный модуль для работы с различной внешней памятью FMC (NAND flash, SDRAM, SRAM). Могут выходить в сеть — Ethernet интерфейс тоже на борту. Перечислять можно долго. Подбор МК под проект становится все более сложной задачей.

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

Интерфейс программирования

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

Если вы решили работать с определенным видом МК, вы должны будете приобрести или сделать самостоятельно, как минимум программатор, а ещё лучше отладчик. Наличие схем таких приборов или их низкая стоимость, снижает порог вхождения в данную группу МК. Прежде чем приобретать микроконтроллер, вам надо озаботится о том как вы будете его программировать.

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

С прошивкой дела обстоят немного проще. Производители стараются сделать процесс загрузки прошивки более универсальным. В микроконтроллеры в специальную область памяти встраиваются мини программы Bootloader, загрузчики прошивки. Они работают по широко распространненым универсальным интерфейсам. Сами используемые это:

  • UART — последовательный интерфейс.

  • USB.

  • CAN шина, есть МК которые можно прошивать по CAN шине, очень удобно для обновления прошивки в машине, в труднодоступных устройствах.

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

А вот с отладкой все немного хуже. Самые распространённые интерфейсы отладки:

  • JTAG — используется 5 сигнальных линий, AVR, многие ARM МК.

  • SWIM — используется одна сигнальная линия, только МК STM8, иногда нужен RESET, если планируется программировать МК в спящем режиме.

  • SWD — общий протокол для ARM микроконтроллеров, использует 2 линии.

  • ICSP для МК PIC — PICKIT — свой протокол, свой прибор. Использует 3 линии.

  • ISP — программатор по порту SPI. Используется в AVR. Используется 4 линии.

Здесь перечислены не все интерфейсы, и общее правило простое — под каждый МК нужен свой программатор отладчик.

Все наши проекты, которые мы будем делать, мы будем сопровождать необходимыми программаторами. Их схемы и инструкции по изготовлению смотрите на нашем сайте.

Производители микроконтроллеров и основные классы

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

  • MSP430 — TI

  • PIC — Microchip

  • AVR — Atmel

  • ARM - много производителей

  • STM8 STM32 — STMicroelectronics

  • C8051Fxx, EFM32xx, Precision32 - Silicon Labs

  • LPCxxx ARM - NXP Semiconductors

  • NuMicor ARM - NUVOTON

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

  • stm8

  • stm32

  • atmega

  • nuvoton

]]>
(Super User) Теория Fri, 29 Sep 2017 18:27:27 +0000
Как собирать прибор /index.php/theory/item/25-kak-sobirat-pribor /index.php/theory/item/25-kak-sobirat-pribor

В данной статье мы опишем общие правила сборки любого прибора. Как проверять прибор перед первым включением? Как защитить плату от окисления? В каком порядке паять элементы?

Так как все платы у нас будут подготовлены в Kicad, то вам необходимо сначала установить эту программу с сайта разработчика. Далее необходимо скачать с github выбранного прибора папку с проектом Kicad и папку с общими библиотеками для Kicad.

Запускаете Kicad и открываете файл проекта с расширением «.pro». Первым делом необходимо проверить наличие у вас всех необходимых комплектующих. Все электронные компоненты у вас на схеме, вы можете сформировать перечень компонентов из меню «Инструменты — сформировать перечень элементов». Файл будет сформирован в папке проекта. Необходимо сверить состав с тем, что вы купили у нас в магазине, или в другом месте.

Далее необходимо проверить печатную плату. На всякий случай можно переформировать список цепей, чтобы быть уверенным, что плата соответсвует схеме. Открываем файл платы, загружаем заново список цепей и запускаем проверку «Инструменты — DRC». Вы должны получить пустой список не подсоединённых элементов и нарушений (если в плате специально оставлены нарушения, то об этом будет указано в разделе сборка прибора, если специального указания нет, то нарушений быть не должно!).

Теперь согласно описанию в нашей статье про Kicad необходимо подготовить файлы SVG обеих сторон платы. Далее, если вы делаете плату по нашему методу, то необходимо в редакторе InkScape подготовить файл для печати. Предварительно необходимо распечатать этот файл на обычном листе бумаге и проверить правильно ли определены посадочные места (не забудьте, что на распечатке плата отражена зеркально). Приложить на бумагу разъёмы, микросхемы — убедиться, что все подходит! Таким образом, вы ещё раз проверите, что у вас нет нарушений геометрии при печати. Проверьте как лёг тонер, вы должны увидеть точные чётки чёрные линии. Посмотрите на них под увеличительным стеклом. Все должно быть как на экране компьютера! Если все отлично, то делаем плату дальше согласно нашей статье.

!ВНИМАНИЕ! Перед тем как травить плату, обязательно проверьте геометрию рисунка. Сверьте расстояния между точками по диагональным краям (как минимум 4 точки) на вашей плате и в Kicad. Должно быть идеально точно!

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

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

Переходим к пайке. Тут есть один очень важный нюанс! Во всех приборах есть микросхемы питания - LDO, DC-DC и другие. Стоят они как правило, не дорого. Но если, с ними что-то будет не так, то может сгореть все остальное. Некоторые LDO, когда сгорают, то дают на выход весь вход без регулировки! Поэтому, очень важно, ВЫ ДОЛЖНЫ сначала запаять все микросхемы питания и проверить их после запайки! Подать нужное входное питание и проверить на всех выводах микросхем питания нужного напряжения. Еще лучше проверить их под нагрузкой, хотя бы в виде резисторов - их можно временно припаять.

Далее паяем остальные компоненты на каждой стороне независимо. Перед запайкой многовыводных компонентов и элементов с определённой полярностью обязательно десять раз сверьте номера выходов, отметку первого выхода, плюсовой вывод диодов и т. д. Техника пайки показана в нашем видео. Не забывайте, что лучше не использовать флюсы кроме спиртового раствора канифоли или ЛТИ-120. Начинать лучше с микроконтроллера и других микросхем, резисторы и конденсаторы припаиваем потом. Все выводные элементы паяем уже в самом конце. После того, как вы припаяли все компоненты, посмотрите на просвет, что у вас нет замыканий дорожек. Все проверьте внимательно. Если необходимо — под лупой (можно использовать камеру сотового телефона).

После того как стороны готовы, необходимо их соединить. Соединяем две стороны по переходным отверстиям, если у вас есть желание, можно склеить их эпоксидной смолой, обычно в этом нет необходимости. Когда будете запаивать переходные отверстия, то плотно сжимайте обе стороны, чтобы переходы держали плату. Для запайки можно использовать проводник витой пары или любой другой толщиной 0.4 — 0.5мм. Предварительно его надо залудить и очистить от изоляции. Вставляете его в отверстие платы, если необходимо можно чуть-чуть рассверлить отверстие, делаете так, чтобы проводок торчал на 1мм и запаиваете его. Потом откусываете с другой стороны, оставляя 1мм, плотно сжимаете и запаиваете вторую часть. После того как стороны соединены, запаиваете разъёмы и все что осталось. Если необходимо, можно по краям просверлить отверстия в области земляных полигонов и запаять туда перемычки для прочности конструкции.

Прибор готов! Но включать его пока рано! Необходимо сначала провести базовые проверки обычным мультиметром в режиме проверки диода или сопротивления на градации 200ом.

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

Необходимо проверить, что все земляные полигоны соединены.

Необходимо проверить, что между ВСЕМИ цепями питания и землей сопротивление бесконечно велико (сначала оно может быть мало за счет зарядки емкостей по питанию, но оно должно расти и стать бесконечно большим). Проверять НАДО не только входные цепи питания, но и все цепи питания после регуляторов напряжения.

В статье про прибор могут быть указаны дополнительные проверки — их тоже необходимо провести!

Можно включать прибор. Первым делом необходимо проверить работу всех регуляторов напряжения. Подаём основное питание, и проверяем мультиметром, что все варианты питания соответствуют схеме. Если есть такая возможность, то первое включение необходимо делать от блока питания с защитой от КЗ (короткого замыкания)! Если такого блока питания нет, то вы можете взять 3.3в с нашего прибора ST-LINK, они подаются с регулятора, который защищён он КЗ и выдаёт до 300ма. Этого напряжения хватит, чтобы поработать с МК в обход основных цепей питания. Если все цепи питания на месте, проверьте не греются ли какие-то компоненты, если да, то сразу выключите прибор — возможно где-то есть короткое замыкание. Если все хорошо, то переходим к проверке МК. Подключаем программатор и пробуем соединится с МК — можно попробовать прочитать его флеш память. Если он отвечает — то все отлично. Если нет — то проверяем опять все цепи питания прямо на МК. Проверяем правильно ли подключили выводы программатора и т. д.

Когда прибор готов, переходим к его программированию. Скачиваем с github проекта папку с проектом для МК. Устанавливаем необходимую среду программирования. Загружаем прошивку. Далее согласно программе проверяем работу прибора. После программирования можно разместить прибор в корпусе, просверлить и вырезать нужные отверстия для кнопок — довести прибор до финального вида. Дополнительно вы можете покрыть плату акриловым лаком (пример лака приведён в статье про изготовление платы), делать это желательно в самом конце, когда повторная пайка будет не нужна (хотя его без проблем можно снять и даже паять через него). Перед покрытием лака необходимо закрыть разъёмы, важные датчики бумажкой, чтобы лак не попал туда, куда не следует.

Поздравляем Вас! Вы сделали сложный прибор на микроконтроллере, и он работает. Можно им пользоваться, менять программу, заниматься его развитием, использовать его как тестовый образец — для чего же ещё вы его собирали. Если же вдруг что-то пошло не так, не расстраивайтесь, осмотрите внимательно плату, проверьте не перепутали ли вы местами микросхемы, диоды, транзисторы и другие полярные элементы. Помните! Цифровая электроника прощает много ошибок, но не все. 10 раз проверь — один раз отрежь.

]]>
(Super User) Теория Sat, 30 Sep 2017 11:51:11 +0000
ST Visual develop IDE - среда для программирования STM8 /index.php/theory/item/26-st-visual-develop-ide-sreda-dlya-programmirovaniya-stm8 /index.php/theory/item/26-st-visual-develop-ide-sreda-dlya-programmirovaniya-stm8

В данной статье мы рассмотрим IDE от компании ST для программирования и отладки микроконтроллеров ST7 и STM8. Как установить, где скачать, основные возможности.

{index}

Установка среды и компилятора

Сама программа поставляется компанией ST бесплатно. Скачать её можно с официального сайта ST по этой ссылке. Установка не имеет каких либо особенностей.

Для работы с этой средой дополнительно необходим компилятор. Можно использовать два компилятора COSMIC и REISONANCE. COSMIC ранее был платный, но сейчас его можно скачать здесь и установить абсолютно бесплатно, его и будем использовать. Единственная проблема — ожидание ключа активации — 1-2 рабочих дня. Также необходимо раз в год активировать компилятор заново (проще переустановить).

После установки можно сразу запустить среду, создать новый проект и начать программировать. Но тогда придётся прописать все пути руками. Гораздо проще использовать стандартную библиотеку от ST, вместе с ней поставляется шаблон проекта. Так мы и поступим.

Набор стандартных библиотек для STM8, новый проект

Стандартные библиотеки для STM8 можно скачать здесь. Библиотека поставляем в zip архиве с подробным описанием и широким набором примеров. Внутри она имеет следующий набор папок.


Для создания нового проекта, проще всего скопировать всю папку библиотеки STM8S_StdPeriph_Lib, назвать её по имени проекта, лучше по-английски. Далее из Visual develop IDE необходимо открыть файл проекта:


Лучше сразу связать это расширение с нашей IDE.

При старте нового проекта из шаблона, вы получаете сразу готовые настройки под все МК STM8.


Остаётся только выбрать нужный МК и начать разработку. Остальные можно удалить.

Первым делом необходимо сделать начальные настройки проекта. Нажимаем на нужной серии правой кнопкой мышки и выбираем Settings. В данном окне переходим на закладку MCU selections и выбираем нужный МК:


Далее нажимаем на плюс, открываем файлы проекта, видим файл main.c, нажимаем на нем два раза мышкой и начинаем программирование.

Все проекты для наших приборов будут созданы из шаблона проекта. Соответственно, чтобы с ними работать, вам необходимо скачать папку проекта и запустить ярлык из папки проекта, как написано выше.

Если вам не хватает памяти, то можно отключить обработку исключительных ситуаций. Это делается через файл stm8s_conf.h. Надо закомментировать строку:

#define USE_FULL_ASSERT (1).

В результате освободится довольно много памяти для программы. Также можно заменить простые процедуры библиотеки на прямую запись в регистры.

Настройка использования типовых библиотек СИ

Если вы планируете использовать в проекте стандартные библиотеки языка СИ, например math (функция RAND) или другие, то необходимо, кроме указания в тексте соответствующего #include «math.h», в настройках проекта на закладке Linker, указать использование стандартных библиотек:

Работа в среде

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


Для запуска отладки и прошивки МК — кнопку Debug:


При написании кода по комбинации «CTRL пробел» вызывается подсказка по имени переменной или функции:

По имени функции, по правой кнопке мышки можно быстро перейти в самой функции — команда «Go to defenition».


Это очень удобно использовать для функций стандартных библиотек, чтобы познакомиться как они реализованы.

Если вы используете в проекте внешний кварц, то его частоту придётся задать руками в файле проекта «stm8s.h»:

Работа с прерываниями организована в виде предопределённых функций в файле «stm8s_it.c», остаётся только написать свой код в нужной функции.


Сама библиотека очень хорошо описана в файле «stm8s-a_stdperiph_lib_um.chm» в корне стандартной библиотеке.

Работа с библиотекой достаточно удобная, за исключением немного большого расхода памяти на вызов стандартных процедур, какую то часть функций можно было реализовать просто через «#define»

В данной статье мы не будем подробно описывать, как писать программу для STM8 в этой среде, это будет сделано в статье по приборам на основе этого микроконтроллера.

Симулятор

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


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

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

Отладка, прошивка, оптимизация кода

Для работы с реальным устройством вам необходимо иметь программатор — ST-LINK. В настройке отладки выбираем его, остальные настройки оставляем по умолчанию.


Далее все просто, при начале отладки — программа компилируется, прошивается микроконтроллер и начинается отладка. Если вам необходимо просто прошить МК, то надо начать отладку и после ее начала — прервать ее, по соответствующей кнопке.

В процессе отладки вам доступна возможность установки не более 8 точек останова и возможет просмотр всех переменных, а также состояния внутренних регистров, во время остановки программы. Это очень мощный инструмент, который позволяет изучить, как работает микроконтроллер, а также найти и поправить ошибки в своей программе. Через меню «View» во время отладки вы можете включить нужные окна.


Например, окно «Watch» позволяет просмотреть любые переменные, провести вычисления:


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

Программирование option byte

Для программирования option byte необходимо через меню TOOLS запустить porgrammer. Это отдельное приложение для прошивки МК, через него можно прошить option byte.


Изменение значения осуществляется по правой кнопке мышки. Программирование — на закладке Program по кнопке START. Предварительно на закладке Settings надо задать типа программатора ST-LINK.

Контроль размера прошивки

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


смотреть нужно все позиции, кроме сегмента debug и info.

Там же рядом находится прошивка в формате s19, прошить её можно через UART или другими средствами.

]]>
(Super User) Теория Wed, 04 Oct 2017 14:52:16 +0000
Приемы программирования МК /index.php/theory/item/37-priemy-programmirovaniya-mk /index.php/theory/item/37-priemy-programmirovaniya-mk

В данной статье мы расскажем как программировать микроконтроллеры на Си, как работать с основной периферией. Подробно разберем основные приемы программирования.

{autotoc}

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

Что подтянуть в си

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

Основные типы данных, приведение типов, числовые константы

Константы

Ни одна программа на Си не обходится без констант. Константа может быть определена как переменная с модификатором const, а может просто быть указана в тексте программа.

[code]const int i = 10;  //констант i, равная 10
#define I 10 //константа I определенная через#define
int b;
b *= 2; //константа 2, сразу указанная втексте
[/code]

Лучше использовать вместо const, методы #define. Это позволяет задавать вам константы при сборке программы, используя make в сложных проектах.

Когда вы используете числовые константы не забудьте добавить модификатор типа этой константы.

[code]10  //константа типа int !!!! (2 или 1 байт)
10L //константа типа long (4 байта)
10U //беззнаковая константа
10F //число float
10D //число double
[/code]

Если этого не сделать, то компилятор может ошибиться, и не привести её к нужному типу. Например, 1<< 31 = 0, а вот 1L << 31 = 2 в 32 степени. Программируя микроконтроллеры, вы всегда должны помнить о типе каждой константы, каждой переменной. Это очень важно!

Переменные

Когда вы пишете программу для МК, то у вас обязательно будут какие-то переменные. Очень большое значение имеет тип этих переменных. Вы должны точно знать сколько бит занимает тот или иной тип. К сожалению в Си типы определены не очень строго, например, тип int может занимать 2 байта или 4 байта. Как правило, это зависит от компилятора или выбранной среды программирования. Поэтому когда вы начинаете работать в новой среде, обязательно уточните в документации, сколько байт занимает каждый тип данных.

Во многих библиотеках на Си для микроконтроллеров используются специальные типы, обозначающие точное количество занимаемых бит. Например: uint8_t — этот типа, без знаковое (u — unsigned) целое число (int — integer) длиной 8 бит. Если такие типы определены, лучше использовать их, чем стандартные типы int, char и т. д.

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

[code]u8 i = 255;
u16 b;
b = i * 2; //не явное приведение типа, bбудет равно 254!!!! а не 500
b = (u16)i * 2 //явное приведение типа b = 500
[/code]

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

В МК всегда не хватает памяти, всегда идёт гонка за производительностью. Поэтому, большинство ваших переменных, должно иметь тот тип, с которым комфортно работает микроконтроллер. Например, для 32-х битных МК, это u32, для 8-ми битных u8. Это очень сильно влияет на производительность вашей программы.

Битовые операции

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

  • i << 10 - сдвинуть значение переменной i на 10 бит влево. Если представить значение переменной i в двоичном коде, то данная операция сдвигает все биты влево, на пустое место становится 0, старшие биты теряются. Пример: 0b10000110 << 2 = 0b00011000.

  • i >> 10 — сдвинуть значение переменной на 10 бит вправо.

  • i & 0b111 — логическое умножение, работает оно как обычное умножение, только применяется к каждому биту. Данная операция очень часто используется, для выделения из переменной значения одного бита в условиях. Например, i & 0b100, даст нам 0b100, если третий бит равен 1 и 0 в других случаях, а значит условие if (i & 0b100) сработает, когда третий бит выставлен в 1. Можно сказать, что данная операция является наложением маски на значение переменной.

  • i | 0b001 - логическое сложение. Работает как обычное сложение, только для каждого бита, при этом 1 | 1 = 1, а не 2. Данная операция используется для установки нужных бит в значении в единицу, не затрагивая других бит. Например, i | 0b100, выставит третий бит в единицу.

  • ~ i - логическое отрицание, данная операция меняет все 1 на 0. Очень часть используется вместе с логическим умножением, для снятия нужного бита. Например, i & (~ 0b100) обнулит третий бит в переменной i.

В некоторых микроконтроллерах (например, STM32), есть специальные служебные регистры, установка в которых, определённого бита в 1, снимает бит в нужном регистре. Если есть такие особенности, то предпочтительно использовать именно эти служебные регистры, а не обычные.

Для удобной работы с битами, в Си есть понятие битовые структуры. Например:

[code]typedef struct GPIOx{
u32:0 PIN0;
u32:1 PIN1;
...
u32:31 PIN31;
} GPIOA;
[/code]

Такая структура позволит вам удобно обращаться к битам, через их символьное описание. GPIOA-> PIN0 = 1;

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

Операции сдвига очень часто используются для сборки из байтов длинных переменных. Например, у нас есть 2 байта, надо из них получить число u16:

[code]	(u16) i = (a << 8) | b;
[/code]

Вызов функций по указателю

Очень удобно использовать возможность Си хранить указатель на функцию в переменной. Это позволяет делать универсальные обработчики событий. В переменную помещаем указатель на нужную функцию, и по окончанию какого -то события вызываем эту функцию. Такой приём часто используется в обработчиках прерываний. На Си это выглядит так.

[code]typedef void(*PFN_Callback_t)(void);   //создаем типуказатель на функцию

void * PcallBack; //создаем переменную указательна функцию

PcallBack = (void*)(&func1); //записываем впеременную нужную нам функцию

((PFN_Callback_t)PcallBack)(); //вызываем функцию
[/code]

Разбираем данные на байты

В Си есть функции преобразования типов. Очень удобно с их помощью работать с различными данными. Например, любую структуру можно представить в виде массива байт. Это часто используется, чтобы передать структуру по какому-то протоколу или записать её в EEPROM. Предварительно, вы должны оценить размер структуры в байтах, для этого в Си есть функция sizeOf(), в которую вы передаёте нужный тип. Просто сложить размеры входящих переменных в структуру нельзя, компилятор для оптимизации может использовать выравнивание переменных и добавить пустые байты. Самым правильным будет в отладчике (или в симуляторе) посмотреть размер структуры с помощью функции sizeof() и дальше исходить из этого.

Разберём подробнее как можно «разобрать» данные на байты.

[code]u8 i;
u16 b;
u32 f;
[/code]

Введём три переменные. В любой момент вы можете обращаться к ним как к массиву.

[code]	(u8 *) (&b) [0] = 1;
(u8 *) (&b) [1] = 2;

sendUart( (u8 *) (&f)[0]);
sendUart( (u8 *) (&f)[1]);
sendUart( (u8 *) (&f)[2]);
sendUart( (u8 *) (&f)[3]);

(u8 *) (&f) [0] = readUart();
(u8 *) (&f) [1] = readUart();
(u8 *) (&f) [2] = readUart();
(u8 *) (&f) [3] = readUart();
[/code]

Приводим адрес переменной b к указателю на массив байт. И обращаемся к первому и второму байту. Посылаем по UART 32-ух битное число побайтно и потом собираем его обратно.

Функции, inline

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

[code]inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;

if (i != rx_buffer->tail) {
rx_buffer->buffer[rx_buffer->head] = c;
rx_buffer->head = i;
}
}
[/code]

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

Целочисленная математика и тип float

В микроконтроллерах используется в основном целочисленная математика. Есть отдельные МК, которые имеют FPU (float point) модуль для проведения расчетов с дробными числами типов float и double. Если ваш МК не имеет такого модуля, то вам стоит избегать данных типов в вашей программе. Выполнение операций с данными типами на МК без модуля FPU будет выполняться очень долго. Например, среднее время операции умножения дробных чисел на STM8 занимает 2000 тактов!!!

При работе с целочисленной математикой, вы должны всегда следить за размерностью результата, а также быть осторожнее с операциями деления. Прежде чем делить результат на что-то, для повышения точности, вы должны сначала провести все операции умножения. Например, результат будет разный, если (2 / 100 * 100) и (2 * 100 / 100). В первом случае вы получите 0, потому что, 2 меньше 100 и первая операция деления даст 0. А во втором случае получите единицу, потому что 200 / 100 = 1. Все операции деления в целочисленной математике не имеют остатка!

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

Допустим, нам надо посчитать ток, которое потребляет устройство. У нас есть датчик тока. Каждую секунду мы знаем мгновенный ток. Чтобы посчитать ток, потраченный за минуту, надо каждую секунду делить его на 60 и сложить полученный результат. Но, в целочисленной математике, вам надо сложить все результаты, а потом поделить на 60. То есть, правильнее будет сделать так:

[code]	//вводим две переменные! Для секунд идля тока!
u32 tok;
u32 sec;

//каждую секунду добавляем ТОК, иничего не делим.
sec++;
tok+= gettok();

//когда надо выдать результат, тутбудем делить
sendLCD( tok / sec);
{\ccc]
[/code]

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

Основная модель программирования МК

Если вы в любой среде программирования микроконтроллеров создадите пустойпроект, то увидите примерно такую программу:

[code]#define …
//секция 1

int main() {

//секция 2 - инициализация
while (1) {
//секция 3 - основной цикл
};
}
[/code]

Это не случайное сходство для различных сред программирования МК. В данной мини программе заложена основная модель программирования всех микроконтроллеров. Любой микроконтроллер работает после включения в бесконечном цикле. И вы должны это запомнить. Любая программа для МК никогда не заканчивается. После подачи напряжения, инициализации и старта, МК работает непрерывно, выполняя бесконечно Основной цикл программы.

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

Существует две методики программирования микроконтроллеров:

  • используется только основной цикл — polling (опрос)

  • используются прерывания — interrupt

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

Инициализация

Любая программа начинается с инициализации, микроконтроллеры - не исключение. Первым делом необходимо инициализировать состояние всех внешних портов, настроить периферию, задать параметры тактирования микроконтроллера, произвести прочие настройки.

Данный код выполняется один раз, при включении микроконтроллера. Далее микроконтроллер переходит в основной цикл.

Стадия инициализации длится очень быстро — несколько микросекунд, но по меркам схемотехники, это очень долго. Такого времени вполне достаточно, чтобы сгорели внешние транзисторы или другие детали. Когда проектируете своё устройство, имейте это ввиду. Все важные узлы схемы должны работать при полном отсутствии микроконтроллера! Например, если у вас H — мост управления двигателем, то обязательно должны быть резисторы подтяжки на транзисторах, которые обеспечат нужный уровень без работающего микроконтроллера. Если вы управляете пищалкой, то транзистор должен иметь подтяжку к GND, чтобы без МК транзистор не остался в неопределённом состоянии.

Если вам важно энергопотребление (например, при питании от аккумулятора), то необходимо позаботится об этом на стадии инициализации. Если вы не используете какую либо периферию, то необходимо отключить ее, через специальные регистры. Если у вас остались свободные выводы у МК, необходимо перевести их в Push Pull режим и перевести в выдачу Low сигнала, они не должны оставаться в неопределённом состоянии. Если вам не нужна быстрая обработка данных, надо снизить частоту работы ядра. Все это делается один раз на этапе инициализации.

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

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

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

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

Основной цикл (polling)

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

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

  1. Прочитаем данные с датчика температуры

  2. Произведём необходимые вычисления, чтобы привести эти данные к читаемому виду

  3. Выведем их на экран

  4. Перейдём к п.1

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

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

В данном разделе мы не будем рассматривать то, как МК получает данные от датчика, по какому-то протоколу с использованием периферии, или читая данные с вывода МК. Это будет описано позже. Здесь важно, чтобы вы поняли, как необходимо разделять потоки данных в вашей программе.

Основной цикл должен быть написан максимально без задержек, без использования функций типа Delay(), с чётким разделением всех потоков по временным интервалам. Применительно к нашему термометру, подумаем, как часто нам надо считывать данные с датчика температуры? Если процедура чтения данных будет непрерывно вызываться в основном цикле, то это, при работает МК на частоте 16Мгц, даст нам более 1 млн опросов датчика в секунду. Надо ли нам столько раз его опрашивать, сможет ли датчик выдавать информацию так часто. Об это вы должны думать каждый раз когда пишите какую либо процедуру опроса в основном цикле. То есть первое, что необходимо, это определить частоту, с которой должен выполняться тот или иной кусок программы. Основной цикл должен состоять из большого количества простых условий, вы все время должны проверять различные флажки — состояние выводов, состояние битов в регистрах периферии, значения переменных, эти операции выполняются очень быстро и большую часть времени работы МК, он должен проверять эти флажки. И только в момент, когда это необходимо предпринимать какие-то действия, которые могут выполняться долгое время.

Теперь уточним нашу задачу. Пусть датчик температуры выдаёт данные 10 раз в секунду. Наша программа изменится следующим образом.

[code]	if (timedatchik==0) {
timedatchik = 100;//ms
temp = getdatadatchik();
temp *= 100;
}
if (temp != temoold) refreshlcd();
[/code]

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

А теперь немного отвлечёмся от нашего примера и рассмотрим конструкции, которые наиболее часто используются в основном цикле.

а) Выполнение программы только при изменении состояния датчика.

[code]while(1) {
kn = getdata();
if (knold != kn) {
….
}
knold = kn;
}
[/code]

Создаем две переменные knold и kn, записываем новые данные в kn, сравниваем значение старое с текущим, в конце цикла запоминаем текущее значение kn в переменную knold. Таким образом, мы можем отследить ситуацию изменения значения датчика.

б) выполнение программы с заданной периодичностью:

[code]	if (timedel == 0) {
...
timdel = 10;
}
[/code]

Переменная timdel уменьшается каждую миллисекунду или секунду, когда она равна нулю, то делаем что-то и опять начинаем новый отсчет времени. Так можно программировать работу по временным интервалам.

в) выполнение программы по установленному флажку:

[code]	if (flagset) {

flagset=0;
}
[/code]

Проверяем установлен ли флажок, если да, то делаем что нам нужно, и сбрасываем флаг. Сам флаг устанавливается в другом месте программы.

г) простой автомат

[code]switch (status){
case 10:
...
break;
case 20:
..
break;
case 30:
..
break;
default:
}
[/code]



Теперь мы можем описать схему работы в основном цикле МК.

  1. С нужной периодичностью получаем данные с датчиков

  2. В случае изменения данных датчиков, проводим нужные вычисления

  3. При необходимости производим управляющее действие, что-то выводим на экран, воспроизводим музыку и т. д.

  4. Периодически производим какое-то действие, например, мигаем светодиодом

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

[code]void  getdatadatchik() {
sendbyteI2C(10);
while (bytesending);
sendbyteI2C(10);
while (bytesending);
while (bytereceive==0);
temp = I2Creg->data;
}
[/code]

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

Прерывания

Прерывание (англ. interrupt) — сигнал от программного или аппаратного обеспечения, сообщающий процессору о наступлении какого-либо события, требующего немедленного внимания. Мы не будем вдаваться в тонкости работы механизма прерываний. С точки зрения программирования МК на Си, нам будет достаточно понимания того факта, что в каждом микроконтроллере есть возможность, при наступлении определённого события приостановить выполнение основной программы и передать его в специальную функцию, обработчик данного прерывания. Набор событий зависит от конкретного микроконтроллера, они подробно описаны в datasheets. Рассмотрим, как можно использовать прерывания в вашей программе.

Для лучшего понимания, решим простую задачу — есть кнопка, при её нажатии надо зажечь светодиод. Если мы будем эту задачу решать методом опроса (polling), то мы получим примерно такую программу

[code]	knold = 1;
while (1) {
kn = PORTB->PIN1;//считали состояние кнопки
if ((kn == 0) && knold) {
PORTB->PIN2 = 1;//зажгли светодиод
}
knold = kn;
}
[/code]

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

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

Обработка прерываний построена по принципу очереди. Все прерывания распределены по приоритетам производителем МК, а также есть возможность программно поменять его для каждого прерывания. Вам обязательно надо понять этот механизм и научится им пользоваться. Для этого представим следующую ситуацию, в один и тот же момент времени, сработало прерывание по изменению состояния входа PIN1 — пр1 (приоритет 1), прерывание о готовности данных ADC — пр2 (приоритет 2), прерывание таймера TIM1 — пр3 (приоритет 2). Как же МК поступит в этом случае?

Во первых, МК отсортирует все эти прерывания по приоритету, далее по времени срабатывания и далее просто по внутреннему номеру прерывания — пр1,пр2,пр3. После этого он поставит их всех в очередь, и передаст управление функции, обработчику прерывания пр1. Когда его обработка закончится, то следующему в очереди, и так, пока не обработает все прерывания. У каждого прерывания в очереди есть бит отложенного прерывания (pending bit ), прерывание удаляется из очереди, только когда этот бит будет снят. Как правило, снять этот бит вы должны в обработчике прерывания самостоятельно. Это сделано специально, для того, чтобы МК был уверен в том, что прерывание обработано. Также, такая схема позволяет обрабатывать в одном обработчике несколько различных видов прерываний с разными отложенными битами. Во многих МК есть возможность обрабатывать вложенные прерывания, как правило это включается программно. В этом случае, другое прерывание более высокого уровня может прерывать обрабатываемое. Механизмы реализации тут могут быть разные, более точно необходимо читать в datasheet. Если вам необходимо заняться тонкой настройкой приоритета прерывания, то представьте, что обработчики каждого прерывания выполняется очень долго, и вам надо выяснить остановка какого прерывания может стать для него критической. Приоритет такого прерывания надо сделать самым высоким. И так далее.

Теперь вернёмся к нашей задаче про кнопку. С использованием прерываний программа будет выглядеть так.

[code]void INT1(void) {  // обработчик прерывания
if (PORTB->PIN1==0) {
kn = 1;
}
}

void main(void) {
while (1) {
if (kn) {
PORTB->PIN2 = 1;//зажгли светодиод
kn=0;
}
}
}
[/code]

Функция INT1 назначена на обработку прерывания по изменению значения порта «B». В обработчике прерывания мы проверяем, что кнопка нажата и выставляем флажок. Уже в основном цикле, мы проверяем, что флажок установлен и делаем нужное действие. Можно ли зажечь светодиод не в основном цикле, а сразу в обработчике прерывания? Конечно да, но вы должны понимать, что обработчик прерывания должен выполняться максимально быстро, чтобы не задерживать другие прерывания. Поэтому, там должны быть только простые операции, все сложные вычисления лучше оставить на основной цикл. Внутри прерывания можно смело управлять выводами, читать или записывать переменные, производить не сложные операции. Внутри прерываний желательно не использовать вызовы других функций, нельзя использовать функции зависящие от прерываний (например, Delay).

Прерывания — очень удобный механизм, как правило его используют вместе с основным циклом. Если вы пишите код, на границе возможностей МК по скорости, то вы должны обязательно прочитать в datasheet сколько тактов МК тратит на вход в прерывание — это может быть от 8 до 16 тактов! Как видите - не мгновенно. Также надо понимать, что вести отладку прерываний в реальном времени, не просто, пока отладчик остановится, могут измениться состояния регистров. Поэтому, если вам необходимо понимать сколько времени прошло от события до его обработки, то необходимо использовать debug pin — выводы выделенные для отладки. Самое быстрое, что вы можете сделать — это поменять состояние вывода. И вот это событие, уже необходимо анализировать с помощью осциллографа или логического анализатора — внешнего устройства.

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

Спящий режим

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

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

  • Полная остановка — halt режим, наименьшее энергопотребление, как правило работают только внешние прерывания, именно они и будят МК, например, нажатие кнопки.

  • Остановка с активным таймером пробуждения — active halt, дополнительно работает таймер, который может будить МК через определённые интервалы времени. Такой режим очень подходит, например, для МК, обслуживающего датчик. Прочитали датчик, передали сообщение и опять уснули. При этом, надо понимать, что МК живёт в мире микросекунд. Если он поработает 10 миллисекунд, а спать будет 900 миллисекунд, то потратит одну сотую часть от энергии, постоянной работы. При этом каждую секунду он будет на связи.

  • Остановка с работающей периферией — wait режим, позволяет спать ядру, пока периферия работает. Например, дали задание измерить напряжение, и спать. Результат готов, проснулись, обработали.

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

С точки зрения программирования на языке Си, все довольно просто. Вы должны записать в определённые регистры, что будет работать при остановке ядра, а потом вызвать в коде команду halt() (или аналогичную). На этом месте вашей программы МК уснёт. После выхода из сна, программа продолжится со следующей инструкции после команды halt(). Это очень естественно и понятно, и легко программировать. Дополнительно, в некоторых МК (stm8 и другие), есть возможность работы постоянно в спящем режиме, отвлекаясь только на прерывания, не возвращаясь к основной программе, после обработки прерывания. Это очень удобно. Например, уснули, проснёмся когда 10 раз сработает прерывание от кнопки. Для этого в обработчике прерывания необходимо установить флажок для продолжения сна, пока счётчик не достигнет 10.

Управляем выводами GPIO

GPIO - это самый простой, и одновременно самый важный модуль МК. В основном вся работа с ним сводится к двум операциям:

  • при включении МК надо инициализировать параметры каждого вывода (конечно это можно делать не только при включении МК, но и в процессе работы программы)

  • при работе надо, или прочитать один бит из регистра отвечающего за порт МК, или записать бит

Обычно все выводы МК сгруппированы в порты, и практически все они доступны программно (за исключением специальных выводов — VDD, GND, RESET — иногда и он доступен). Если вы составляете схему самостоятельно, обязательно прочитайте Datasheet на каждый используемый вывод. Во многих МК, не все выводы одинаковые, и некоторые из них имеют большое количество ограничений. Например, STM8S003, выводы I2C, SDA SCL нельзя перевести в HIGH, они работают только как Open Drain вывод. Таким образом, на них нельзя повесить кнопку без внешнего резистора. Обычно вывод, на который подключается внешний кварц, тоже имеет ограничения. Тоже самое касается RESET. Ограничение может иметь вывод программирования МК.

Настройки выводов у каждого МК свои. Но есть общие правила. Каждый вывод может:

  • быть обычным выводом OUTPUT — то есть выдавать 0 или 1 по вашему требованию, иметь PULL UP резисторы, быть выходом Open Drain, быть в неопределённом состоянии

  • быть входом INPUT — то есть иметь возможность программно прочитать состояние выхода, обычно в этом случае используется триггер Шмитта.

  • иметь альтернативную функцию — служить выводом какой либо периферии, например, UART RX, SPI MOSI и т. д.

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

[code]	GPIO_SetMode(P4, BIT2, GPIO_PMD_OPEN_DRAIN);
[/code]

а обращение к выводам может быть такое

[code]	P43=1;  //порт 4, 3 нога в HIGH
P42=0; //порт 4, 2 нога в LOW
[/code]

Если вы разрабатываете программу, то для работы с выводами очень удобно использовать команду #define это позволяет давать выводам имена согласно вашей схеме. Также это позволяет быстро проводить настройку выводов под другую трассировку схемы.

[code]#define BTON PORTB->10 = 1;
#define BTOFF PORTB->10 = 0;

main {
BTON

while (1) {
if( flag ) BTOFF
}
}
[/code]

Прочитать состояние вывода на Си тоже просто. Надо прочитать состояние нужного бита в регистре, отвечающем за порт. Самая быстрая битовая операция (с точки зрения количества тактов) на МК — это установка в единицу одного бита — логическое сложение, поэтому во многих МК, есть специальные регистры, в которых надо установить бит в 1, чтобы задать на выводе состояние 0. Это сильно ускоряет операции с выводами.

Каждый вывод МК имеет ограничения на максимальную частоту меандра. Например, в STM8 максимальная частота меандра на выводе может быть 2 или 10 Мгц. Чем выше частота, тем больше энергопотребление! Поэтому, не следует выбирать максимальную частоту там, где это не надо. В STM32, чтобы получить частоту выше 50Мгц, сделаны специальные ячейки для подзарядки выводов, которые тоже потребляют энергию и их надо специально включать. Также надо иметь ввиду, если частота ножек будет больше 50Мгц, то потребуются специальные решения при трассировке платы, с меньшими частотами проблем не должно возникать. Как правило, программно получить такой меандр на выводе не получится, в основном это возможно только при использовании периферии, например таймеров.

МК имеет на борту большое количество различной периферии. Но производитель не знает, какая периферия будет вам нужна. Поэтому, он оставляет это на ваш выбор. Каждый вывод МК ценный и может служить обычным выводом. Но если вам нужна периферия, то можно задействовать определённые выводы под периферию. В последних моделях МК, периферию можно подключить практически любой вывод МК, на младших, она закреплена на фиксированных выводах. Конечно, это очень удобно, когда можно использовать любые выводы, это сильно упрощает трассировку платы. Поэтому, выбирая МК под проект, имейте это ввиду. Иногда производитель предлагает выбрать из нескольких вариантов выводов для одной периферии. Будьте очень внимательны при таком выборе выводов, может оказаться так, что назначая на определённый вывод UART RX, вы теряете какую-то другую периферию. На текущий момент существуют специальные визуальные конструкторы (см. в конце статьи), которые позволяют упростить этот процесс, практически на все серии МК. Обязательно используйте их, но не доверяйте на 100 процентов, проверяйте по datasheet. Тут лучше 10 раз проверить, один отрезать.

Используя вывод для какой то периферии, производитель, как правило, оставляет возможность настроить сам вывод как вам надо (по любому варианту вывода). Например, ножка UART TX, может иметь режим Open Drain (или PULL UP), тогда 1 в TX будет означать неопределённое состояние ножки, а вовсе не HIGH! Это очень удобно использовать при согласовании уровней. Open drain режим можно использовать для управления выводом с подтяжкой к другому напряжению, отличному от питания МК. Например, МК питается от 3в, а Open drain будет управлять 5В или 1.8В.

Отдельно стоит сказать про выводы, толерантные к напряжению 5В. Например, если МК имеет напряжение питания 3.3В и есть необходимость взаимодействовать с датчиком или другой микросхемой, которая имеет напряжение питания 5В. Различное напряжение питания элементов схемы порождает проблемы согласования уровней, что требует схемного решения. Производители МК специально, для упрощения таких решений, делают часть выводов толерантными к 5В. Это говорит о том, что МК не «сгорит», если подать на эти ножки 5В, вместо 3.3В. В случае HIGH состояния вывода у МК на выводе будет около 3.3В. Такое напряжение воспринимается пятивольтовыми датчиками как логическая единица. Это все позволяет не делать схемных решений по согласованию уровней. Будьте ВНИМАТЕЛЬНЫ — не все выводы толерантны к 5В, а только некоторые. Внимательно читайте Datasheet.

Кнопки

Кнопки - самый часто используемый элемент в приборах. Ничего сложного в их обработке нет. Как правило кнопка подключается одним выводом на GND, а другим к выводу МК. Таким образом, при нажатии, вывод соединяется с GND. Чтобы обработать такой вариант кнопки, необходимо вывод установить в режим работы INPUT PULLUP. То есть, когда кнопка не нажата на выводе должна быть логическая единица, из-за резистора подтяжки к VDD. Если кнопка подключена длинными проводами, то внутренней подтяжки может не хватить, надо использовать внешний резистр.

Обрабатывать кнопки можно как в основном цикле, так и с помощью прерываний. В начале разберём как это делать с помощью прерываний. В разных МК, прерывания на выводах работают по разному. Если есть такая возможность, лучше настроить срабатывание прерывания по падающему сигналу FALL (то есть в момент когда HIGH меняется на LOW), если такое не возможно, то по изменению сигнала PIN CHANGE (в этом случае прерывание будет срабатывать и при нажатии и при отпускании кнопки). Как правило, обработчик прерывания один на весь порт, и если у вас подключено несколько кнопок к выводам одного порта, то в обработчике прерывания надо проверить, какой вывод равен нулю, чтобы узнать какая кнопка сработала. Далее все просто, устанавливаем флажок, что кнопка нажата, и в основном цикле или сразу делаем нужное действие. Код на Си будет выглядеть примерно так.

[code]void INT1(void) {
if (PORTB->PIN1 == 0) {
kn = 1;
}
}

main() {
while (1) {
if (kn) {
kn = 0;
}
}
}
[/code]

Чтение порта сбрасывает Pending бит данного прерывания. В случае обработки кнопки в основном цикле, нужна будет переменная knold, и программа будет выглядеть примерно так.

[code]main() {
while(1) {
kn = PORTB->PIN1;

if (kn==0 && knold) {
//...
}
knold = kn;
}
}
[/code]

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

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

  • По нажатию кнопки зажечь светодиод, по следующему нажатию выключить

  • По нажатию зажечь, по длительному нажатию выключить (3 секунды)

  • По двойному нажатию зажечь и тройному нажатию выключить (в течение 2 секунды 2 нажатия или 3)

Для отслеживания двойного и долгого нажатия нужна переменная таймер, для учёта времени, прошедшего с начала нажатия. Для двойного нажатия также нужен счётчик. Логика простая. Например, выделяем время 2 секунды. Кнопка нажата, счётчик плюс один. Если прошло две секунды, то обнулили счётчик. Если счётчик равен 2, то зафиксировано двойное нажатие. Для долгого нажатия, запускаем таймер после нажатия, и если до его окончания кнопку отпустили, то сбрасываем все и опять ждём нажатия.

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

Таймеры

Таймеры в МК — это вторая самая часто используемая периферия. Вам обязательно нужно изучить, и попробовать на практике, как с ней работать. В разных МК таймеры могут работать по разному, поэтому обязательно читаем datasheet перед начало работы с ними. Мы рассмотрим общие моменты использования таймеров. Чтобы было понятнее, будет рассматривать настройки таймера на примере реальных задач. Названия регистров приведены на примере STM8, у других производителей могут быть выбраны другие названия, но сути это не меняет.

Для начала, разберём самый простой вариант использования таймера — счётчик миллисекунд. Нам необходимо, чтобы переменная milis содержала количество миллисекунд, прошедшее с запуска таймера. Так как, мы считаем миллисекунды, то тип переменной сделаем unsigned long, чтобы быстро не наступило переполнение. Вся работа с таймерами ведётся с помощью прерываний, потому что, очень сложно поймать путём опроса состояния таймера момент перехода таймера через 0, хотя это тоже возможно. Разберем как решается данная задача с помощью прерываний.

Первым делом, необходимо произвести настройки таймера. Потом, запустить его, и далее в обработчике прерывания останется только добавлять единицу к нашей переменной. Так как нам надо учитывать миллисекунды, то необходимо настроить таймер так, чтобы прерывание вызывалось каждую миллисекунду. Как мы ранее описывали в статье про микроконтроллеры, таймер — это простой счётчик, который с каждым тактом МК уменьшается (или увеличивается) на единицу. Основные его параметры — предделитель PSCR (pre scaler register) и максимальное значение счетчика ARR (auto reload register), которое ограничено разрядностью таймера. Необходимо, используя эти два параметра и настроить период срабатывания прерывания. Допустим частота МК 16 МГц и таймер работает на этой же частоте (таймер может работать на частоте отличной от частоты МК). Чтобы прерывание срабатывало каждую миллисекунду, необходимо сделать так, чтобы таймер досчитал до 16 000 и вызывал прерывание. Для этого достаточно установить ARR таймера в 16 000. Для такого большого числа нужно 16 бит. Если таймер имеет такую разрядность, то достаточно в ARR записать (16000 — 1), обычно таймер начинает считать с нуля. Однако, такое не всегда возможно, разрядность ограничена производителем МК. На помощь приходит предделитель. По сути, в этом случае получается два связанных таймера. Сначала, каждый такт, предделитель уменьшается на единицу, и только когда он дойдет до 0, увеличивается счетчик таймера CNT (counter), когда его значение дойдет до ARR, то сработает прерывание. Например, если предделитель будет равен 15 (16-1), то в ARR надо записать уже не 16 000, а 16 000 / 16 = 1000. А если предделитель равен 160, то уже 100 надо записать в ARR. Таким образом, можно пользоваться таймерами и с низкой разрядностью. Естественно, такой таймер не позволит учитывать другой интервал времени, например, каждые 999 миллисекунд. На Cи таймер программируется очень просто, для предделителя и ARR, есть специальные регистры, надо в них записать нужные значения и все.

[code]	TIM1_PSCR = 160;  //предделитель
TIM1_ARR = 100; // максимальное значениетаймера
[/code]

Для запуска таймера необходимо в специальном регистре установить в 1 бит. Дополнительно, может понадобиться включить питание на периферию таймера TIM1. Если нам необходимо, то надо включить обработку прерываний таймера — установить в единицу нужные биты в регистрах. Если вы работаете с библиотекой, то там могут быть готовые функции, которые сразу настраивают таймер. Например, на stm8 это выглядит так:

[code]	TIM1_TimeBaseInit(TIM1_PRESCALER_16, 1000);
TIM1_ClearFlag(TIM1_FLAG_UPDATE);
TIM1_ITConfig(TIM4_IT_UPDATE, ENABLE);
TIM1_Cmd(ENABLE);
[/code]

Первая команда настраивает таймер, задает предделитель и значение таймера. Следующая команда сбрасывает таймер на 0, а следующая запускает обработку прерываний. Последняя - стартует сам таймер. Все, осталось обработать прерывание.

[code] INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
milis++;
/* Cleat Interrupt Pending bit */
TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
}
[/code]

После обработки события, в прерывании необходимо очистить бит отложенного прерывания, иначе обработчик будет вызываться постоянно. Здесь стоит отметить, что если у вас, например, 8-ми битный МК, а разрядность таймера 16-ти битная, то регистр ARR состоит из двух регистров — обычно _High и _Low. Запись в эти регистры должна быть в определённой последовательности, сначала _High, а потом _Low (читайте это в datasheet). На си это выглядит примерно так:

[code]  TIM1->ARRH = (uint8_t)(TIM1_Period >> 8);
TIM1->ARRL = (uint8_t)(TIM1_Period);
[/code]

Мы познакомились с основными регистрами таймера — PSCR и ARR. Что еще можно делать с помощью таймеров? Таймеры могут генерировать ШИМ (PWM) сигнал. Для этого вводится ещё один регистр — сравнения и захвата CCR (capture and compare). Он имеет такую же разрядность как и счетчик таймера CNT. В данный регистр мы можем записать значение, и когда таймер дойдёт до него, то будет вызвано дополнительное прерывание. Таким образом, у нас будет уже два прерывания — когда таймер достигнет до данного значения и когда дойдет до ARR. Если в одном прерывании подать на некий вывод HIGH, а в другом LOW, то получится ШИМ сигнал. Значение CCR будет регулировать скважность ШИМ сингала.




Таймеры могут самостоятельно управлять выводами, без обработчиков прерывания. Это позволяет организовать «железный» ШИМ, без участия ядра МК. К сожалению, не все выводы можно задействовать для управления, обычно они жёстко определены. Это создаёт определённые неудобства при трассировке платы. С использованием же прерываний, можно использовать любой вывод.

Дополнительно, производители МК добавляют в каждом таймере несколько каналов. По сути, это отдельные, таймеры, но связанные общим предделителем и максимальным значением. Значение сравнения CRR у каждого канала может быть своё. Такая схема позволяет на железном уровне синхронно работать всем каналам таймера. В этом случае лучше использовать прямое управление выводами. Самое частое использование эта модель находит в управлении моторами. Специальный бит в регистре настроек таймера позволяет синхронно менять все настройки каналов таймера. Работает это обычно очень просто, вы записываете новые значения CRR и других параметров таймера, но реально таймер не применяет их, пока вы не установите в единицу этот специальный бит. И в этом момент, сразу все значения всех каналов будут обновлены. Также, можно одновременно запускать все каналы. Для управления моторами существует много настроек, которые предназначены для защиты, быстрое выключение всех таймеров по специальному выводу, блокирование настроек таймеров, для запрета случайного изменения, все их необходимо читать в datasheet для конкретного МК.

Таймеры могут помогать декодировать сигналы. Например, вам необходимо посчитать сколько микросекунд прошло между импульсами на определённом выводе МК. Даже если вы будете делать это с помощью прерываний, вы не сможете точно посчитать время из-за работы других прерываний и задержек по входу в прерывание. Если нужно точное значение, то здесь поможет только таймер. При таком использовании, разрядность таймера определяет точность посчитанного времени. По сути одна единица счётчика (с учетом предделителя) — это минимальная единица времени, которую вы сможете учесть. Настраивается тут опять же все просто. С помощью специального регистра, вы переводите таймер в режим учета входа (обычно вывод опять же предопределён), настраиваете ARR таймера, настраиваете уровень сигнала, который вы ждёте и запускаете таймер. В итоге, когда произойдёт нужное событие, будет вызвано прерывание, и в регистре сравнения CRR будет лежать значение, равное времени интервала. Вам остаётся только его перевести в нужную единицу времени, в зависимости от настроек таймера. Где это ещё может понадобиться: декодирования сигнала пульта ИК управления телевизором, декодирование ШИМ сигнала на входе (например, считывание команды с передатчика радиоуправления), декодирование 1-wire сигнала и другие варианты управления по одному проводу.

Таймеры - довольно сложная периферия, имеющая очень широкие возможности. Они также могут:

  • управлять другими таймерами (по срабатыванию одного таймера, запускается другой таймер, особенно это удобно, при декодировании сигнала)

  • управлять другой периферией (считывание ADC синхронно с таймером, с определённый момент, синхронное копирование данных через DMA)

  • генерирование одного импульса нужной длины

  • управление моторами с учетом dead time (время задержки между включением выключением синхронных выводов)

  • управление моторами с получением сигналов от энкодера положения вала

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

Учёт временных интервалов

Практически ни одна программа для МК не обходится без учёта временных событий. Например, каждые 500 миллисекунд считываем показания датчика, через 3 секунды после нажатия кнопки выключить светодиод, пищать каждую секунду, мигать светодиодом каждые 5 минут и т. д. Вы должны легко уметь программировать обработку таких событий. Есть несколько вариантов как это можно реализовать. Все они основаны на таймере, например, миллисекундном. Итак, у нас есть настроенный таймер и обработчик прерывания, который срабатывает каждую миллисекунду, как это настроить мы писали выше. Рассмотрим как можно запрограммировать учет таких событий.

Пусть нам надо каждые 500 миллисекунд включать и выключать светодиод. Необходимо создать переменную timeled, в которую записать значение 500. Далее в обработчике прерывания, каждый раз уменьшать значение этой переменной на единицу. Когда она дойдет до нуля, в основном цикле можно сделать нужное действие и опять записать туда 500. Все повторится сначала.

[code]TIMINT()  {
if (timeled) timeled--;
}

main() {
while(1) {
if (timeled==0) {
//делаем что нужно..
timeled = 500;
}
}
}
[/code]

Конечно, если это задача, помигать светодиодом, то можно это сделать прямо в прерывании. Если же это что-то более массивное, например, обмен с датчиком, то лучше делать все в основном цикле. Напомним ещё раз - обработчики прерывания должны быть очень небольшие и быстрые. Заметьте, что мы используем не увеличивающуюся переменную, а уменьшающуюся. Так у вас не будет проблем с переполнением.

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

[code]typedef struct
{
timer_res_t msec;
timer_res_t start;
void* pCallback;
} Vtimer_t,*Pvtimer;

TIMINT() {
u8 i;

for (i = 0; i < VTIMER_NUM; i++)
{
if (sVtimer[i].msec) sVtimer[i].msec--;
}
}

main() {
while(1) {
for (i = 0; i < VTIMER_NUM; i++)
{
if (sVtimer[i].msec == 0 && sVtimer[i].pcallback != 0) {
((PFN_Callback_t)sVtimer[i].pCallback)();
sVtimer[i].msec = sVtimer[i].start;
}
}
}
}
[/code]

Если нужен какой-то ряд событий по временным интервалам, то в основном цикле вы можете использовать убывающие сравнения со значением переменной.

[code]	if (timled > 300) {
//выполняется от 500 до 300
} else if (timeled > 200) {
//выполняется от 300 до 200
} else if(timeled)
//от 200 до 0
}else {
timeled = 500;//перезапуска таймер
}
[/code]

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

Работа с основной периферией

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

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

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

ADC

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

Механизм работы с ADC очень простой. Вы даёте команду, записывая единицу в специальный бит регистра настроек ADC, на старт измерения, и через какое-то время ADC выдаёт результат в регистр ответа, и выставляет в единицу бит готовности, и если настроено, вызывает прерывание. Далее вы обрабатываете результат. Все это можно делать в основном цикле. Тогда необходимо ждать ответ в цикле, проверяя бит готовности и потом считать полученные данные.

[code]	ADC1.CR1 |= ADCSTART;
while ((ADC1.SR & ADCREADY)==0);
rez = ADC1.DATA;
[/code]

Названия регистров, конечно, могут отличаться у каждого МК, они свои, общего стандарта тут нет. Как долго производит вычисления модуль ADC? Обычно МК содержат не очень быстрые и точные ADC, в среднем одно измерение занимает от 1 до 10 микросекунд и имеет разрядность 10-12 бит. Если вам нужен более быстрый или более точный ADC, то надо подбирать специальный МК или смотреть в сторону внешних специализированных ADC. Там скорость может доходить до 1 наносекунды и точность до 24 бит.

Мы рассмотрели самый простой случай работы с ADC — считывание результата с одного канала. Практически все МК умеют работать с каналами в последовательном режиме и управлять последовательностью опроса выводов. В этом случае, вы задаёте какие выводы надо опрашивать и в каком порядке (обычно прямой или обратный порядок по нумерации выводов ADC1 … ADC10 или ADC10...ADC1) путём записи в регистры настроек. Запускаете ADC, и по готовности каждого результата забираете его в регистре данных. Тут опять же есть разные варианты настроек, МК может начать следующее измерение после того, как вы заберёте предыдущее или работать на скорость, не успели забрать, потеряли данные. Удобнее всего в этом режиме работать через прерывания. Если вам неважна скорость обработки данных, то самый правильный вариант, собирать с помощью прерывания сразу все нужные каналы в один массив данных и потом уже в основном цикле работать с ними. ADC могут работать в непрерывном режиме и единичном. В непрерывном, после одного измерения сразу начинается другое.

Вы должны понимать, что любая работа с ADC требует применения фильтров, это может быть решено схематически — добавляется RC цепочка, или программно, тогда используется цифровой фильтр по специальному алгоритму. Самый простой цифровой фильтр, например, скользящее среднее последних 10 значений. Без использования фильтров возможны выбросы пиков значений, что приведёт к неверной работе вашей программы. Если некуда спешить, то можно сразу получить 5-10 значений и выбрать из них среднее прямо в основном цикле.

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

Если нужна синхронная работа ADC с какими-то событиями, то тут необходимо использовать таймеры. Они могут давать сигнал о начале измерения. Правда это могут не все таймеры, поэтому внимательно читаем datasheet. Если у МК есть модуль DMA, мы его рассмотрим далее, то очень удобно с его помощью, вообще без прерываний, перемещать результаты ADC сразу в массив в памяти. В этом случае вы прозрачно работаете с массивом готовых данных и программа сильно упрощается. Конечно цифровой фильтр в таком случае применить сложнее.

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

К данной периферии также можно отнести компаратор и функцию Analog Watchdog. Эти функции позволяют генерировать прерывание при попадании напряжения на выводе в определённый заданный вами интервал.

UART

UART — универсальный асинхронный приемопередающий модуль. Обычно он может работать и в синхронном режиме тоже, и по сути является универсальным синхронно асинхронным интерфейсом. Возможности этой периферии очень широки. Кроме классического последовательного порта она также может декодировать 1-wire протокол, IRDA (инфракрасный приёмник) декодирование, работа со SmartCard протоколом, мульти процессорный обмен данный с использование адресов.

Рассмотрим самый простой, и наиболее часто встречающийся вариант — классический асинхронный последовательный порт. С точки зрения программирования данного модуля все довольно просто. Как правило есть два регистра данных — полученные данные и передаваемые данные, в некоторых МК это один регистр, через который данные передаются в независимые регистры, недоступные программисту. Перед началом работы необходимо провести инициализацию периферии. Настроить параметры порта, скорость обмена (сейчас есть варианты автоопределения скорости при получении данных), формат пакета (8-9 бит, наличие аппаратного контроля чётности и т. д.). Когда все настроено, остаётся только получать и передавать данные. Например, если мы хотим передать данные, то записываем их в регистр передачи данных и выставляем флажок начала передачи. Ждём выставления флажка, что данные переданы, тогда можно передавать следующие данные, и так пока не передадим все данные. Если мы работаем в основном цикле, то просто в цикле ожидаем нужного статуса и передаём очередной пакет данных. При работе с прерывании, функция отправки выглядит примерно так.

[code]UART_TX_INT() {
data = TxBuffer1[IncrementVar_TxCounter1()];
UART1->DR = data;
if (GetVar_TxCounter1() == GetVar_NbrOfDataToTransfer1())
{
/* Disable the UART1 Transmit interrupt */
UART1_ITConfig(UART1_IT_TXE, DISABLE);
}
}

UART_RX_INT() {
data = UART1->DR;
RxBuffer1[IncrementVar_RxCounter1()] = data

if (GetVar_RxCounter1() == GetVar_NbrOfDataToRead1())
{
/* Disable the UART1 Receive interrupt */
UART1_ITConfig(UART1_IT_RXNE_OR, DISABLE);
}
}
[/code]

Прерывание на передачу данных вызывается каждый раз, когда освобождён буфер передачи данных, в обработчике мы должны просто положить очередную порцию данных в регистр данных, если же это все данные — то необходимо отключить данный вид прерывания. При получении данных, тоже самое, прерывание будет вызвано когда данные будут доступны для чтения, получаем их, если это конец, то отключаем прерывания. У вас может возникнуть вопрос - пока мы будем записывать данные в регистр, линия будет ждать пакета данных и нарушится непрерывная передача? Этого не произойдёт, потому что, на самом деле МК имеет еще один регистр данных (буфер), которые реально передаются, поэтому на самом деле, как только мы положим данные в регистр данных DR, они сначала скопируются в другой внутренний регистр и начнётся передача данных, и когда передача ещё идёт, уже сработает прерывание и мы положим новую порцию данных раньше чем та была отправлена. Так организуется непрерывный поток данных. В более мощных МК, данная периферия может иметь большой буфер в несколько десятков байт для передачи и получения данных, это позволяет работать с очень большими скоростями непрерывных данных.

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

Следует сказать что в Си есть очень удобная функция printf и scanf для формирования строк. Обычно производители МК в своих библиотеках позволяют перенаправить эти функции на UART периферию. В этом случае можно в удобном формате передавать данные на компьютер с вашего устройства через COM порт. Например, в STM8, достаточно оформить следующие функции и поток будет перенаправлен на UART периферию.

[code]PUTCHAR_PROTOTYPE
{
/* Write a character to the UART1 */
UART1_SendData8(c);
/* Loop until the end of transmission */
while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
return (c);
}
GETCHAR_PROTOTYPE
{
char c = 0;
/* Loop until the Read data register flag is SET */
while (UART1_GetFlagStatus(UART1_FLAG_RXNE) == RESET);
c = UART1_ReceiveData8();
return (c);
}
[/code]

UART очень удобно использовать для настройки и программирования вашего устройства по bluetooth или wifi. В этом случае после установки соединения вы просто передаете данные в определённом вами формате по UART. В обработчике прерывания ждёте начала сообщения, наполняете буфер и передаёте сигнал готовности, далее в основном цикле обрабатываете данные и производите нужные настройки.

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

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

SPI

Это самый простой протокол обмена данными, который к тому же, один из самых быстрых из межмикросхемных протоколов. Он предполагает наличие одной линии данных для передачи, одной для чтения, и одной линии тактового генератора. В настоящее время существует модификация QUAD SPI, имеющая 4 вывода данных, работающие в асинхронном режиме, и один тактовый вывод, имеющая очень большую пропускную способность. Если вы работаете с флеш картами, то лучше выбирать МК с данной модификацией, иначе скорость чтения/записи будет низкой.

Следует сразу отметить, что данная периферия может работать как в режиме ведущего (master) так и в режиме ведомого (slave). В случае ведущего, МК генерирует тактовый сигнал, а в режиме ведомого, генерирует сигнал другое внешнее устройство, например, другой МК. Также существует синхронный режим получения данных вместе с передачей по трем линиям, или обмен по двум линиям в двух стороннем режиме.

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

[code]        //ждем окончания передачи когдаможно класть следующий байт
while (SPI_GetFlagStatus(SPI_FLAG_TXE)== RESET)
{
}
/* Write one byte in the SPI Transmit Data Register */
SPI_SendData(TxBuffer2[TxCounter]);
/* Wait the byte is entirely received by SPI */
while (SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET)
{
}
/* Store the received byte in the RxBuffer2 */
RxBuffer2[RxCounter++] = SPI_ReceiveData();
[/code]

В случае с прерываниями, по сути, для МК это будет как бы асинхронная передача, свой буфер на прием и свой буфер на передачу. Буфер передачи будет на шаг впереди. Кладем второй байт, получаем первый, кладем третий, получаем второй и так пока не получим\передадим обе очереди.

Остальные режимы отличаются только параметрами регистров настройки. Настроек как всегда много. Можно задавать какой уровень является тактовым, что делать на линии во время простоя и т. д.

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

Отметим, что в данном протоколе используется также вывод CS — выбор датчика, с которым мы будем общаться. Он необходим даже в случае одного единственного датчика, для получения начального состояния. При включении питания все выводы МК находятся в неопределённом состоянии и датчик может зафиксировать случайные сигналы. Обмен с датчиком производится только при низком состоянии вывода CS.

I2C

Данный протокол широко используется в датчиках, микросхемах внешней памяти. Поэтому им обязательно надо научиться пользоваться. Если у вас есть готовый драйвер обмена по этому протоколу, то проблем нет, однако обычно производитель МК в библиотеках даёт только удобный доступ к регистрам периферии I2C, а полный драйвер надо писать самостоятельно или искать в сети. Полный драйвер написать сложно, он должен уметь обрабатывать все исключительные ситуации, и как правило в сети есть частичные драйвера (они конечно тоже работают, но могут иметь не корректную обработку редких случаев). Поэтому данную периферию очень часто ругают, что реализована она дескать криво и косо производителем МК. Отчасти и это верно, потому что, этот модуль обычно содержит и железные ошибки. Наиболее простой вариант использования данной периферии, когда МК является ведущим, а датчики ведомым. Он обычно работает отлично и отлажен. Ситуация наоборот, работает хуже, а самая сложная — смена ведущего в процессе работы, ещё хуже. Если у вас последний случай, то готовьтесь самостоятельно отлаживать данный протокол и дописывать драйвер. Вам обязательно понадобится внешний логический анализатор. Мы рассмотрим только частый случай, когда МК ведущий. Также, сразу отметим, что реализовывать программный вариант данного протокола это худший случай, выбирайте МК, имеющий данную периферию, если она вам нужна в проекте.

I2C — этот тот случай, когда работать с периферией лучше через прерывания. Однако надо иметь ввиду, что в этом случае прерывания должны иметь очень высокий приоритет! Почему? Сейчас вы это поймёте, но для начала разберёмся как производится обмен по данному протоколу.

Обмен производится по двум линиям — тактовый сигнал CLOCK (SCL) и данные DATA (SDA). Как обычно SCL задает ведущий, а вот данные в этом протоколе могут ходить в обе стороны, протокол двухсторонний. Протокол позволяется общаться сразу с несколькими устройствами находящимися на одной шине. Для этого у каждого ведомого устройства должен быть свой уникальный адрес, ведущему он не нужен. Классическая реализация использует 7 бит под адрес и 1 бит для определения направления данных — чтение (от ведомого к ведущему) или запись (от ведущего к ведомому) (существует расширенная версия 10 бит под адрес). В режиме простоя на обоих линиях должна быть логическая единица. Обмен начинается с того, что мастер формирует сигнал Старт (S), формируя ноль на линии SCL. Передача заканчивается сигналом STOP (P), переход от нуля к единице на линии SCL. Переда началом обмена, мастер обязательно должен проверить, что линия не занята — на SCL логическая единица. Биты считываются при высоком состоянии линии SCL, изменяются при низком состоянии SCL. Самая большая хитрость протокола состоит в 9-м бите — ACK\NACK.


Этот бит подтверждает, что данные получены или переданы. Некорректная обработка этого бита может привести к зависанию линии. Давайте посмотрим на примере, как происходит обмен по данному протоколу. Возьмём datasheet на датчик температуры NCT75, в нем приведены диаграммы сигналов, которые помогут понять, что происходит при обмене по данному протоколу.




Как видно на картинке, начинается обмен с сигнала старт на линии. Далее МК передаёт адрес датчика и последний бит R\W (запись или чтение) — в данном случае запись, низкий уровень. После передачи адреса, если датчик с таким адресом есть на линии, то он отвечает сигналом ACK (низкий уровень), если нет ответа, то сигнал будет NACK (высокий уровень) и МК должен закончить передачу, подав сигнал стоп. Далее МК передаёт адрес регистра указателя с которым дальше он будет работать. Датчик опять отвечает ACK, что означается, что данные получены. МК завершает передачу сигналом стоп.




Если надо записать один байт в какой то регистр, то сначала надо выбрать адрес регистра, а потом не передавая сигнал стоп, сразу же передать записываемый байт, и завершить сигналом стоп. Таким образом, вроде все легко и понятно. Алгоритм простой: проверили линию, если линия свободна, подали сигнал старт, далее передали адрес и указали, что будем делать — записывать или читать. Далее получили ответ от датчика, что все хорошо. Передали записываемые данные и завершили передачу данных. Если делать это все руками, в основном цикле, то особенных проблем нет (в этом просто случае). Но если работает периферия I2C, то у нас получается асинхронный обмен с этой периферией. И если не успеть отреагировать на ответные сигналы ACK\NACK или не успеть передать их на линию, то вся система разрушится. По какой причине можно не успеть? Допустим мы работаем по прерываниями. МК передал адрес и получил ACK, пора передавать сам байт данных. Вы должны его положить в специальный регистр. МК вас оповестит и вызовет прерывание, в котором вы и должны это сделать. Но если у прерывания низкий приоритет, то его может прервать другое прерывание и вы продолжите чуть позже.. весь пакет может нарушится. В итоге, если вы пользуетесь прерываниями, то приоритет у I2C должен быть высоким. Особенно, если вы работаете на высоких скоростях (есть возможность работать на скоростях до 3МГц).

Теперь, рассмотрим этот процесс поподробнее со стороны периферии МК. Так как периферия работает асинхронно, то почти во всех МК, можно считать, что она работает через буфер. Разберём, на примере STM8, как работает передача данных.


На данной схеме события, которые отслеживает МК отмечены как EVx (на все эти события может быть назначено прерывание). Генерируем старт, записываем бит в специальный регистр. EV5 — в статус регистре выставляется флажок, что старт сгенерирован. Это событие нужно для того, чтобы вы положили байт с данными (адрес) в регистр данных. Далее периферия сама его отправит и проверит, что получен ACK. EV6 — адрес корректно отправлен, если он не было получен, то этого события не будет. EV8_1 — Регистр данных пустой, можно записывать данные, записываем туда данные. EV8 — данные начали передаваться, они лежат в буфере, а вот регистр данных пустой — можно записать следующий байт, хотя передача первого ещё идёт. Как вы видите мы работает наперёд, когда идёт передача первого байта, уже записываем второй байт, и т. д. Это позволяет МК работать на быстрой скорости непрерывно. EV8_2 - в конце мы проверяем, что байт передан и получен, и генерируем сигнал стоп. Уже видно возможные ошибки, если не обработать корректно, что нет ответа при передаче адреса от датчика, то можно ждать ответа бесконечно. Если байт прошёл с ошибкой, то надо начать сначала или повторить байт. Все эти ситуации надо обрабатывать, а это усложняет разработку драйвера. Конечно на практике, это все можно не обрабатывать, если у вас один два датчика, то в ошибок скорее всего не будет. Но вот если, например, в квадрокоптере по I2C идёт общение с главным датчиком - акселерометром, то из-за не обработанной ошибки, он просто упадёт. В проекте Paparazzi UAV, разработчики написали полноценный драйвер, можете оценить его сложность.

С получением данных ещё сложнее. Проблема в том, что МК должен подтверждать полученные данные сигналом ACK, а последний байт NACK и потом стоп. Посмотрим диаграмму.


Начало тут такое же. Передаём старт, потом адрес. EV6 — говорит, что адрес передан, а далее, EV7 — Rx буфер заполнен, можно читать данные. Опять же, МК работает на перед. Пока мы читаем данные DATA1, он уже получает данные DATA2, поэтому, для того чтобы корректно завершить получение данных, необходимо действовать строго по datasheet. А именно, в момент EV7_2, не считывая данные из регистра данных, необходимо дождаться статуса получения следующего байта в буфер, BTF — передача байта завершена. В этом случае, DATAN-2 будет в DR регистре, DATAN-1 уже в буфере, и вот тут надо уже установить признак NACK, так как он будет относится к следующему байту — то есть последнему! Потом надо прочитать DR, там DATAN-2, и уже выставить статус STOP, он будет относится опять же к следующему байту, последнему, и после этого прочитать DR опять, там DATAN-1. Остаётся получить последний байт после статуса EV7. Выполнять последние команды необходимо с отключёнными прерываниями, чтобы никто не нарушил данный процесс. Если же посылка у нас всего из двух байт, то ситуация меняется, и действовать надо раньше, сразу после получения подтверждения передачи адреса. А если мы читаем один байт, то NACK надо выставлять до очистки статуса получения адреса, а стоп выставлять сразу после очистки статуса получения адреса.

Вот так запутано работает данная периферия в режиме без прерываний. С прерываниями же все проще, достаточно перед получением последнего байта установить NACK и STOP в обработчике прерывания. Но прерывания должны иметь максимальный приоритет.

Дополнительно стоит отметить, что, есть ещё событие RESTART, вместо STOP и следом START, и некоторые датчики ждут полного завершения и старта заново, а некоторые сразу ждут RESTART между посылками.

С драйвером мы разобрались. Теперь осталось немного примеров, как работать с датчиками. Обычно все датчики работают по I2C по общему принципу. Сначала мы передаём в режиме записи номер регистра из которого необходимо прочитать данные, а потом в режиме чтения читаем нужное количество байт. С I2C удобно работать сразу в пакетном режиме. Создаём буфер (массив), и создаём процедуру, в которую передаём указатель на этот буфер, количество байт на запись, количество байт на чтение. Первый байт в буфере всегда адрес, второй байт — номер регистра, а дальше полученные данные. С такой процедурой общение по I2C становится гораздо удобнее. Так как протокол общения по I2C не очень быстрый (100-400кГц), то удобно также наш буфер снабдить функцией обработчиком данных, и как только они будут получены, то будет вызвана данная процедура. Примерно так выглядит обмен в этом случае.

[code]	buf[0] = addr;
buf[1] = 0x45;
readi2c(buff,1,2, &func);//передать 1 байт,прочитать 2 байта и вызвать функциюfunc…
[/code]

Мы даём задание прочитать 2 байта по указателю 0x45 и вызвать функцию func, если все успешно. Далее в функции просто обрабатываем нужные данные.

EEPROM

Данный вид памяти используется для хранения энергонезависимых настроек и параметров вашей программы. Размер этой области не очень большой, но и хранить нам много не надо. Работа с EEPROM ведётся как с обычными переменными, по сути надо просто записать или прочитать данные из определённого адреса памяти. Производители МК специально защищают данную область памяти, делая её доступной только после определённых команд, чтобы случайно не стереть её по ошибке.

Таким образом, вы сначала должны разблокировать доступ к области памяти, далее записываете данные и опять блокируете. Обычно стирание памяти производится медленно, а запись быстрее. Поэтому производители МК специально делают две команды - стереть данные в памяти и записать данные в память. Также может быть одна объединённая команда, запись сразу со стиранием. При этом стёртая ячейка, как правило, содержит все 1, а не 0!

Разные МК имеют различные режимы записи в этот вид памяти. Практически у всех есть побайтный режим, может быть режим записи сразу двух байт, четырех, стирание может производится только постранично. Это все необходимо читать в datasheets.

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

Watchdog timer

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

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

DMA

DMA — direct memory access — прямой доступ к памяти. Это очень полезная периферия. Она имеет очень много различных настроек. Здесь мы разберём только основные принципы её использования.

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

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

[code]	volt = ADCDATA;
[/code]

В переменную volt кладем данные из регистра ADC. Но, как вы понимаете, такая конструкция отвлекает от важных дел наш центральный процессор. Он должен прервать основную программу и выполнить эту одну команду. Вот, чтобы этого не делать, и нужна периферия DMA. Достаточно ей дать задание - копировать из области памяти регистра ADCDATA в область памяти переменной volt, по наступлению события — ADCREADY (ADC посчитал результат). Например, на STM8L это будет выглядеть так:

[code]#define ADC1_DR_ADDRESS        ((uint16_t)0x5344)
#define BUFFER_SIZE ((uint8_t) 0x01)
#define BUFFER_ADDRESS ((uint16_t)(&volt))

SYSCFG_REMAPDMAChannelConfig(REMAP_DMA1Channel_ADC1ToChannel0);//присоединяем событие окончания ADC кDMA каналу 0

DMA_Init(DMA1_Channel0, BUFFER_ADDRESS, //какой каналADC и куда
ADC1_DR_ADDRESS, //откуд
BUFFER_SIZE,//размер буфера
DMA_DIR_PeripheralToMemory,//из другойпериферии в память
DMA_Mode_Normal, //нормальный режим илимассив
DMA_MemoryIncMode_Inc,
DMA_Priority_High,
DMA_MemoryDataSize_HalfWord);

//включаем канал0
DMA_Cmd(DMA1_Channel0, ENABLE);

//если нужно включаем прерывание
//DMA_ITConfig(DMA1_Channel0, DMA_ITx_TC, ENABLE);

//включаем DMA периферию
DMA_GlobalCmd(ENABLE);
[/code]

Один раз производим настройку, задаём откуда, куда, сколько байт, какими партиями копировать данные (по байту или 2 байту и т. д.) и запускаем в работу периферию. Теперь, когда ADC закончит вычисления, то он даст команду DMA и она скопирует данные в нашу переменную. Нам же останется просто работать с переменной volt, там будет всегда свежее значение данных.

Конечно, для такого простого случая DMA не нужен. Но возможности этого модуля гораздо шире. Он может работать с массивами данных, кольцевыми буферами, а это уже гораздо интереснее. Например, можно считывать данные последовательно с 4 каналов ADC и помещать их в массив. Можно запускать работу DMA по таймеру. Можно просто копировать большие объёмы данных без нагрузки на процессор. Можно перекладывать данные из одной периферии в другую, например, с UART в SPI. Можно получать данные с UART сразу в буфер. Можно передать массив данных сразу на UART или SPI.

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

Генераторы кода

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

Такие программы сейчас есть практически у всех линеек МК. Рассмотрим кратко основные.

STMCube

STM8CubeMX — это программа от компании ST предназначенная для конфигурирования STM8 серии МК. К сожалению, код она писать не умеет, но может посчитать энергопотребление вашей схемы. Также поможет рассчитать схему тактирования CPU и периферии. Однозначна полезная программа.




STM32CubeMX — серия для STM32. Этот продукт уже гораздо более серьёзный. По сути это не только конфигуратор, генератор кода, но ещё и набор библиотек для разных серий МК. Правда, к этим библиотекам до сих пор есть много нареканий, с точки зрения ошибок и производительности, но это очень удобный механизм. По сути вы получаете сразу готовый проект, со всеми библиотеками, с настроенной периферией, с обработчиками прерываний и т. д. Остаётся только писать свой код.






MPLab IDE

Микроконтроллеры компании Microchip можно настраивать сразу в среде разработки MPLab IDE. Среда отхватает серию PIC и dsPIC. Настройка производится на уровне конфигурирования библиотек. Ранее было отдельное решение MPLab VDI для визуальной настройки, но оно больше не поддерживается.

Существует онлайн верия IDE MPLab Express по данному адресу. Там же есть MPLab Code Configurator.




Все очень наглядно и удобно. Также можно добавить наличие большого количества доступных для разработки библиотек.

ATMEL Start

Компания ATMEL имеет он лайн конфигуратор доступный по этому адресу http://start.atmel.com/. Тут даже есть готовые примеры проектов. Генерация кода, готовый проект. Визуальный выбор периферии. Все, вплоть до покупки самого МК.




Если вы только начинаете работать с МК, то попробуйте этот конфигуратор.




Кроссплатформенная разработка

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

Для серии ARM-Cortex M3-M0-M4 есть очень хорошая библиотека LibOpenCM3 для работы с периферией под GCC, распространяемая бесплатно. Она очень часто используется в Open-Source проектах. Поддержка большого количества ARM микроконтроллеров — STM32, NXP LPC1000, EXM32, Atmel SAM3U и другие. Библиотека хорошо документирована и позволяет писать кросс платформенные проекты. На ней написано очень много проектов, откуда смело можно брать код.

Для серии ATMEGA — существует проект Arduino, под который написано очень много готовых библиотек, работа со всевозможными датчиками, управление внешней памятью, чего там только нет. Arduino может работать на разных процессорах и код будет общий.

Учитывая, то что эти библиотеки и примеры написаны на Си, то их всегда можно скопировать с одного микроконтроллера на другой.

Если вы собрались делать проект под разные устройства, то стоит обратить внимание на эти библиотеки.

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

Вообще же стоит рассчитывать на то, что вы пишите уникальный софт под конкретный микроконтроллер. Поэтому надо хорошо подумать, когда вы выбираете МК — хватит ли его на все ваши задачи. И не бойтесь использовать различные МК, выбирайте тот, который вам нужен, а не тот, который вы знаете.

]]>
(Super User) Теория Sat, 06 Jan 2018 18:58:28 +0000
Как управлять мотором постоянного тока /index.php/theory/item/39-kak-upravlyat-motorom-postoyannogo-toka /index.php/theory/item/39-kak-upravlyat-motorom-postoyannogo-toka

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

{autotoc}

Двигатель постоянного тока

Для начала рассмотрим повнимательней обычный двигатель постоянного тока. Любой двигатель имеет две основные части - ротор и статор. В коллекторном двигателе статор — неподвижная часть, состоит из постоянных магнитов (или в более мощных двигателях электромагнитов). Ротор (якорь) — вращается, совмещён с валом двигателя и состоит из многих катушек (как минимум трех). Коллектор (щёточно-коллекторный узел) отвечает за переключение выводов катушек ротора. Ток в таком двигателе подводится к катушкам ротора через скользящие контакты (или щётки). В один момент времени подключена только одна катушка, она и создаёт момент вращения двигателя за счет проходящего тока.

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




Когда мотор подключён источнику постоянного тока и еще не начал вращаться, то он представляет из себя обычное сопротивление. То есть через него течет ток согласно закону Ома и сопротивлению его обмотки. Преобладает компонента R. Индуктивность начинает влиять когда напряжение не постоянное, например, если мотор питается от ШИМ (PWM) сигнала.

Сопротивление ротора и индуктивность, как правило, очень малы. Его можно померить обычным мультиметром. Небольшие модельные моторы имеют сопротивление 1-10 Ом. Поэтому, при старте мотора (когда он ещё не начал вращаться), ток сильно превышает рабочий ток мотора и если мотор долго будет неподвижен (его заклинило), то такой высокий ток может привести к перегреву мотора и выходу из строя.

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

Во время вращения катушки ротора начинают вырабатывать ток (как генератор) - возникает обратная ЭДС. Чем быстрее вращается ротор, тем выше обратная ЭДС возникающая в катушках, а так как она направлена против напряжения питания, то ток потребляемый мотором снижается.

В дальнейшем нам понадобятся следующие выводы:

  • пока мотор не начал вращаться он является сопротивлением

  • если приложить к мотору изменяющееся напряжение (например PWM), то индуктивность будет иметь большое влияние, она будет сопротивляться изменению тока через мотор

  • когда мотор вращается, то он является генератором, и за счет этого потребляемый ток снижается (итоговое напряжение равно V — Vbemf).

Как подключить мотор к МК

В данной статье мы будем разбираться как управлять с помощью МК скоростью и направлением вращения обычным двигателем постоянного тока.

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


Максимальной мощности (Torque — крутящий момент) мотор достигает при максимальном токе. И зависимость тока и момента — линейная. Максимальной скорости двигатель достигает при отсутствии нагрузки (на холостых оборотах), при увеличении нагрузки скорость вращения падает. Номинальное рабочее напряжение указано в паспорте на двигатель и именно для него и приведён и этот график. Если же снижать напряжение, то скорость вращения, и все остальные показатели будут тоже падать. Как правило, ниже 30-50% от номинального напряжения мотор перестанет вращаться. Если же мотор не сможет прокрутить вал (его заклинило), то по сути станет сопротивлением и потребляемый ток достигает максимальной величины, зависящей от внутреннего сопротивления его обмоток. Обычный мотор не рассчитан на работу в таком режиме и может сгореть.

Посмотрим как меняется ток от нагрузки на реальном моторе R380-2580.


Мы видим, что рабочее напряжение данного мотора — 12В, потребляемый ток под нагрузкой — 1.5А. Ток останова мотора вырастает до 8А, а в холостом же вращении, потребляемый ток равен всего 0.8А.

Как мы знаем, порт микроконтроллера не может выдать ток больше 50мА, и напряжение питания 12В для него слишком большое. Для управления моторами нам понадобится электронный ключ — транзистор, возьмём обычный биполярный транзистор NPN и подключим его по следующей неправильной схеме.




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

Как мы уже знаем одна из компонент мотора — индуктивность - сопротивляется изменению тока. Поэтому, когда мы закроем транзистор, чтобы выключить мотор, то сопротивление транзистора резко увеличится и он перестанет пропускать через себя ток. Однако индуктивность будет сопротивляться этому, и для того, чтобы удержать ток на прежнем уровне, по закону Ома, напряжение на коллекторе транзистора начнёт резко повышаться (может достигнуть даже 1000В, правда очень на малое время) и транзистор сгорит. Чтобы этого не произошло необходимо параллельно обмоткам мотора поставить диод, который откроет путь для обратного напряжения и замкнёт его на обмотке мотора, тем самым защитит транзистор.

Также, все постоянные моторы имеют еще одну неприятность — при вращении механический контакт в коллекторе не идеален, щётки искрят в процессе работы, создавая помехи, что может привести к сбою микроконтроллера. Чтобы снизить эти помехи, необходимо использовать конденсаторы небольшой ёмкости, подключенный параллельно выводам мотора (как можно ближе к самому мотору). Вот окончательная правильная схема (диод может быть не обязательно Шоттки, но он предпочтителен).




Биполярные транзисторы в открытом состоянии они ведут себя как диоды (на них падает около 0.7 В). А это, в свою очередь, вызывает их большой нагрев на больших токах и снижает КПД схемы управления мотором. Поэтому лучше управлять моторами с помощью полевых (MOSFET) транзисторов. В настоящее время они достаточно распространены и имеют невысокую цену. Их низкое сопротивление в открытом состоянии позволяет коммутировать очень высокие токи с минимальными потерями. Однако и у них есть свои недостатки. Так как MOSFET транзисторы управляются напряжением, а не током (и обычно оно составляет 10В), то нужно или выбирать специальные логические MOSFET, которые могут управляться низким напряжением — 1.8 .. 2.5В или использовать специальные схемы накачки напряжения (драйверы полевых транзисторов). Как выбирать MOSFET под вашу схему мы рассмотрим в других статьях, на конкретных приборах.

Теперь, подавая на выход микроконтроллера логическую единицу, мы заставим мотор вращаться, а логический ноль — остановится. Однако вращаться он будет с постоянной скоростью и только в одну сторону. Хотелось бы иметь возможность менять направление вращения мотора, а также его скорость. Рассмотрим, как этого можно добиться с помощью микроконтроллера.

H-Мост — меняем направление вращения мотора

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


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




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

Если в вашей схеме будет использоваться высоковольтный мотор постоянного тока (больше 24В) или мощный мотор с токами более 10А, то лучше использовать специальные микросхемы — драйверы MOSFET транзисторов. Драйверы управляются, как правило, сигналами микроконтроллера от 2 до 5В, а на выходе создают напряжение необходимое для полного открытия MOSFET транзисторов — обычно это 10-15В. Также драйверы обеспечивают большой импульсный ток необходимый для ускорения открытия полевых транзисторов. С помощью драйверов легко организовать управление верхним N-канальным транзистором. Очень хорошим драйвером является микросхема L6387D от компании ST. Данная микросхема хороша тем, что не требует диода для схемы накачки напряжения. Вот так она подключается для управления H-мостом на 2-х N-канальных транзисторах.


N-канальные полевые транзисторы, стоят дешевле P-канальных, а также имеют меньшее сопротивление в открытом состоянии, что позволяет коммутировать большие токи. Но ими сложнее управлять в верхнем положении. Проблема использования N-канального транзистора в верхнем ключе состоит в том, что для его открытия нужно подать напряжение 10В относительно Истока, а как вы видите на схеме там может быть все напряжение питания мотора, а не 0 вольт. Таким образом, на базу необходимо подать 10В + напряжение питания мотора. Нужна специальная bootstrap схема для повышения напряжения. Обычно, для этих целей используется схема накачки напряжения на конденсаторе и диоде. Однако такая схема работает только, если вы постоянно подзаряжаете конденсатор — открывая, закрывая нижний транзистор (в ШИМ управлении). Для возможности поддерживания верхнего транзистора постоянно открытым нужно еще усложнять схему — добавлять схему внешней подпитки конденсатора. Вот пример схемы управления N-канальными транзисторами без использования микросхем драйверов.




Перейдём к управлению скоростью вращения мотора.

ШИМ сигнал — управляем скоростью вращения мотора

Моторы постоянного тока имеют линейную зависимость скорости вращения от приложенного напряжения. Таким образом, чтобы снизить скорость вращения, надо подать меньше напряжения. Но надо помнить, что с падением напряжения, у мотора падает мощность. Поэтому, на практике, можно управлять скоростью мотора только в пределах 30%-50% от полной скорости вращения мотора. Для управления скоростью мотора без потери мощности, необходима обратная связь от мотора по оборотам вращения, например как в электрическом шуруповерте. Такой режим управления, требует более сложной схемы. Мы же будет рассматривать простой вариант — управление скоростью мотора без обратной связи.

Итак, нам необходимо менять напряжение подаваемое на мотор. В нашем распоряжении есть MOSFET транзистор. Мы помним, что наш мотор имеет индуктивность. Индуктивность сопротивляется изменению тока. И если быстро включать и выключать напряжение на моторе, то в момент выключения ток будет продолжать течь благодаря индуктивности. А мотор будет продолжать вращаться по инерции, а не остановится. Но естественно, вращаться он будет медленнее, среднее напряжение на его обмотках будет меньшее.

Микроконтроллер, как раз, отлично умеет генерировать импульсный ШИМ (PWM) сигнал. А мотор умеет интегрировать данный сигнал (усреднять) за счёт индуктивности обмоток и инерции ротора. От коэффициента заполнения (скважности) ШИМ сигнала как раз и будет зависеть полученное мотором среднее напряжение, а значит и скорость.

Какая же частота ШИМ нужна для лучшего управления мотором? Ответ очень простой, чем больше, тем лучше. Минимальная частота зависит от индуктивности мотора, а также массы ротора и нагрузки на вал мотора. Если смоделировать в электрическом симуляторе (например, PROTEUS) ШИМ управление мотором, то будет видно, что чем больше частота ШИМ, тем более ровный ток протекает через мотор (ripple current — снижается при увеличении частоты). Низкая частота:


высокая частота:




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




Отлично, все просто! Делаем частоту ШИМ побольше, например 1 МГц, и любому мотору хватит. В жизни же, все не так просто. Для понимания всех возможных проблем можно упрощенно принять затвор MOSFET транзистора за идеальный конденсатор. Для того чтобы транзистор полностью открылся, конденсатор необходимо зарядить до 10В (на самом деле меньше). Чем больше ток, который мы можем вкачать в конденсатор, тем быстрее он зарядится, а значит быстрее откроется транзистор. В процессе открытия транзистора, ток и напряжение на нем будут максимальными, и чем больше это время, тем сильнее нагреется транзистор. В datasheet обычно есть такой параметр как Qgate — полный заряд, который надо передать транзистору, чтобы он открылся полностью.




Чем меньше эта величина, тем меньшей ток нужен для управления данным транзистором. Естественно, такой ток нужен только на очень короткое время — какое, опять же написано в datasheet — tr, обычно оно измеряется в наносекундах. Чтобы выдать такой ток, нужны специальные драйверы, если же мы управляем логическим MOSFET напрямую от микроконтроллера, то мы не сможем обеспечить такой ток. Поэтому для защиты микроконтроллера необходимо перед базой MOSFET ставить резистор, а это сильно замедляет время открытия. В итоге, микроконтроллер в прямом управлении не может обеспечить более 1-2 мкc на открытие и закрытие транзистора. Время открытия и закрытия должно занимать не более 10% длительности ШИМ сигнала. Таким образом, мы сразу получаем ограничение в частоте — 50 000 Гц. Дополнительно, сам микроконтроллер должен иметь возможность генерировать ШИМ сигнал с возможностью хотя бы 8 битного управления шириной ШИМ (для этого требуется большая рабочая частота МК). В итоге, обеспечить большую частоту ШИМ не так просто. Так же, на высоких частотах, начитает мешать паразитные ёмкости и индуктивности. На плате, которую можно сделать дома, получить частоту ШИМ больше 300 кГц, очень сложно. Трассировка платы должна быть сделана идеально. Для снижения требований к плате, в настоящее время выпускаются специальные MOSFET, объединённые с драйверами управления, они позволяют на заводских, многослойных платах получить частоту управления MOSFET в 2МГц.

Индуктивность моторов не такая уж маленькая, и такие большие частоты не нужны. Для управления моторами постоянного тока вполне достаточно 8 кГц, лучше около 20кГц (за звуковым диапазоном).

Дополнительно стоит отметить, что для снижения стартового тока необходимо плавно поднимать на старте частоту ШИМ. А еще - лучше контролировать стартовый ток мотора с помощью датчиков тока.

ШИМ управление мотором предполагает очень быстрое изменение напряжение от 0 для максимального, что порождает большие проблемы при трассировке платы. Перечислим коротко правила, которые необходимо соблюдать при трассировке платы.

  • Земли управления моторами и микроконтроллера обязательно должны быть разделены, соединение в одной точке тонким проводником, например 0.3мм, как можно ближе к проводам питания всей схемы

  • Драйвера управления MOSFET должны быть как можно ближе к самим MOSFET транзисторам

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

  • Обязательно наличие конденсатора как можно ближе к зоне прохождения больших импульсных токов. Если такого конденсатора не будет, то напряжение на линии питания будет сильно проседать и микроконтроллер будет постоянно сбрасываться. Также без такого конденсатора, за счёт индуктивности проводов питания, напряжения на линии питания может увеличиться в несколько раз и компоненты выйдут из строя!

Более подробно мы рассмотрим как работают эти правила на конкретных приборах.

ШИМ сигнал в H-мосте

Чтобы можно было менять направление вращения и скорость — нужна схема H-моста, а для регулирование скорости нужно управлять транзисторами ШИМ сигналом. В схеме H-моста четыре транзистора. Как лучше ими управлять? На какой транзистор подавать ШИМ сигнал? Разберёмся в этом вопросе (рекомендуем прочитать очень подробную статью на эту тему).

Рассмотрим нашу схему с точки зрения нагрева транзисторов. Это один из основных критериев, по которому наш прибор может выйти из строя. Полевой транзистор состоит из двух элементов — собственно транзистор и паразитный диод. В схеме управления мотором оба элемента работают. Нагрев полевого транзистора происходит в следующие моменты времени:

  • когда транзистор открыт, нагрев идёт из-за сопротивления в открытом состоянии Rdson, пропорционально времени открытия транзистора выделяется мощность P = I * I * Rdson

  • когда транзистор закрыт, то ток ЭДС мотора идёт через диод, то есть нагрев идет из-за диода P = I * U diode forward (как правило 1В)

  • когда транзистор переключается из открытого состояния в закрытое, то нагрев пропорционален времени открытия и закрытия транзистора

Посмотрим, как влияет схема управления на нагрев нашим электронных ключей. Допустим, что мы управляем мотором ШИМ сигналом со скважностью 50% и мотор крутится в одну сторону.

Самый простой вариант — применить ШИМ сигнал к одному из двух транзисторов, а второй оставить все время открытым. Обычно, ШИМ в этом случае подаётся на нижний транзистор (N типа), который обычно быстрее. В этом случае нагрев нижнего будет больше верхнего на величину тепла выделяемого при переключениях транзистора. Чтобы сравнять счёт, можно попеременно подавать ШИМ сигнал то на верхний (если они одинаковые), то на нижний транзистор. Также можно подавать ШИМ на оба транзистора одновременно, но из-за разницы в транзисторах это будет не эффективно, а также будет увеличивать нагрев за счёт переключения транзисторов. При такой схеме управления, два других транзистора работают как диоды. К счастью, наибольший ток через диод будет при наибольшей скважности ШИМ, при этом диод будет задействован очень малое время.

Для исключения тока через диоды, которые дают существенный нагрев, можно мотор никогда не отключать от напряжения, а вместо этого, крутить его в обратную сторону. Таким образом, мы должны, например 70% ШИМ сигнала крутить вправо, а 30% влево. Это даст в итоге 70%-30%=40% скорости вправо. Но при этом не будут задействованы диоды. Такой метод управления называется комплиментарным. Такая схема требует большого конденсатора на линии питания, а также источника питания, который может потреблять ток (например аккумулятора).

Вместо вращения мотора в разные стороны, можно помогать диодам — а именно тормозить мотор, открывать два верхних транзистора в момент низкого уровня ШИМ сигнала. На практике, все эти методы не дают существенного изменения скорости вращения двигателя, но позволяют эффективно управлять нагревом полевых транзисторов. Более подробно про особенности различных схем управления можно в этой статье.

На этом мы закончим нашу статью про моторы. Теперь можно перейти к практике — будем делать плату управления4-мя моторами для робота.

]]>
(Super User) Теория Mon, 19 Mar 2018 19:31:23 +0000
Управление приборами 220В /index.php/theory/item/52-upravlenie-priborami-220v /index.php/theory/item/52-upravlenie-priborami-220v

Очень много приборов работает непосредственно от «розетки». Переменное напряжение 220В позволяет использовать прибору большую мощность при меньшем токе. Как микроконтроллер может управлять такими приборами? В этой статье рассмотрим основные модели управления микроконтроллером приборами, работающими от сети переменного тока.

{autotoc}

Самый простой вариант — Реле

Электромагнитное реле — самый простой вариант управления микроконтроллером нагрузкой 220В. По сути это обычный электромагнит. При подаче постоянного тока на катушку возникает магнитное поле, сердечник втягивается и замыкает выводы. Для управления самим реле применимы те же методы, описанные в статье «Как управлять мотором постоянного тока». Важно обращать внимание на ток удержания реле и максимальный ток и коммутируемое напряжение. Как правило, ток удержания довольно высокий, около 100 мА, а напряжение 5 или 12В. Поэтому управлять напрямую от микроконтроллера не получится. Нужен будет транзистор.


Примерная схема подключения реле с использованием MOSFET транзистора. Как видно на схеме, обязательно наличие диода. Дополнительно можно ограничить потребляемый ток самим реле, включив его последовательно через резистор. Обычно ток удержания сильно меньше стартового тока при включении реле. Также можно добавить конденсатор, чтобы он давал стартовый ток. Примерно так можно будет выглядеть полная схема:


Основным минусом схемы с реле является наличие механической части в реле. Именно эта часть ограничивает частоту переключений реле и позволяет использовать реле с частотой 0.5 Гц или меньше. Таким образом управлять реле нагрузкой можно только в режиме включил-выключил, без возможности регулирования мощности подаваемой на нагрузку.

Управляем нагрузкой 220В с регулировкой мощности

Хотелось бы иметь возможность регулировать мощность, подаваемую на управляемый прибор в диапазоне от 0 до 100%. Вот эту задачу и будем решать.

Как известно бытовая электросеть имеет переменное напряжение 220В с частотой 50 Гц. На осциллограмме это выглядит так:




Напряжение меняется по синусоиде, меняя полярность каждые 10 мс. Ограничить полную мощность синусоиды можно двумя методами:

  • фазовый метод

  • метод полных полупериодов

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


Во втором методе, полных периодов или полупериодов, нагрузка отключается на целое количество периодов:


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

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

Симистор — мощный ключ для сети 220 В

Самый простой способ управления нагрузкой 220В — использовать реле. Оно позволяет с помощью постоянного напряжения управлять мощной нагрузкой. В этой статье не будет рассматривать этот метод, он достаточно простой. Достаточно подать напряжение на магнит реле и он замкнёт контакты. К сожалению, реле не позволяет управлять нагрузкой достаточно быстро. При большом количестве включений\выключений оно быстро выходит из строя. Также, в момент переключения возникают большие импульсные помехи. Использовать реле лучше при частоте управления не больше одного раза в 2-3 секунды.

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

Для переменного тока тоже существуют такие электронные ключи — Симисторы.

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

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

Симистором можно управлять напрямую от микроконтроллера, но для этого нужен довольно большой ток — 10-20 мА. Существуют также логические симисторы. У них ток управления составляет около 5 мА. В схемах лучше использовать обычные симисторы, они более защищены от самопроизвольного открытия. Что это такое и как можно управлять обычными симисторами? Читаем дальше.

Для начала посмотрим насколько мощной нагрузкой может управлять типичный симистор. Возьмём для примера симистор BT139-800. В datasheet обычно приводят графики выделяемой мощности на симисторе при управлении нагрузкой. Вот пример такого графика.


Зная выделяемую мощность, используем параметры рассеивания тепла корпусом, чтобы получить температуру нагрева симистора и оценить его работоспособность.




Из всех этих параметров следует, что без радиатора данный симистор может рассеять около 2Вт тепла. При управлении полными полупериодами нужно брать график тока для a=180 градусам. График в этой области практически линейный, поэтому можно сказать, что средний ток будет около 2А.

То есть без радиатора этот симистор сможет управлять нагрузкой в 2А * 220В = 440 Вт. В остальных случаях нужен будет радиатор.

Теперь разберёмся как микроконтроллер может управлять мощным симистором?

Оптосимистор — удобный метод управления мощным симистором микроконтроллером

Так как симистор проводит ток в обоих направлениях, то по отношению к его основным терминалам, управляющий ток может находится в четырёх квадратах.


Можно это также представить в виде таблицы:




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






Видно, что 4-ый квадрант самый невыгодный. Управляющий ток резко возрастает. Также и защитные свойства при таком управлении падают.


Отсюда следует вывод, что при управлении микроконтроллером лучше управлять в 1-3 квадранте.

Если управление прямое, то МК необходимо уметь менять полярность вывода, что сложно, или иметь общее с терминалом A1 плюсовое питание (управление будет во втором и третьем квадранте). Второй вариант не сложно реализовать при конденсаторном источнике питания. В этом appnote AN2986 подробно рассматривается этот случай.




Второй вариант — управлять через оптосимистор. Таких устройств довольно много и они стоят недорого. Например — MOC3041. Есть оптосимисторы со встроенной схемой контроля перехода через ноль, они могут выключаться только около нуля. Такой нам и нужен для схемы управления полными периодами. А есть без этой схемы. С их помощью можно управлять фазовым методом.

Схема управления с использование оптосимистора получается такая:




само устройство внутри выглядит так:


Управление в этом случае получается одной полярности с терминалом A2, то есть в первом и третьем квадранте.

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

Цепь защиты симистора от помех в сети

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

Простой защитой от этого случая является снабберная цепь (резистор плюс конденсатор):


Но она не гарантирует работу во всех случаях. Параметры рассчитываются под конкретную индуктивность. Appnote AN-3004 подробно рассматривает расчет снаббера.

Второй вариант — использование симисторов работающих в 1-3 квадранте. Например, T405. Производитель указывает, что они могут использоваться для управления даже индуктивной нагрузкой без снаббера.

Фазовый метод

Для решения задачи фазового управления нагрузкой микроконтроллеру необходимо знать когда был совершён переход через ноль. Тогда можно будет рассчитать время задержки включения нагрузки.

Самый простой метод получения события перехода через ноль в сети переменного тока подробно описан в appnote AN521 от компании Microchip. Практически каждый микроконтроллер имеет высоковольтные защитные диоды на каждом цифровом входе. Это можно использовать, чтобы получить информацию о переходе через ноль. Достаточно на входе поставить высокоомный резистор, ограничивающий ток на выводе МК, до значений указанных в datasheet на МК. В этом случае вывод в обычном цифровом режиме будет принимать значение 0 в момент перехода через ноль. Временная задержка от реального состояния до реального будет минимальна и составляет около 50 мкс.




Минусом такой схемы является отсутствие гальванической развязки схемы управления от сети 220В. Если это необходимо, то можно использовать оптопару.

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

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

]]>
(Super User) Теория Thu, 09 Jan 2020 17:15:26 +0000