#include "linkBlink.h" static uint32_t GetTick(LedBlinker_HandleTypeDef* hblinker) { if (hblinker->htim != NULL) { return __HAL_TIM_GET_COUNTER(hblinker->htim); } return HAL_GetTick(); // Используем системный таймер если свой не задан } HAL_StatusTypeDef LedBlinker_Init(LedBlinker_HandleTypeDef* hblinker, GPIO_TypeDef* led_port, uint16_t led_pin, GPIO_TypeDef* de_re_port, uint16_t de_re_pin, TIM_HandleTypeDef* htim) { if (hblinker == NULL || led_port == NULL) { return HAL_ERROR; } // Инициализация полей hblinker->led_port = led_port; hblinker->led_pin = led_pin; hblinker->de_re_port = de_re_port; hblinker->de_re_pin = de_re_pin; hblinker->htim = htim; hblinker->blink_duration = 100; hblinker->last_blink_tick = 0; hblinker->led_state = false; hblinker->blinking = false; hblinker->blink_count = 0; hblinker->target_blink_count = 1; hblinker->last_packet_tick = 0; // Настройка пина светодиода GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = led_pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(led_port, &GPIO_InitStruct); // Выключаем светодиод HAL_GPIO_WritePin(led_port, led_pin, GPIO_PIN_RESET); // Настройка пина управления RS485 если используется if (de_re_port != NULL && de_re_pin != 0) { GPIO_InitStruct.Pin = de_re_pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(de_re_port, &GPIO_InitStruct); // Режим приема по умолчанию HAL_GPIO_WritePin(de_re_port, de_re_pin, GPIO_PIN_RESET); } return HAL_OK; } void LedBlinker_Update(LedBlinker_HandleTypeDef* hblinker) { if (hblinker == NULL || !hblinker->blinking) return; uint32_t current_tick = HAL_GetTick(); if ((current_tick - hblinker->last_blink_tick) >= hblinker->blink_duration) { hblinker->last_blink_tick = current_tick; // Переключаем состояние светодиода hblinker->led_state = !hblinker->led_state; HAL_GPIO_WritePin(hblinker->led_port, hblinker->led_pin, hblinker->led_state ? GPIO_PIN_SET : GPIO_PIN_RESET); // Если светодиод выключился, уменьшаем счетчик if (!hblinker->led_state) { hblinker->blink_count++; if (hblinker->blink_count >= hblinker->target_blink_count) { hblinker->blinking = false; HAL_GPIO_WritePin(hblinker->led_port, hblinker->led_pin, GPIO_PIN_RESET); } } } } void LedBlinker_ProcessPacket(LedBlinker_HandleTypeDef* hblinker, uint8_t* data, uint16_t len) { if (hblinker == NULL || data == NULL || len == 0) return; hblinker->last_packet_tick = HAL_GetTick(); // Анализ пакета и выбор паттерна мигания if (len >= 1) { // Пример: первый байт определяет количество миганий uint8_t blink_count = data[0]; if (blink_count == 0) blink_count = 1; if (blink_count > 20) blink_count = 20; // Ограничение // Второй байт может определять длительность (если есть) uint32_t duration = 100; if (len >= 2) { duration = 50 + (data[1] * 10); if (duration > 1000) duration = 1000; } LedBlinker_BlinkPattern(hblinker, blink_count, duration); } // Дополнительные паттерны в зависимости от данных if (len >= 4 && data[0] == 0xFF) { // Специальный паттерн для команд LedBlinker_BlinkPattern(hblinker, 5, 50); } } void LedBlinker_BlinkOnce(LedBlinker_HandleTypeDef* hblinker, uint32_t duration) { if (hblinker == NULL) return; hblinker->blink_duration = duration; hblinker->target_blink_count = 1; hblinker->blink_count = 0; hblinker->blinking = true; hblinker->led_state = false; hblinker->last_blink_tick = GetTick(hblinker); // Немедленное включение HAL_GPIO_WritePin(hblinker->led_port, hblinker->led_pin, GPIO_PIN_SET); hblinker->led_state = true; } void LedBlinker_BlinkPattern(LedBlinker_HandleTypeDef* hblinker, uint8_t count, uint32_t duration) { if (hblinker == NULL || count == 0) return; hblinker->blink_duration = duration; hblinker->target_blink_count = count; hblinker->blink_count = 0; hblinker->blinking = true; hblinker->led_state = false; hblinker->last_blink_tick = HAL_GetTick(); // Немедленное включение HAL_GPIO_WritePin(hblinker->led_port, hblinker->led_pin, GPIO_PIN_SET); hblinker->led_state = true; } void LedBlinker_SetRS485Mode(LedBlinker_HandleTypeDef* hblinker, bool transmit) { if (hblinker == NULL || hblinker->de_re_port == NULL) return; HAL_GPIO_WritePin(hblinker->de_re_port, hblinker->de_re_pin, transmit ? GPIO_PIN_SET : GPIO_PIN_RESET); } bool LedBlinker_IsBlinking(LedBlinker_HandleTypeDef* hblinker) { return (hblinker != NULL) ? hblinker->blinking : false; } uint32_t LedBlinker_GetTimeSinceLastPacket(LedBlinker_HandleTypeDef* hblinker) { if (hblinker == NULL) return 0; if (hblinker->last_packet_tick == 0) return 0; return GetTick(hblinker) - hblinker->last_packet_tick; }