https://hubstub.ru/stm32/65-stm32-gpio-ili-porty-vvoda-vyvoda.html stm32f1xx //Полагаем что выводы после сброса в режиме плавающего входа //разрешаем тактирование порта A RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //вход с подтяжкой к + GPIOA->CRL &= ~GPIO_CRL_CNF0; GPIOA->CRL |= GPIO_CRL_CNF0_1; GPIOA->ODR |= GPIO_ODR_ODR0; //вход с подтяжкой к - GPIOA->CRL &= ~GPIO_CRL_CNF1; GPIOA->CRL |= GPIO_CRL_CNF1_1; GPIOA->ODR &= ~GPIO_ODR_ODR1; //аналоговый режим GPIOA->CRL &= ~GPIO_CRL_CNF2; //выход с открытым стоком 2MHz GPIOA->CRL &= ~GPIO_CRL_CNF3; GPIOA->CRL |= GPIO_CRL_CNF3_0; GPIOA->CRL |= GPIO_CRL_MODE3_1; //двухтактный выход 10MHz GPIOA->CRL &= ~GPIO_CRL_CNF4; GPIOA->CRL |= GPIO_CRL_MODE4_0; //альтернативная ф-ция, двухтактный выход, 50 MHz GPIOA->CRL &= ~GPIO_CRL_CNF5; GPIOA->CRL |= GPIO_CRL_CNF5_1; GPIOA->CRL |= GPIO_CRL_MODE5; //альтернативная ф-ция, выход с открытым стоком, 50 MHz GPIOA->CRL |= GPIO_CRL_CNF6; GPIOA->CRL |= GPIO_CRL_MODE6; //проверяем значение нулевого вывода порта А if (GPIOА->IDR & GPIO_IDR_IDR0) //если вывод в режиме входа то активируется подтяжка к питанию GPIOA->ODR |= GPIO_ODR_ODR0; //или к земле GPIOA->ODR &= ~GPIO_ODR_ODR0; //если в режиме выхода, то на нём установится соответствующий лог.уровень //например так можно установить все выходы порта в 1 GPIOA->ODR = 0xFFFF; //сбросить нулевой бит порта А GPIOA->BRR = GPIO_BRR_BR0; //сбросить нулевой бит GPIOA->BSRR = GPIO_BSRR_BR0; //установить нулевой бит GPIOA->BSRR = GPIO_BSRR_BS0; -=-=- Как проверить состояние пина порта? Скажем 4 пина порта С? просто. Можно использовать стандартную библиотеку: if (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4)== Bit_RESET).... Можно и так(само коротко и быстро: if (GPIOС->IDR & GPIO_IDR_IDR4)... #define pin_X (GPIOС->IDR & GPIO_IDR_IDR4) if (pin_X == 1) {......} -=-=- Код: #define GPIO_ODR_ODR0 ((uint16_t)0x0001) /*!< Port output data, bit 0 */ #define GPIO_ODR_ODR1 ((uint16_t)0x0002) /*!< Port output data, bit 1 */ #define GPIO_ODR_ODR2 ((uint16_t)0x0004) /*!< Port output data, bit 2 */ GPIO_ODR_ODR0 это макросы описывающие битовую маску. Хотите изменить сразу несколько - пишите как я в примере или укажите свою маску: Код: GPIOB->ODR ^=0x00ff; //переключит младшие 8 ног. или что-б потом самому легче читалось: Код: /* маска для 8-ми нечетных ног */ #define ODD_0_8 0x0055 /* маска для 8-ми четных ног */ #define EVEN_0_8 0x00AA GPIOB->ODR ^= ODD_0_8; //переключит нечетные GPIOB->ODR ^= EVEN_0_8; //переключит четные -=-=-=-=-=- а как тогда событие нажатия отследить? Ну, как-то так (одновременно и с дребезгом поборемся): Код: #define MAXCNT 10 char flip=0, pressed=0; while(1) { if((GPIOA->IDR&0x01)==0) //кнопка не нажата (или 0 читается во впемя дребезга) - готовимся к обработке { pressed=0; cntr=0; } else if(!pressed) //кнопка вроде бы нажата, но возможно это пока что только дребезг { cntr++; // сосчитаем до десяти в надежде, что за это время переходные процессы завершатся if(cntr>MAXCNT) // десять последних проходов кнопка в состоянии "нажато" - считаем, что событие "нажатие кнопки" свершилось { // тут соб-сно ваша реакция на событие "нажатие кнопки", т.е. переход от 0 к 1 flip=!flip; // организуем простейший двоичный переключатель ("flip-flop") if(flip) // и в зависимости от его состояния выполняем ту или иную ветвь { GPIOC->BSRR = GPIO_BSRR_BS9; GPIOC->BSRR = GPIO_BSRR_BR8; } else { GPIOC->BSRR = GPIO_BSRR_BS8; GPIOC->BSRR = GPIO_BSRR_BR9; } pressed=1; // отработав событие "нажатие кнопки", отключаем проверку на это событие -> до следующего отпускания кнопки } } else //кнопка в состоянии "нажато" (после отловленного события "нажатие кнопки") - в нашем случае неинтересно { } }