Урок 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()— включает тактирование GPIOGPIO_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)