STM32L Линии ввода-вывода

В первую очередь при работе с новым микроконтроллером мне необходима его связь с “внешним миром”, самое простое средство – линии ввода-вывода. Ранее в обзоре я писал об изменениях в данном модуле относительно старого семейства STM32F1хх, поэтому использовать описанные ранее макросы для работы с линиями ввода-вывода не получиться, они требуют доработки.


Линии ввода-вывода

Рассмотрим структурную схему стандартной линии ввода-вывода:

image

Первоначально взглянув на структурную схему, мне показалось что нет ни каких изменений относительно STM32F1хх, но это не верно. Основное изменение это перенос резисторов подтяжки (Pull up, Pull down) из входного драйвера во “внешнюю” цепь, для сравнения структурная схема STM32F1хх:

image

В связи с чем появились дополнительные возможности конфигурирования линии ввода-вывода:

image

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

Перейдем к блоку альтернативных функций.

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

Фактически выход каждой линии ввода-вывода может быть подключён к определенной альтернативной функции (модулю).

Для управления мультиплексорами на каждый порт дополнительно ввели два регистра (AFRL, AFRH) и по четыре бита на каждую линии ввода-вывода, определив тем самым количество комбинаций (16):

image

image

Что бы было более понятно приведу начало таблицы распределений альтернативных функций для микроконтроллера STM32L152RB (полное описание в справочном листке):

image

Например линия ввода-вывода PA1 имеет возможность подключения к пяти альтернативным функциям (на рисунке выше я их отметил синим). Если необходимо подключить линию PA1 ко второму каналу таймера 2, достаточно установить AFRL1[3:0]=1 в регистре AFRL.

Основываясь на документации я написал новые макросы для работы с линиями ввода-вывода.


Макросы для работы с линиями ввода-вывода

Режимы работы согласно документации (данные объявления необходимы для функции автозавершения):

#define MODE_OUTPUT_PUSH_PULL					MODE_OUTPUT_PUSH_PULL
#define MODE_OUTPUT_PUSH_PULL_PULL_UP			MODE_OUTPUT_PUSH_PULL_PULL_UP
#define MODE_OUTPUT_PUSH_PULL_PULL_DOWN			MODE_OUTPUT_PUSH_PULL_PULL_DOWN
#define MODE_OUTPUT_OPEN_DRAIN					MODE_OUTPUT_OPEN_DRAIN
#define MODE_OUTPUT_OPEN_DRAIN_PULL_UP			MODE_OUTPUT_OPEN_DRAIN_PULL_UP
#define MODE_OUTPUT_OPEN_DRAIN_PULL_DOWN		MODE_OUTPUT_OPEN_DRAIN_PULL_DOWN

#define MODE_AF_PUSH_PULL						MODE_AF_PUSH_PULL
#define MODE_AF_PUSH_PULL_PULL_UP				MODE_AF_PUSH_PULL_PULL_UP
#define MODE_AF_PUSH_PULL_PULL_DOWN				MODE_AF_PUSH_PULL_PULL_DOWN
#define MODE_AF_OPEN_DRAIN						MODE_AF_OPEN_DRAIN
#define MODE_AF_OPEN_DRAIN_PULL_UP				MODE_AF_OPEN_DRAIN_PULL_UP
#define MODE_AF_OPEN_DRAIN_PULL_DOWN			MODE_AF_OPEN_DRAIN_PULL_DOWN

#define MODE_INPUT_FLOATING						MODE_INPUT_FLOATING
#define MODE_INPUT_PULL_UP						MODE_INPUT_PULL_UP
#define MODE_INPUT_PULL_DOWN					MODE_INPUT_PULL_DOWN

#define MODE_ANALOG								MODE_ANALOG


Максимальная частота переключения:

#define SPEED_400KHZ							SPEED_400KHZ
#define SPEED_2MHZ								SPEED_2MHZ
#define SPEED_10MHZ								SPEED_10MHZ
#define SPEED_40MHZ								SPEED_40MHZ


Альтернативная функция:

#define AF_NO									0
#define AF0										1
#define AF1										2
#define AF2										3
#define AF3										4
#define AF4										5
#define AF5										6
#define AF6										7
#define AF7										8
#define AF8										9
#define AF9										10
#define AF10									11
#define AF11									12
#define AF12									13
#define AF13									14
#define AF14									15
#define AF15									16


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

#define LED_GREEN	B, 7, HIGH, MODE_OUTPUT_PUSH_PULL, SPEED_400KHZ, AF_NO


  • В — литера порта
  • 7 – номер линии
  • HIGH – активный уровень
  • MODE_OUTPUT_PUSH_PULL – режим работы
  • SPEED_400KHZ – максимальная частота переключения
  • AF_NO – альтернативная функция

Далее перед использованием разрешить тактирование и сконфигурировать линию:

