Примечание переводчика: Не так давно, мне пришел заказанный мною LaunchPad. Единственное что мне тогда хотелось, это сразу же начать мигать светодиодиками. Так я столкнулся с первой проблемой — у меня Linux. Почитав про основные IDE для разработки под эту платформу, я понял, что ничего хорошего мне тут не светит. А использовать Energia, просто напросто не позволяла религия. Имею привычку(не знаю, хорошую или нет) не работать с подобными инструментами «повышенной абстракции» пока не изучу подноготную того с чем работаю. Поэтому, Energia быстро отсеялась из возможных вариантов. Осталось только одно — собрать тулчейн gcc-msp430, включающий в себя все необходимое. Ноутбук у меня очень слабый, поэтому собирался этот тулчейн аж полдня. Что никак не радовало меня, так как я уже хотел МИГАТЬ. Когда собрал, столкнулся со следующей сложностью. Очень мало русскоязычной литературы и справки по этому микроконтроллеру. Что-то поспрашивал среди, что-то кое-как смог вытащить из примеров кода от TI, но проблема оставалась — я слабо понимал все то что делаю. Продолжалось это ровно до тех пор, пока я не набрел на один замечательный англоязычный блог в котором хоть и на английском языке, но довольно доступно объяснялись все основы. Его я и принялся читать и переводить. Признаюсь честно, перевод я этот писал не столько для хабры, сколько для себя, чтобы на все 100% понять изложенный материал. Сказать что понял все на 100% — немного соврать. Скажу честно — от электроники я далёк, на момент получения лаунчпада я обладал нулевыми знаниями в этой сфере. Поэтому некоторые моменты перевода, могут, наверное, заставить плакать кровавыми слезами более серьезных разработчиков. К примеру — Vcc и Vss или PxREN. Идею я понимаю, но я сомневаюсь что перевел технически грамотно. Тем не менее, переводить я старался так, чтобы было понятно такому же нулю как я. В общем, если что — не обессудьте. Как мог. Кроме того, в переводах есть абзацы которые написаны чисто от себя, чтобы немного более подробно разжевать материал.
Ах да, начал переводить с лекции 02, так как в первой «Вводной» лекции содержится слишком много воды, которой и так море и на просторах хабры, да и вообще интернета. Мы же хотим сразу же работать, а не читать о том, как хорошо поступили TI выпустив дешевые LaunchPad'ы.
Итак.
Большинство статей, посвященные MSP430, что мне довелось видеть, почти с первых строк рассказывали об архитектуре процессора, адресации памяти, шинах данных и прочих технических штуках, которые, к сожалению, человеку без опыта в области электроники, довольно тяжело понять. В этой статье я попытаюсь объяснить вам азы, необходимые для начала работы с этим семейством микроконтроллеров(далее МК), без всяких заумных вещей типа биполярных соединений и тому подобного. Глубокие технические знания были бы очень полезны в тонкой настройке разрабатываемой системы или в программировании на ассемблере, но и элементарных знаний языка С достаточно, чтобы начать вполне комфортную и продуктивную работу.
Одна из особенностей, которая выделяет микроконтроллеры MSP430 из основной массы, — это фон-Неймановская архитектура: все данные, которыми может оперировать процессор, расположены в одном адресном пространстве. Остальные же микроконтроллеры отличаются в этом плане: их данные могут располагаться в различных адресных пространствах, что повышает эффективность, но изрядно усложняет работу с ними, а нам этого ой как не хочется. Чтобы быстро понять, о чем речь, можно представить себе микроконтроллер как город: в фон-Неймановских городах(как MSP430) все люди живут в одном городе и имеют свой собственный, уникальный адрес. Ну а, к примеру, в Гарвардской архитектуре городов несколько, поэтому адреса могут повторяться. Таким образом, если вы захотите отправить письмо по определенному адресу, сначала вам придется уточнить город.
Память
Адресное пространство MSP430 включает в себя область для хранения непосредственно самой программы, область для хранения данных, необходимых этой программе, оперативную память и прочую важную информацию, которую мы с вами рассмотрим чуть позже. Сегодня же всю вашу неуёмную тягу к знаниям мы будем удовлетворять изучением адресов в памяти, которые называются “регистрами”. Эти адреса как различные коммунальные и социальные службы (такие как почта или ЖКХ) в нашем небольшом MSP430-городке. В нашем же микроконтроллере регистрами контролируются различные функции процессора и периферии. Представьте себе помещение с множеством разных переключателей и кнопочек, от которых зависит включат ли завтра в вашем районе отопление или горячую воду — это и будут наши регистры. Как и любые другие выключатели, они имеют всего лишь два состояния — “включено” и “выключено”, говоря компьютерным языком — 1 и 0. В микроконтроллере же состояние регистров определяет как будет себя вести та или иная периферия, за что будет отвечать та или иная ножка вашего МК, что произойдет при наступлении определенного события, и так далее, и тому подобное. Регистры в MSP430 сгруппированы в 3 секции:
1) Регистр специальных функций (англ: Special Function Registers (SFR)).
(прим. переводчика.: подобные аббревиатуры следует запоминать, или хотя бы записывать, в дальнейшем, они будут использоваться достаточно часто)
2) 8-битные регистры, для различной периферии процессора(для хранения “настроек” периферии которым, достаточно лишь 8 бит)
3) 16-битные регистры(то же самое, только выделяется 16 бит).
В качестве примера, давайте взглянем на самого маленького представителя семейства MSP430, а именно — на микроконтроллер MSP430G2001. Откройте следующие документы: описание серии x2xx и спецификации G2x01.
Заметьте, что вышеуказанные ссылки могут быть несуществующими, такое случается, если “Texas Instruments” делает обновление документации. Проще всего отыскать эти документы, перейдя на официальный сайт TI и найти блок “Search by Part Number”. Для того, чтобы найти документацию по серии G2x01, достаточно ввести любую маркировку, которая попадает под эту маску, к примеру msp430g2001.
Давайте взглянем на четвертую часть первой главы(Address Space) описания серии x2xx(англ.: family guide), которая иллюстрируют нам карту нашего “городка” семейства x2xx. Как вы видите, регистры SFR расположены, начиная с адреса 0h и заканчивая Fh (символ h указывает на то, что адрес написан в шестнадцатеричной системе исчисления; в десятеричной же они бы выглядели как 0 и 15). Следующими идут 8-битные регистры; их адреса начинаются с 010h и заканчиваются адресом 0FFh (в десятичной системе: с 16 по 255), затем, с адреса 0100h по 01FFh идут 16-битные регистры. Вы, наверное, заметили огромное пустое место между областями оперативной и флэш памяти(прим.: не путайте flash-память с USB-накопителями или другими внешними накопительными устройствами, в данном случае, флэш-память — это “перепрограммируемая память”). Описание данной серии микроконтроллеров показывает нам те области памяти, которые относятся ко всему семейству x2xx, чтобы увидеть точные значения для какого-либо конкретного микроконтроллера, вам необходимо обратиться к спецификации этого чипа, называемой даташитом(англ.: datasheet — привыкайте к этому названию, везде используется именно оно).
Одиннадцатая страница даташита предоставляет нам карту распределения памяти, которая соответствует всем микроконтроллерам серии G2x01 и G2x11. Взглянув на столбик с G2001, можно увидеть, что сначала идут служебные регистры периферии(SFR, 8-bit, 16-bit) затем идут 128 бит оперативной памяти. Адресное пространство, начиная с адреса 0201h и заканчивая 10FEh, пустое, после него мы видим 256-бит памяти, именуемые служебной областью памяти(эта область памяти хранит в себе калибрационные данные и прочие важные значения, которые необходимо сохранить, если питание к устройству перестало поступать. Обычно эти данные недоступны для перезаписи, но это не значит, что это невозможно при реальной необходимости, но это отдельная история, заслуживающая отдельной лекции). В итоге мы имеем 512 байт памяти для программного кода и, в довершение всему, память, которая выделена под векторы прерываний(но об этом тоже в другой лекции).
Регистры
Теперь мы с вами видим как выглядит изнутри наш “G2001-городок”, следовательно, нам следовало бы разобраться, как работать с теми самыми “домами с переключателями”, которые мы описали выше. Регистры в микроконтроллере MSP430 — это специальные секции в памяти, с помощью которых он конфигурируется и которые сообщают нам, когда случается что-то важное. Страница номер 10 нашего даташита показывает, какие регистры специальных функций(SFR) доступны в нашем G2001. Как мы видим, у этого устройства есть только четыре регистра спец. функций, расположенных по адресам с 0h по 3h: регистр разрешения прерываний 1 (англ.: Interrupt Enable 1(IE1)), регистр разрешения прерываний 2(IE2), и два регистра флагов прерываний IFR1 и IFR2 (англ.: Interrupt Flag Register). Каждый адрес указывает на 1 байт в памяти, а в одном байте, как нам известно, — 8 бит. Помните наши “дома с переключателями”? Так вот, каждый бит в регистре выполняет роль одного переключателя. Таким образом, сам регистр является домом, а каждый его бит — переключателем, который имеет два состояния 0(выкл) и 1(вкл). Каждый из этих битов очень важен, состояние каждого из них так или иначе влияет на работу микроконтроллера и его поведение в целом. Страница 10 также показывает нам какие биты в этих регистрах доступны на нашем G2001.
В данном случае, в регистре IE1 нам доступны только 0, 1, 4 и 5 бит, в то время как в IFG1 нам доступны все биты с 0 по 5. В даташите содержится полная информация о том, какое имя носит каждый из этих бит и какую функцию он выполняет. К примеру, нулевой бит в регистре IE1 называется WDTIE — разрешение прерываний сторожевого таймера(англ.: WatchDog Timer Interrupt Enable). По умолчанию этот бит имеет значение 0, но если мы изменим его и установим в него 1, то мы позволим сторожевому таймеру “поднимать” флаг прерывания в регистре IFG1(бит под номером 0, если быть точнее), тем самым вызывая прерывание(как уже говорилось, что такое прерывания мы рассмотрим позже). Проще говоря, этот бит указывает нашему MSP430, может ли сторожевой таймер сигнализировать процессору о том, что нужно что-то сделать, или же он используется в обычном режиме. Тут, наверное, стоило бы пояснить, что такое сторожевой таймер и что есть “обычный” его режим. Сторожевой таймер необходим для того чтобы сбрасывать процессор в то состояние, в котором он был на момент подачи питания. Сбрасывает он его регулярно, с определенным интервалом. Зачем же это нужно? Если во время работы программы происходит какой-то сбой, то сторожевой таймер сбрасывает эту программу, чтобы она снова смогла работать. Разумеется, его можно отключить. Когда мы переводим сторожевой таймер в интервальный режим, то он вместо того, чтобы сбрасывать нашу программу, просто напросто посылает процессору сигнал. Как обрабатывать этот сигнал и что делать процессору при получении этого сигнала — это решение ложится на плечи программиста. Обычно это используется для того, чтобы совершать какие-либо цикличные действия. К примеру, в самом элементарном случае поморгать светодиодом, чем мы с вами вскоре и займемся.
Теперь взглянем на 14 страницу нашего даташита. Эта таблица предоставляет нам всю информацию о существующих периферийных “устройствах”, адреса их регистров и их имена. Кстати говоря, внизу таблицы расположена информация и о SFR, которые мы не раз упоминали в данной статье. Таким образом, когда вы захотите использовать какую-либо периферию вашего микроконтроллера, эта таблица будет вашей отправной точкой для того чтобы узнать какие именно “домики с переключателями” вам необходимо посетить, чтобы быть уверенным, что все ваши регистры настроены правильно. Сегодня мы с вами подробнее рассмотрим регистры предназначенные для порта 1(Port P1) и порта 2(Port P2), так как они являются основными элементами которые необходимы для работы с нашим микроконтроллером.
Порты это основные устройства ввода/вывода доступные на микроконтроллере, ввод/вывод производится через ножки(англ.: pin) вашего МК. Распиновку вашего устройства вы можете посмотреть на третьей странице даташита. Под портом обычно подразумевается набор из 8 пинов микроконтроллера. Но пинов у порта может быть и меньше, это бывает, если ножек просто напросто не хватает до полного набора. Распиновка, изображенная в даташите, показывает нам, что G2001 имеет полный набор из 8 ножек для порта 1(c P1.0 по P1.7) и две ножки для порта 2(с P2.6 по P2.7). Каждый регистр каждого порта имеет бит, который соотносится с соответствующей ножкой микроконтроллера. К примеру, P1.4 контролируется 4-м битом каждого регистра, который принадлежит порту 1(P1). Давайте познакомимся поближе с регистрами, которые предлагает нам микроконтроллер.
PxIN
Входной регистр(режим ввода), значения которого находятся в режиме “только для чтения”(англ.: read-only). Если направление ножки было выбрано как “входящее”(англ.: INput), то значение этого регистра будет сообщать вам, подано ли в данный момент напряжение на эту ножку или же нет. Следует понимать, что чтение значения регистра PxIN возвращает вам данные по всем ножкам соответствующего порта за раз. Не стоит так же забывать и то, что это цифровая технология, поэтому каждый считанный бит может быть только в двух состояниях: 1 или 0. Эти значения показывают нам, какое напряжение подано на ножку: Vss(если значение 0) или же Vcc(если значение 1), значение 0 принимается в том случае, если поданное напряжение ниже 1.8 вольт(Vss < 1.8В), ну а значение 1 принимается в том случае, если поданное напряжение попадает в рамки между 1.8 и 3.6 вольт(1.8В <= Vcc <= 3.6В). Во избежание нанесения ущерба вашему устройству НИКОГДА не пытайтесь напрямую подавать напряжение выше верхнего порога Vcc. Если говорить в двух словах — Vcc это вольтаж, а Vss — земля.
PxOUT
«Выходной» регистр(режим вывода), доступный для записи. Когда определенный пин вашего микроконтроллера установлен в “режим вывода”(англ.: OUTput), вы можете подавать на него напряжение, просто установив соответствующему биту в этом регистре значение 1. Так же как и в регистре PxIN при значении 0 на ножку подается напряжение с Vss, если 1 — Vcc.
PxDIR
Регистр направления(англ.: DIRection), определяет пин в режим ввода, если в соответствующем бите данного регистра установлено значение 0 и в режим вывода, если 1. В самом начале вашей программы следует указать все направления пинов, которые вы планируете использовать. Разумеется, это не значит, что вы не можете изменить эти значения где-нибудь в середине программы.
PxIE, PxIES, и PxIFG
Следующие три регистра, которые имеются у наших портов: регистр разрешения прерываний(англ.: Interrupt Enable (IE)), контрольный регистр прерываний(англ.: Interrupt Edge Select (IES)) и регистр флагов прерываний(англ.: Interrupt FlaG (IFG)). Мы рассматриваем эти три регистра вместе, так как работа с любым из этих регистров, предполагает работу с двумя оставшимися, они неразрывны друг с другом. Что такое прерывание? В настоящий момент вам достаточно будет просто представить, что это некое сообщение, посылаемое процессору, при получении которого он приостанавливает все свои дела и начинает выполнять те действия, которые предписаны на выполнение при получении оного. Как только он завершит обработку прерывания, процессор как ни в чем не бывало возвращается к своей предыдущей работе и продолжает выполнение основной программы. Чтобы разрешить определенному пину вашего порта генерировать прерывания, вы просто “поднимаете”(устанавливаете значение 1) соответствующий этой ножке бит в регистре разрешения прерываний(PxIE где x — номер порта). Контрольный регистр прерываний(PxIES) содержит в себе контрольные биты(edge-bits), с которыми сравнивается текущее состояние регистра PxIN. Проще говоря, если у вас есть ножки, которые в регистре PxDIR назначены в input-режим(битам, соответствующим ножкам назначено значение 0), то регистр PxIN сравнивается по битам со всеми значениями регистра PxIES и если случается так, что значения соответствующих битов в этих регистрах имеют разное значение, то следующее, что делает процессор — это проверяет, разрешены ли для этих ножек прерывания — сравнивает с регистром PxIE,- и если прерывания разрешены — генерируется прерывание, а это, в свою очередь, ни что иное как “поднятие” соответствующих битов в регистре PxIFG(регистр флагов прерываний).
Ещё раз вкратце: прерывание для определенной ножки вашего микроконтроллера считается сгенерированным, если в регистре PxIFG поднят флаг(бит принял значение 1) который своим порядковым номером соответствует этой ножке. Биты регистр PxIE определяют, какие вообще ножки вашего микроконтроллера имеют право поднимать эти флаги, если в регистре PxIE бит с порядковым номером 0 имеет значение 0, то эта ножка попросту не имеет доступа к регистру PxIFG, а следовательно, не может генерировать прерывания. В регистре PxIES хранятся контрольные значения. Процессор сравнивая регистры PxIN и PxIES генерирует прерывания для ножек, значения битов которых в этих регистрах разнятся.
PxSEL
Если снова взглянуть на третью страницу нашего даташита, где изображена распиновка нашего микроконтроллера, можно заметить, что каждая ножка имеет несколько функций, которые разделены слэшем. Этот регистр выбора(англ.: SELection Register) определяет, какую функцию тот или иной пин будет выполнять. Функция, которую та или иная ножка выполняет по умолчанию, указана первой — так мы можем заметить, что все ножки первого порта(P1) по умолчанию настроены просто на ввод и вывод(I/O — Input/Output), в то время как ножки P2 по умолчанию подключены к кварцевому генератору. Изменение битов в PxSEL поменяет основную функцию соответствующей ножки. Все это мы рассмотрим позднее, сейчас же наша основная задача — научиться использовать стандартные функции, которые предопределены в этом регистре.
PxREN
Регистр включения резисторов(англ.: Resistor ENable register) — очень удобная функция портов. Иногда необходимо вручную подать напряжение или же напротив, прекратить подачу оного. К примеру если вы подключите к вашему микроконтроллеру какую-нибудь кнопку. Регистр включения резисторов предоставляет вам эту возможность. Когда бит, соответствующий вашей ножке в этом регистре “поднят”, подача может регулироваться установкой этого же бита в регистре PxOUT в 1 или 0.
Ну что же, мы рассмотрели некоторые доступные нам “переключатели”, поэтому, чтобы закрепить пройденное, в следующей статье мы рассмотрим как их использовать при написании нашей программы и загрузке её на наше устройство.
Оригинал статьи.
Отдельное «спасибо», хотелось бы сказать компании «Мегафон», которая по какой-то причине заблокировала доступ к этому бложику.
Автор: DarthRamone