STM32. Работа с базовыми портами ввода/вывода. Примеры.
Настройка порта
Настройка порта GPIO в STM32 для цифрового ввода/вывода требует выполнения двух основных действий – подключения тактового сигнала и настройки режима работы. Также, при необходимости, выполняется блокировка настроечных параметров.
Пример 1. Вариант настройки, с использованием структур языка С.
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Подключение тактового сигнала GPIOC->CRH |= GPIO_CRH_MODE8; // Настройка режима PORTC.8 с частотой 50 МГц GPIOC->CRH &=~GPIO_CRH_CNF8; // Установка простого режима цифрового выхода
В языке С очень популярно использование разнообразных структур данных и определений. Пример выше использует все эти элементы. Первая строчка выполняет функцию подключения PORTC к шине APB2. Запись RCC->APB2ENR представляет собой обращение к регистру APB2ENR из группы регистров тактирования и контроля RCC. RCC_APB2ENR_IOPCEN есть определение значения управляющего бита PORTC в регистре APB2ENR. В числовом виде данное значение выглядит как 0x00000010. Для установки используется оператор «ИЛИ», так как в данном регистре уже есть настроенные биты. Использовать чистое присваивание в данном случае нельзя.
Вторая строчка устанавливает режим работы выхода 8 в PORTC. Опять используется константа GPIO_CRH_MODE8 = 0x00000003, устанавливающая линию на выход с максимальной частотой. Также можно использовать GPIO_CRH_MODE8_0 =0x00000001 или GPIO_CRH_MODE8_1=0x00000002, которые устанавливают порт на выход с частотой 10 и 20 МГЦ соответственно. Для других линий ввода/вывода используются точно такие же константы, имеющие номер соответствующей линии. Следует учитывать, что настройка линий с 0 по 7 производится обращением к регистру GPIOC->CRL.
Третья строчка устанавливает тип ввода вывода. В данном случае используется простой цифровой вывод. Для этого в поле CNF8 необходимо записать значение 00. Делается это использованием оператора «И» и инверсией константы GPIO_CRH_CNF8. Последняя, в ее прямом значении, устанавливает режим альтернативного вывода с открыты стоком, так как ее значение равно 11. Доступны константы GPIO_CRH_CNF8_0 = 0x00000004 (режим 01) и GPIO_CRH_CNF8_1 = 0x00000008 (режим 10).
После выполнения всех этих действий, настройку порта можно считать законченной.
Пример 2. Настройка порта «классическим» способом.
RCC->APB2ENR |= 0x00000010; // Подключение тактового сигнала GPIOC->CRH = 0x00000333; // Настройка режима PORTC.8,9,10 с частотой 50 МГц
Данный код выполняет те же самые функции, что и приведенный выше. Единственное отличие – использование записи данных напрямую, без предопределенных констант. Это несколько снижает объем исходного кода и больше напоминает программирование на ассемблере.
Первая строчка полностью аналогична первому примеру. Вторая выполняет настройку сразу трех линий ввода вывода. Каждый разряд используемого операнда отвечает за одну линию. В итоге одной строчкой можно настроить половину порта ввода/вывода. Значение параметра соответствующей линии записывается в шестнадцатеричной форме, и устанавливает сразу оба поля CNF и MODE. Так значение 3h соответствует 0011 или режиму простого вывода с максимальной скоростью, а значение Bh то же самое, что и 1011 или высокоскоростной выход, подключенный к альтернативному модулю.
Пример 3. Настройка порта на вывод
GPIOC->CRH = 0x00008333;
Данный пример осуществляет установку линий 8,9,10 как выходов, а линию 11 как цифровой вход. Для этого в поля CNF11и MODE11 заносится значение 8h или в двоичном виде 1000b.
Вывод информации
Запись данных в регистр производится самым обычным способом, с помощью операции равно.
GPIOA->ODR=0xABCD; GPIOA->ODR=0x0000;
При использовании регистра GPIOx_BSRR возможна как запись значений, так и предопределенных констант. Для установки высокого уровня сигнала применяются константы GPIO_BSRR_BSy, а для сброса GPIO_BSRR_BRy, где y – номер соответствующей линии.
Пример 4. Использование GPIOx_BSRR
GPIOC->BSRR=0x00010010; GPIOC->BSRR=0x00100001; GPIOC->BSRR=GPIO_BSRR_BS4|GPIO_BSRR_BR0; GPIOC->BSRR=GPIO_BSRR_BS0|GPIO_BSRR_BR4;
Первая и третья строчки устанавливают линию 4 и сбрасывают 0, вторая и четвертая производят обратную операцию.
Чтение состояния бита
if (GPIOC->IDR & GPIO_IDR_IDR11) GPIOC->BSRR = GPIO_BSRR_BS8;
Данная строчка выполняет опрос бита 11 регистра GPIOC->IDR и установку бита 8 в случае положительного результата. Также при программировании STM32 возможно простое присваивание значения регистра IDR какой-либо переменной.
Все, вышеуказанные примеры были опробованы на плате STM32 Discovery и показали свою работоспособность.