RCC->AHBENR |= RCC_AHBENR_GPIOBEN;

PIN_CONFIGURATION(LED_GREEN);


И на пример меняем состояние на линии:

while (1)
{
	PIN_ON(LED_GREEN);
	PIN_OFF(LED_GREEN);
}





Первый проект

Данный пункт я описывал ранее в серии статей о STM32F1.

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

Простой пример, изменяет состояние светодиодов при нажатии на кнопку пользователя:

int main(void)
{
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;

	PIN_CONFIGURATION(LED_GREEN);
	PIN_CONFIGURATION(LED_BLUE);
	PIN_CONFIGURATION(USER_BUTTON);

	while (1)
	{
		if (PIN_SIGNAL(USER_BUTTON))
		{
			PIN_ON(LED_GREEN);
			PIN_OFF(LED_BLUE);
		}
		else
		{
			PIN_OFF(LED_GREEN);
			PIN_ON(LED_BLUE);
		}
	}

	return 0;
}


 

Полный проект:

ziblog.ru/2011/08/15/stm32l-ndash-linii-vvoda-vyivoda/
  • +2
  • 11 сентября 2011, 13:13
  • ZiB

Комментарии (16)

RSS свернуть / развернуть
А какой смысл в режимах PP+PU/PD?
0
  • avatar
  • ACE
  • 11 сентября 2011, 14:39
да и в режиме OD+PD, вроде то же смысла нет :) тут как бы управление подтягивающими сопротивлениями отдельно и может поэтому не стали заморачиваться с «резервированием».
0
  • avatar
  • ZiB
  • 11 сентября 2011, 14:45
Наверное в условиях особого холода можно микроконтроллер подогревать подтягивающими резисторами :)
0
  • avatar
  • ACE
  • 11 сентября 2011, 14:47
Удобно же, когда надо ногой вдрыгивать, например вниз и на pull-up. В той же 1-wire.
0
Это OD+PU, тут вопросов нет. Но PP+PU…
0
  • avatar
  • ACE
  • 12 сентября 2011, 14:28
Видимо за компанию :)
0
Вопрос немного не в тему, но может подскажите:
В списке поддерживаемых камней CooCox IDE есть только серия STM32F1. Это относится только к дебаггингу, или компилить под STM32L они тоже не умеют? Если не умеют, то где взять сборку GCC с поддержкой STM32L?
0
Не подскажу так как не пользуюсь CooCox IDE.
Компилю вот этой сборкой
ziblog.ru/2011/01/06/pervyiy-start-s-stm32-discovery-chast-2/
0
  • avatar
  • ZiB
  • 12 сентября 2011, 05:04
Большое спасибо, это меня тоже вполне устроит =)
0
Ага, покопался — там используется тот же самый CodeSourcery Lite, так что компилить он должен уметь.
0
мда, давно я так не парился чтобы просто поморгать светодиодом %) Еще вопрос — где в взять описания всех этих AHBENR RCC MODER и прочих вещей? В даташите про них не слова :(
0
В документации на нужный мк, «ключевое слово»:
REFERENCE MANUALS
0
все линки есть в обзоре
ziblog.ru/2011/08/14/stm32l-vvedenie/
0
Баловался я тут с STM32L-DISCOVERY и наткнулся на одну забавную вещь. В хидере stm32l1xx.h есть структура GPIO_TypeDef, а в ней регистр BSRR (который в хидере серии F1 был 32 битным)непонятно зачем разбит на два 16-ти битных BSRRL и BSRRH.
__IO uint16_t BSRRL; /* BSRR register is split to 2 * 16-bit fields BSRRL */
__IO uint16_t BSRRH; /* BSRR register is split to 2 * 16-bit fields BSRRH */

При этом далее идут макросы вида
/******************* Bit definition for GPIO_BSRR register ******************/

#define GPIO_BSRR_BR_6 ((uint32_t)0x00400000)
#define GPIO_BSRR_BR_7 ((uint32_t)0x00800000)

т.е такие же, как были в серии F1

Обнаружил это когда Кейл выдал сообщение «warning: #69-D: integer conversion resulted in truncation» при попытке скомпилить код, содержащий что-нибудь типа GPIOC->BSRRL = GPIO_BSRR_BR_6;
Думал у меня старая версия stm32l1xx.h, но на сайте ST не нашел версии новее 1.0.0. Видимо придется подправить хидер или получше поискать другой версии.
0
  • avatar
  • Anton
  • 15 декабря 2011, 16:21
прикольно
не заметил (работаю через свои макросы)
0
В первой версии несколько ошибок,
новую версию макросов можно взять тут
ziblog.ru/2011/12/14/stm32l-interfeys-i2c/
0
  • avatar
  • ZiB
  • 15 декабря 2011, 17:40
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.