Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // === Конфигурация периферии и утилиты ===
- #include "riscv_csr_encoding.h"
- #include "scr1_csr_encoding.h"
- #include "mcu32_memory_map.h"
- #include <power_manager.h>
- #include <pad_config.h>
- #include <gpio_irq.h>
- #include <epic.h>
- #include <csr.h>
- #include <gpio.h>
- // === Аппаратные определения ===
- #define INDICATOR_A 9U
- #define INDICATOR_B 10U
- #define USER_SWITCH 15U
- #define SWITCH_BANK 1U
- // === Вспомогательные макросы ===
- #define BIT(n) (1U << (n))
- #define IS_PRESSED(p) (((p)->STATE & BIT(USER_SWITCH)) == 0U)
- #define TOGGLE_STATE(s) ((s) ^= 1U)
- // === Прототипы локальных функций ===
- static void system_clocks_init(void);
- static void io_pins_configure(void);
- static void indicators_set(uint8_t pattern);
- static void short_delay_ms(uint32_t cycles);
- static uint8_t read_switch_stable(void);
- // === Точка входа ===
- void main(void)
- {
- system_clocks_init();
- io_pins_configure();
- uint8_t current_pattern = 0U; // 0 → A, 1 → B
- indicators_set(current_pattern);
- for (;;) {
- if (read_switch_stable()) {
- TOGGLE_STATE(current_pattern);
- indicators_set(current_pattern);
- // Ждём отпускания с подтверждением
- while (read_switch_stable()) {
- short_delay_ms(100U);
- }
- }
- }
- }
- // === Реализация функций ===
- static void system_clocks_init(void)
- {
- // Включаем тактирование GPIO-портов и контроллеров прерываний
- PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_0_M
- | PM_CLOCK_APB_P_GPIO_1_M
- | PM_CLOCK_APB_P_GPIO_2_M
- | PM_CLOCK_APB_P_GPIO_IRQ_M;
- // Активируем модули конфигурации, пробуждения, питания и EPIC
- PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PAD_CONFIG_M
- | PM_CLOCK_APB_M_WU_M
- | PM_CLOCK_APB_M_PM_M
- | PM_CLOCK_APB_M_EPIC_M;
- // Тактируем SPIFI для полной совместимости
- PM->CLK_AHB_SET |= PM_CLOCK_AHB_SPIFI_M;
- }
- static void io_pins_configure(void)
- {
- // Кнопка — вход с подтяжкой (аппаратной)
- GPIO_1->DIRECTION_IN = BIT(USER_SWITCH);
- // Светодиоды — выходы
- GPIO_0->DIRECTION_OUT = BIT(INDICATOR_A) | BIT(INDICATOR_B);
- // Начальное состояние: горит первый индикатор
- GPIO_0->OUTPUT = BIT(INDICATOR_A);
- }
- static void indicators_set(uint8_t pattern)
- {
- // pattern == 0 → INDICATOR_A, иначе → INDICATOR_B
- GPIO_0->OUTPUT = (pattern == 0U) ? BIT(INDICATOR_A) : BIT(INDICATOR_B);
- }
- static void short_delay_ms(uint32_t cycles)
- {
- for (volatile uint32_t c = 0U; c < cycles; ++c) {
- __asm__ volatile ("" ::: "memory"); // барьер компилятора
- }
- }
- static uint8_t read_switch_stable(void)
- {
- // Антидребезг: два подтверждения с паузой
- if (!IS_PRESSED(GPIO_1)) return 0U;
- short_delay_ms(30000U); // ~10-20 мс в зависимости от частоты
- return IS_PRESSED(GPIO_1) ? 1U : 0U;
- }
Advertisement
Add Comment
Please, Sign In to add comment