STM32F030. Порты ввода-вывода

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

Для сравнения вспомним про порты в AVR. Здесь для работы с ними используются три регистра:

  • регистр направления DDRx,
  • регистр данных (выход) PORTx
  • регистр выводов (состояния ножек) PINx.

Всего три регистра — обнобайтовые! Предельно просто и понятно. Благодать!

Если в микроконтроллере включить какое-либо периферийное устройство, которое претендует на ножки порта, (например, UART) то ножки отключаются от порта, и автоматически перейдут под юрисдикцию этого устройства. Блудит и путаться просто негде!

Вспомним про порты в MSP430. Тут немного интереснее. Тут от шести до девяти регистров для управления портом:

  • регистр входа PxIN,
  • регистр выхода PxOUT,
  • регистр направления PxDIR,
  • регистр включения подтягивающего резистора PxREN,
  • регистр разрешения прерывания PxIE,
  • регистр флага прерывания PxIFG,
  • регистр выбора фронта прерывания PxIES,
  • регистр выбора функции PxSEL,
  • регистр выбора функции 2 PxSEL2

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

Не буду вас утомлять регистрами ARM-ов и Cortex-M3, тем более, что их конкретная реализация зависит от производителя. Перейдем сразу к рассмотрению портов STM32F0xx.

Признаться, после работы с портами AVR я в свое время был поражен реализацией портов в MSP430. Я был повторно поражен при изучении портов AT91SAM7xxx и LPC2xxx. Я удивился, изучая реализацию портов в STM32F1xx. Мне казалось, дальше развиваться уже просто некуда. — Кого там, «некуда»! Только предоставь возможность!…

Порты STM32F0xx насчитывают 11 регистров! Причем, эти регистры совсем не однобайтовые, как у AVR или MSP430. Сами по себе порты — это двухбайтовые (16 битные) бестии. Иначе говоря, регистр ввода IDR, регистр вывода ODR — 16-битные.

(Для справки, в LPC17xx порты не байтовые и не двухбайтовые, а полутра-байтовые — то есть 12-битные. Немного забавно, да.)

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

Регистр BRR — 16-разрядный, он отвечает за сброс соответствующих битов в регистре ODR. С ним просто. Регистр BSRR — 32-разрядный. С ним немножко по-сложнее. В нем младшая половина битов отвечает за установку, а старшая за сброс битов регистра ODR.

Следующий регистр — MODER имеет по два бита для управления на каждый бит порта. Значение этих битов задают режим работы порта:

  • 00 : бит порта работает на ввод (после сброса)
  • 01 : бит порта работает на вывод
  • 10 : бит порта отключен, вместо него управление ножкой осуществляется от альтернативной функции
  • 11 : бит порта отключен, ножка работает как аналоговый ввод

Если бит порта сконфигурирован на вывод (сам по себе или на вывод альтернативной функции), то регистр мы можем «поиграться» с регистром OTYPER, который определяет тип вывода:

  • 0 : push-pull вывод (обычный вывод)
  • 1 : open-drain вывод (вывод с открытым стоком)

Следующий регистр — OSPEEDR. Он отвечает за скорость вывода. Если выражаться более точно, то — за крутизну фронтов.

  • 00  : низкая скорость (low speed)
  • 01 : средняя скорость (medium speed)
  • 10 : низкая скорость
  • 11 : высокая скорость (high speed)

Если в STM32F1xx в документации указывались конкретные цифры скоростей — 2, 10, 50 МГц, то в документации для STM32F0xx разработчики решили обойтись пространными low, medium и high speed.

Следующий регистр — PUPDR, регистр подтяжки. Он может задавать следующие конфигурации порта:

  • 00 : нет подтяжки (ни вверх, ни вниз)
  • 01 : подтяжка вверх (pull-up)
  • 10 : подтяжка вниз (pull-down)
  • 11 : зарезервировано

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

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

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

Ну и последний регистр — самый насыщенный по функциональности (по количеству возможностей на один информационный бит порта) — регистр альтернативных функций. Он настолько большой, что состоит из двух 32-разрядных регистров AFRL и AFRH. Здесь брошено аж четыре бита на один информационный бит ввода-вывода. Эти четыре бита выбирают номер альтернативной функции. Поскольку битов четыре, то теоретически можно выбрать аж 16 функций. (Куда столько!)

Но реально в документации прописано только первые 8 функций — от AF0 до AF7. Оставшиеся восемь функций зарезервированы для дальнейших расширений.

Мы вкратце рассмотрели в общих чертах все регистры порта. Теперь я хотел бы заострить внимание вот на каком аспекте.

В отличие от AVR и MSP430, в микроконтроллерах Cortex практически нет никаких ограничений в адресном пространстве. Здесь его — умотаться! 4ГБ — всем хватит!

— Я думаю, пространства в 640 кБ (10 кратное превосходство над 16-битными процессорами), должно хватить на все случаи жизни. (с) Билл Гейтс

Так вот, если у AVR пространства для регистров периферийных устройств настолько мало, что разработчики теперь пихают «новые» биты во все оставшиеся дырки (чем и приводят в систему в состояние «винегрет»), то в отношении Cortex тут целый космос.

А поскольку и как правило, в микроконтроллерах реализован не один порт, а несколько, то было бы разумнее все порты сделать одинаковыми (с точки зрения регистров управления). Так, например, для STM32F0xx имеется группа из 11-ти регистров для управления портом. Если в каком-то микроконтроллере будет сделано, скажем, пять портов, то нам нужно разместить в пространстве пять групп управления этими портами. Понятно, что эти группы будут сидеть на своих адресах. Но вот относительно своего базового адреса регистры в группах будут иметь одинаковое смещение. Я имею ввиду следующую картину:

Смещение Регистр
 +0x00    MODER
 +0x04    OTYPER
 +0x08    OSPEEDR
 +0x0C    PUDPR
 +0x10    IDR
 +0x14    ODR
 +0x18    BSRR
 +0x1C    LCKR
 +0x20    AFRL
 +0x24    AFRH
 +0x28    BRR

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

Например, мне хотелось бы знать адрес регистра ODR вывода порта GPIOB. Для этого я нахожу базовый адрес порта 0x48000400 и добавляю к нему смещение +0x00000014. В результате я получаю число 0x48000414, которое соответствует адресу этого регистра. Теперь, если я запишу по этому адресу что-то, то оно (это «что-то») появится на выводах микроконтроллера. (Ну, разумеется, что порт был правильно сконфигурирован для этого!)

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

Документация на процессор называется RM0360
Reference manual
и хранится на сайте ST-Microelectronics в файле с именем DM00091010.pdf. Это 655-ти страничный манускрипт.

Но это еще не все! В этом документе описана только периферия, которая не относится к ядру Cortex. По самому же ядру имеется еще один документ — PM0215 Programming manual, файл которого называется DM00051352.pdf.

Кроме того, у меня в ходу еще один документ — STM32F030x4 STM32F030x6 STM32F030x8, файл которого называется DM00088500.pdf. В нем расписаны назначения выводов и другие физические (напряжения, токи, времена) характеристики микроконтроллера.

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

PS.

Я вот тут ради развлечения посчитал количество управляющих бит, приходящихся на один разряд порта. У AVR — это число равно трем. У MSP430 — от 6 до 9. (На старых моделях может бить и четыре). У STM32F0xx — 17 (семнадцать) бит!

— Ах-х! Скоко-скоко!? (с)

Advertisements

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s