Compare commits

8 Commits

Author SHA1 Message Date
Razvalyaev
5ad51f0d61 В LED добавлен режим помежуточной яркости диода 2026-02-05 17:30:27 +03:00
Razvalyaev
c0733a1d31 улучшение макросов для тиков 2025-11-28 18:18:19 +03:00
Razvalyaev
11c00f1e0c исправлена фильтарцяи дребезга кнопки 2025-11-24 18:59:44 +03:00
Razvalyaev
74d692fdd5 Добавлены дефайны для принудитльного выставление ARR, PSC в таймерах 2025-11-19 15:27:41 +03:00
Razvalyaev
2344926f92 деактивация модуля __general_flash, т.к. он все равно пока не сделан 2025-11-19 00:38:39 +03:00
Razvalyaev
272642b310 Добавлены дефайны для расчета тиков по периоду в мс и мкс
фикс расчета по частоте из предыдущего комита
2025-11-16 19:39:49 +03:00
Razvalyaev
b3f118b074 Добавлен дефайн для расчета тиков исходя из частоты
* надо добавить дефайн для расчета тиков исъходя из периода
2025-11-15 19:05:48 +03:00
2eae8d34d8 Обновить README.md 2025-11-07 22:37:59 +03:00
5 changed files with 111 additions and 32 deletions

View File

@@ -63,8 +63,9 @@ typedef enum
{ {
LED_IS_OFF = 0, ///< Светодиод выключен LED_IS_OFF = 0, ///< Светодиод выключен
LED_IS_ON = 1, ///< Светодиод включен LED_IS_ON = 1, ///< Светодиод включен
LED_IS_BLINKING = 2, ///< Моргание светодиодом LED_IS_DUTY = 2, ///< Светодиод включен на частичную яркость
LED_IS_FADING = 3, ///< Плавное моргание светодиодом LED_IS_BLINKING = 3, ///< Моргание светодиодом
LED_IS_FADING = 4, ///< Плавное моргание светодиодом
}GPIO_LEDStateTypeDef; }GPIO_LEDStateTypeDef;
/** /**
@@ -80,6 +81,7 @@ typedef struct
uint8_t LED_ActiveLvl; ///< Активный уровень ножки (при котором светодиод горит) uint8_t LED_ActiveLvl; ///< Активный уровень ножки (при котором светодиод горит)
uint32_t LED_Period; ///< Период моргания светодиода uint32_t LED_Period; ///< Период моргания светодиода
uint32_t LED_Duty; ///< Текущая яркость светодиода
uint32_t tickprev; uint32_t tickprev;
}GPIO_LEDTypeDef; }GPIO_LEDTypeDef;
@@ -94,7 +96,7 @@ typedef struct
uint32_t Sw_Pin; ///< GPIO пин ножки кнопки uint32_t Sw_Pin; ///< GPIO пин ножки кнопки
uint8_t Sw_ActiveLvl; ///< Активный уровень ножки (при котором кнопка нажата) uint8_t Sw_ActiveLvl; ///< Активный уровень ножки (при котором кнопка нажата)
uint32_t Sw_PrevState; ///< Предыдущее состояние кнопки uint32_t Sw_CurrentState; ///< Текущее состояние кнопки
uint32_t Sw_FilterDelay; ///< Фильтр от дребезга (в мс) uint32_t Sw_FilterDelay; ///< Фильтр от дребезга (в мс)
uint32_t tickprev; uint32_t tickprev;
@@ -192,6 +194,8 @@ HAL_StatusTypeDef GPIO_LED_On (GPIO_LEDTypeDef *led);
HAL_StatusTypeDef GPIO_LED_Off (GPIO_LEDTypeDef *led); HAL_StatusTypeDef GPIO_LED_Off (GPIO_LEDTypeDef *led);
/* Выставить светодиод по переменной */ /* Выставить светодиод по переменной */
HAL_StatusTypeDef GPIO_LED_Set (GPIO_LEDTypeDef *led, uint8_t led_state); HAL_StatusTypeDef GPIO_LED_Set (GPIO_LEDTypeDef *led, uint8_t led_state);
/* Выставить яркость светодиод */
HAL_StatusTypeDef GPIO_LED_Duty_Set(GPIO_LEDTypeDef *led, uint8_t led_duty);
/* Активировать моргание светодиодом */ /* Активировать моргание светодиодом */
HAL_StatusTypeDef GPIO_LED_Blink_Start (GPIO_LEDTypeDef *led, uint32_t period); HAL_StatusTypeDef GPIO_LED_Blink_Start (GPIO_LEDTypeDef *led, uint32_t period);
/* Активировать моргание светодиодом */ /* Активировать моргание светодиодом */

