Урок 2: GPIO и работа с портами

GPIO (General Purpose Input/Output) — универсальные порты ввода-вывода, которые позволяют микроконтроллеру взаимодействовать с внешними устройствами. В CH32 есть несколько портов GPIO с различными функциями.

Структура GPIO

CH32V307 имеет порты GPIO от A до E, каждый с 16 пинами.

  • GPIOA — порт A (PA0-PA15)
  • GPIOB — порт B (PB0-PB15)
  • GPIOC — порт C (PC0-PC15)
  • GPIOD — порт D (PD0-PD15)
  • GPIOE — порт E (PE0-PE15)

Режимы работы GPIO

Каждый пин GPIO может работать в различных режимах.

// Режимы GPIO GPIO_Mode_AIN // Аналоговый вход GPIO_Mode_IN_FLOATING // Вход без подтяжки GPIO_Mode_IPD // Вход с подтяжкой к земле GPIO_Mode_IPU // Вход с подтяжкой к питанию GPIO_Mode_Out_OD // Выход с открытым стоком GPIO_Mode_Out_PP // Выход push-pull GPIO_Mode_AF_OD // Альтернативная функция, открытый сток GPIO_Mode_AF_PP // Альтернативная функция, push-pull
  • Push-Pull — активно управляет и высоким, и низким уровнем
  • Open Drain — активно управляет только низким уровнем
  • Pullup/Pulldown — внутренний резистор подтяжки

Настройка GPIO на выход

Пример настройки пина как цифровой выход.

#include "ch32v30x.h" void GPIO_Config_Output(void) { GPIO_InitTypeDef GPIO_InitStructure; // Включение тактирования порта RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // Настройка PA5 как выход GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } int main(void) { GPIO_Config_Output(); while(1) { GPIO_SetBits(GPIOA, GPIO_Pin_5); // Высокий уровень Delay_Ms(1000); GPIO_ResetBits(GPIOA, GPIO_Pin_5); // Низкий уровень Delay_Ms(1000); } }
  • RCC_APB2PeriphClockCmd() — включает тактирование GPIO
  • GPIO_Mode_Out_PP — режим push-pull выход
  • GPIO_Speed_50MHz — максимальная скорость переключения

Настройка GPIO на вход

Чтение состояния кнопки или датчика.

#include "ch32v30x.h" void GPIO_Config_Input(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Настройка PB0 как вход с подтяжкой к питанию GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); } int main(void) { GPIO_Config_Input(); GPIO_Config_Output(); while(1) { // Чтение состояния кнопки if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == RESET) { // Кнопка нажата (подключена к земле) GPIO_SetBits(GPIOA, GPIO_Pin_5); } else { GPIO_ResetBits(GPIOA, GPIO_Pin_5); } } }
  • GPIO_Mode_IPU — вход с внутренней подтяжкой к питанию
  • GPIO_ReadInputDataBit() — чтение состояния одного пина
  • RESET — низкий уровень (0), SET — высокий уровень (1)

Работа с целым портом

Можно работать сразу с 16 битами порта.

#include "ch32v30x.h" void GPIO_Config_Port(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // Настройка всех пинов PC0-PC7 как выходы GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); } int main(void) { uint8_t counter = 0; GPIO_Config_Port(); while(1) { // Запись значения в младшие 8 бит порта C GPIO_Write(GPIOC, counter); counter++; Delay_Ms(100); } }
  • Можно объединять пины операцией |
  • GPIO_Write() — запись 16-битного значения в порт
  • Удобно для управления шинами данных

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

Многие пины GPIO могут работать в режиме альтернативных функций (UART, SPI, I2C и т.д.).

// Пример настройки UART TX/RX void GPIO_Config_UART(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // PA9 - UART TX (альтернативная функция) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // PA10 - UART RX (вход) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); }
  • GPIO_Mode_AF_PP — режим альтернативной функции
  • TX обычно настраивается как AF_PP
  • RX настраивается как вход (IN_FLOATING или IPU)
🏠 На главную