Найти в Дзене
etrivia

CH32V003xxxx Разбираемся с GPIO. Часть 2.2

Ссылка на предыдущую часть "Разбираемся с GPIO. Часть 2.1"

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

Ещё один момент, дзен совершенно не приспособлен для публикации исходников. Не поддерживается тег <code> и ширина колонки всего 69 символов. Поэтому такое кривое форматирование. Но лучше так чем совсем никак.

В прошлой статье о портах ввода вывода, помигали светодиодами, остановились на функции GPIO_WriteBit() и регистре GPIOD_OUTDR. Теперь разберёмся как собственно на ножках контроллера появляются нули и единицы. Для этого есть два регистра, начнём с регистра GPIOD_BSHR.

GPIOD_BSHR
GPIOD_BSHR

Не зря в названии регистра присутствует Reser/Set, записав в бит BS единичку подаём единицу на ножку, а записав единичку в бит BR сбрасываем ножку в ноль. У многих немедленно возникает вопрос, а что будет если неудержимый носорог врежется в несокрушимую скалу одновременно записать единички в биты BR и BS? Отвечаю, победит бит BS.

Кроме этого есть ещё один регистр GPIOD_BCR.

GPIOx_BCR
GPIOx_BCR

Они позволяет только сбрасывать ножку в ноль. Для этого нужно записать единицу в бит BR.

Посмотрим как устроена функция GPIO_WriteBit() которая предлагается в примерах. Она находится в файле C:\MRS_DATA\workspace\CH32V003F4P6\Peripheral\src\ch32v00x_gpio.c

/*********************************************************************
* @fn GPIO_WriteBit
*
* @brief Sets or clears the selected data port bit.
*
* @param GPIO_Pin - specifies the port bit to be written.
* This parameter can be one of GPIO_Pin_x where x can be (0..15).
* BitVal - specifies the value to be written to the selected bit.
* Bit_RESET - to clear the port pin.
* Bit_SET - to set the port pin.
*
* @return none
*/
void GPIO_WriteBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
{
if(BitVal != Bit_RESET)
{
GPIOx->BSHR = GPIO_Pin;
}
else
{
GPIOx->BCR = GPIO_Pin;
}
}
Так и есть, она записывает единички либо GPIOx_BSHR либо GPIOx_BCR. Хорошая функция, будем применять.

Справедливости ради, нужно заметить, что есть и третий путь, можно записывать данные в рассмотренный нами в предыдущей статье регистр GPIOD_OUTDR.

GPIOx_OUTDR
GPIOx_OUTDR

К примеру вот так можно установить четвёртый пин в ноль
GPIOD->OUTDR &= ~GPIO_Pin_4;.

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

Переходим к тому как узнать состояние кнопки подключенной к ножке микроконтроллера. За это отвечает 7.3.1.2 Port Input Register (GPIOx_INDR) (x=A/C/D)

GPIOx_INDR
GPIOx_INDR

Тут всё просто, читаем нужный бит x=GPIOD->INDR & GPIO_Pin_3; И если вход сконфигурирован как вход с подтяжкой (With pull-up and pull-down mode) то не забываем с помощью выше рассмотренного регистра GPIOx_OUTDR указать подтяжка вверх или вниз. Для этого в функцию инициализации надо добавить эту настройку.

// Если ножка сконфигурирована как подтянутый вход.
// Выбираем тип подтяжки. Вверх или вниз.
#define INP_PULL_UP 0x1 // Подтянуть вверх.
#define INP_PULL_DOWN 0x0 // Подтянуть вниз.
GPIOD->OUTDR |= (
(INP_PULL_DOWN << 2)| // Пин 2 вниз.
(INP_PULL_UP << 3) // Пин 3 вверх.
);

Следующий регистр для работы с GPIO это 7.3.1.6 Port Configuration Lock Register (GPIOx_LCKR) (x=A/C/D)

GPIOx_LCKR
GPIOx_LCKR

Позволяет заблокировать возможность изменения настроек GPIO. Блокировка будет действовать до перезагрузки микроконтроллера. Я честно говоря не понимаю зачем это нужно, но в любом случае чем больше регистров тем лучше. Просто так выполнить запись в этот регистр не получится. Нужен определённый ритуал. А именно, совместно с нужным битом LCKу нужно установить бит LCKK
снять бит LCKK
установить бит LCKK
прочитать регистр GPIOx_LCKR
ещё раз прочитать регистр GPIOx_LCKR чтобы убедиться, что нужный бит установлен. IDE предлагает готовую функцию, чтобы освободить нас от этого шаманства. Она находится в файле C:\MRS_DATA\workspace\CH32V003F4P6\Peripheral\src\ch32v00x_gpio.c

/*********************************************************************
* @fn GPIO_PinLockConfig
*
* @brief Locks GPIO Pins configuration registers.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
* GPIO_Pin - specifies the port bit to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
*
* @return none
*/
void GPIO_PinLockConfig(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
uint32_t tmp = 0x00010000;
tmp |= GPIO_Pin;
GPIOx->LCKR = tmp;
GPIOx->LCKR = GPIO_Pin;
GPIOx->LCKR = tmp;
tmp = GPIOx->LCKR;
tmp = GPIOx->LCKR;
}

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

Всё что тут написано можно обсудить в комментариях и телеграм канале etrivia.

Посетите наш магазин https://etrivia.ru

#CH32V003 #MounRiver #GPIO