View File

@@ -185,6 +185,55 @@ typedef struct // struct with variables for encoder
@endcode @endcode
* @{ * @{
*/ */
/**
* @brief Преобразование частоты в количество тиков таймера.
* @param _freq_ Желаемая частота в Гц.
* @param _timfreqMHz_ Тактовая частота таймера в МГц.
* @return Количество тиков для достижения заданной частоты.
* @details Расчет: (1 000 000 * частотааймера) / желаемая_частота.
*/
#define TIM_FreqToTick(_freq_, _timfreqMHz_) (((1000000*(_timfreqMHz_))/(_freq_))-1)
/**
* @brief Преобразование миллисекунд в количество тиков таймера.
* @param _ms_ Время в миллисекундах.
* @param _timfreqMHz_ Тактовая частота таймера в МГц.
* @return Количество тиков для заданного времени.
* @details Расчет: (мс * 1000 * частотааймера).
*/
#define TIM_MillisToTick(_ms_, _timfreqMHz_) (((uint32_t)((_ms_) * 1000UL * (_timfreqMHz_)))-1)
/**
* @brief Преобразование микросекунд в количество тиков таймера.
* @param _us_ Время в микросекундах.
* @param _timfreqMHz_ Тактовая частота таймера в МГц.
* @return Количество тиков для заданного времени.
* @details Расчет: (мкс * частотааймера).
*/
#define TIM_MicrosToTick(_us_, _timfreqMHz_) (((uint32_t)((_us_) * (_timfreqMHz_)))-1)
/**
* @brief Установка автоперезагрузки (ARR) с принудительным обновлением теневого регистра.
* @param __HANDLE__ Указатель на хендл таймера.
* @param __AUTORELOAD__ Значение автоперезагрузки.
* @details Генерирует событие обновления для немедленного применения нового значения ARR.
* Решает проблему обновления теневых регистров только при переполнении.
*/
#define __HAL_TIM_SET_AUTORELOAD_FORCE(__HANDLE__, __AUTORELOAD__) \
do{ __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__); \
HAL_TIM_GenerateEvent(__HANDLE__, TIM_EVENTSOURCE_UPDATE); } while(0);
/**
* @brief Установка предделителя (PSC) с принудительным обновлением теневого регистра.
* @param __HANDLE__ Указатель на хендл таймера.
* @param __PRESC__ Значение предделителя.
* @details Генерирует событие обновления для немедленного применения нового значения PSC.
* Решает проблему обновления теневых регистров только при переполнении.
*/
#define __HAL_TIM_SET_PRESCALER_FORCE(__HANDLE__, __PRESC__) \
do{ __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__); \
HAL_TIM_GenerateEvent(__HANDLE__, TIM_EVENTSOURCE_UPDATE); } while(0);
/* Initialize TIM with TIM_SettingsTypeDef structure */ /* Initialize TIM with TIM_SettingsTypeDef structure */
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef* stim); HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef* stim);
/* Initialize TIMs clock and interrupt */ /* Initialize TIMs clock and interrupt */

View File

@@ -5,7 +5,7 @@ STM32_General - это набор библиотек для удобной ра
## Структура библиотеки ## Структура библиотеки
*Note: STM32_General требует наличия библиотеки (MyLibs)[https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs] для работы*** *Note: STM32_General требует наличия библиотеки [MyLibs](https://git.arktika.cyou/Razvalyaev/STM32_ExtendedLibs) для работы*
``` ```
ProjectRoot/ ProjectRoot/
└── STM32_General # Работа с периферией STM32 └── STM32_General # Работа с периферией STM32

View File

@@ -1,4 +1,6 @@
#include "__general_flash.h" #include "__general_flash.h"
#if 0
FLASH_EraseInitTypeDef EraseInitStruct; FLASH_EraseInitTypeDef EraseInitStruct;
extern HAL_StatusTypeDef res_hal; extern HAL_StatusTypeDef res_hal;
unsigned CRC_Update; unsigned CRC_Update;
@@ -190,3 +192,4 @@ HAL_StatusTypeDef FLASH_Write_Word(uint32_t Address, uint32_t Data)
} }
//---------------------------------------------------------- //----------------------------------------------------------
#endif

