#include <stm32f0xx.h>
// Определение пинов
#define LED_COUNT 8
const uint16_t ledPins[LED_COUNT] = {GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_5, GPIO_Pin_6,
GPIO_Pin_9, GPIO_Pin_15, GPIO_Pin_10, GPIO_Pin_8};
const uint16_t buttonPin = GPIO_Pin_8;
int currentLed = 0;
int direction = 1;
uint8_t lastButtonState = 1;
void setup() {
// Включение тактирования портов A и B
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
// Настройка светодиодов как выходы
for (int i = 0; i < LED_COUNT; i++) {
GPIOA->MODER &= ~(0x3 << (2 * ((ledPins[i] == GPIO_Pin_15) ? 15 : __builtin_ctz(ledPins[i]))));
GPIOA->MODER |= (0x1 << (2 * ((ledPins[i] == GPIO_Pin_15) ? 15 : __builtin_ctz(ledPins[i]))));
}
// Настройка кнопки как входа с подтягивающим резистором
GPIOB->MODER &= ~(0x3 << (2 * 8)); // PB8
GPIOB->PUPDR |= (0x1 << (2 * 8)); // Подтяжка вверх
}
void loop() {
// Чтение состояния кнопки
uint8_t buttonState = (GPIOB->IDR & buttonPin) ? 1 : 0;
// Обработка нажатия кнопки
if (buttonState == 0 && lastButtonState == 1) {
direction *= -1;
// Задержка для антидребезга
for (volatile int i = 0; i < 100000; i++);
}
lastButtonState = buttonState;
// Гасим все светодиоды
GPIOA->BRR = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_5 | GPIO_Pin_6 |
GPIO_Pin_9 | GPIO_Pin_15 | GPIO_Pin_10 | GPIO_Pin_8;
// Зажигаем текущий светодиод
GPIOA->BSRR = ledPins[currentLed];
// Переходим к следующему светодиоду
currentLed += direction;
// Проверяем границы
if (currentLed >= LED_COUNT) currentLed = 0;
if (currentLed < 0) currentLed = LED_COUNT - 1;
// Задержка
for (volatile int i = 0; i < 500000; i++);
}