View File

@@ -136,6 +136,23 @@ HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state)
return GPIO_LED_Off(led); return GPIO_LED_Off(led);
} }
} }
/**
* @brief Выставить яркость светодиод
* @param led Указатель на структуру светодиода
* @param led_duty Яркость светодиода
* @return HAL Status
*/
HAL_StatusTypeDef GPIO_LED_Duty_Set(GPIO_LEDTypeDef *led, uint8_t led_duty)
{
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return HAL_ERROR;
led_duty = (led_duty*LED_PWM_TICKS)/100;
led->state = LED_IS_DUTY;
led->LED_Duty = led_duty;
return HAL_OK;
}
/** /**
* @brief Активировать моргание светодиодом * @brief Активировать моргание светодиодом
* @param led Указатель на структуру светодиода * @param led Указатель на структуру светодиода
@@ -199,6 +216,21 @@ void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led)
led->tickprev = tickcurrent; led->tickprev = tickcurrent;
} }
} }
/* Режим промежуточной яркости светодиода */
else if(led->state == LED_IS_DUTY)
{
uint32_t tickcurrent = local_time();
/* Формирование ШИМ для яркости */
int duty_crt = (led->LED_Duty*led->LED_Duty/LED_PWM_TICKS);
if(tickcurrent%LED_PWM_TICKS < duty_crt)
{
HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
}
else
{
HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
}
}
/* Режим плавного моргания светодиода */ /* Режим плавного моргания светодиода */
else if(led->state == LED_IS_FADING) else if(led->state == LED_IS_FADING)
{ {
@@ -229,6 +261,7 @@ void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led)
} }
led->tickprev = tickcurrent; led->tickprev = tickcurrent;
} }
led->LED_Duty = duty;
/* Формирование ШИМ для изменения яркости */ /* Формирование ШИМ для изменения яркости */
int duty_crt = (duty*duty/LED_PWM_TICKS); int duty_crt = (duty*duty/LED_PWM_TICKS);
if(tickcurrent%LED_PWM_TICKS < duty_crt) if(tickcurrent%LED_PWM_TICKS < duty_crt)
@@ -280,47 +313,37 @@ int GPIO_Read_Switch(GPIO_SwitchTypeDef *sw)
if(check_null_ptr_3(sw, sw->Sw_Port, sw->Sw_Pin)) if(check_null_ptr_3(sw, sw->Sw_Port, sw->Sw_Pin))
return -1; return -1;
if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl) int current_level = (HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl);
if(sw->Sw_FilterDelay) // если включена защита от дребезга
{ {
sw->Sw_PrevState = 1; // Если таймер не запущен и состояние изменилось - запускаем таймер
if(sw->tickprev == 0 && current_level != sw->Sw_CurrentState)
if(sw->Sw_FilterDelay) // если включена защита от дребезга
{ {
if(sw->tickprev == 0) sw->tickprev = local_time();
sw->tickprev = local_time(); }
// Если таймер запущен
if(sw->tickprev != 0)
{
// Проверяем, прошел ли достаточный интервал для фильтрации
if((local_time() - sw->tickprev) >= sw->Sw_FilterDelay) if((local_time() - sw->tickprev) >= sw->Sw_FilterDelay)
{ {
if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl) // Обновляем состояние только если оно все еще отличается
if(current_level != sw->Sw_CurrentState)
{ {
return 1; sw->Sw_CurrentState = current_level;
} }
else // Останавливаем таймер в любом случае
{
sw->tickprev = 0;
return 0;
}
}
}
else // если нет защиты от дребезга
{
if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
{
return 1;
}
else
{
sw->tickprev = 0; sw->tickprev = 0;
return 0;
} }
} }
} }
else else // если нет защиты от дребезга
{ {
sw->Sw_PrevState = 0; sw->Sw_CurrentState = current_level;
} }
return 0; return sw->Sw_CurrentState;
} }
//------------------------GPIO SW FUNCTIONS------------------------- //------------------------GPIO SW FUNCTIONS-------------------------
//------------------------------------------------------------------- //-------------------------------------------------------------------