Доработал модуль TIM (с точки зрения документции. Код не проверен)

Доработна документация в целом
	- добавелн main page
	- исправлены ошибки в шапках и коментах
	- добавлен граф инклюдов
This commit is contained in:
2025-10-19 11:55:12 +03:00
parent f61aa1ff0f
commit 9d720767b0
534 changed files with 13259 additions and 9229 deletions

View File

@@ -1,7 +1,7 @@
/*********************************UART**************************************
Данный файл содержит объявления базовых функции и дефайны для инициализации
UART.
***************************************************************************/
/**************************************************************************
* @file general_flash.h
* @brief Заголовочны файл модуля работы с FLASH.
*************************************************************************/
#ifndef __FLASH_GENERAL_H_
#define __FLASH_GENERAL_H_
@@ -41,22 +41,4 @@ HAL_StatusTypeDef FLASH_Write_HalfWord(uint32_t Address, uint16_t Data);
HAL_StatusTypeDef FLASH_Write_Word(uint32_t Address, uint32_t Data);
///////////////////////////---FUNCTIONS---///////////////////////////
#ifndef LED_PWM_TICKS
#define LED_PWM_TICKS 15
#endif
#ifndef LED_ON
#define LED_ON 1
#endif
#ifndef LED_OFF
#define LED_OFF 0
#endif
#ifndef SW_ON
#define SW_ON 1
#endif
#ifndef SW_OFF
#define SW_OFF 0
#endif
#endif // __FLASH_GENERAL_H_

View File

@@ -1,8 +1,8 @@
/**
**************************************************************************
* @file general_spi.h
* @brief Заголовочны файл модуля инициализации SPI.
*************************************************************************/
**************************************************************************
* @file general_spi.h
* @brief Заголовочны файл модуля инициализации SPI.
*************************************************************************/
#ifndef __SPI_GENERAL_H_
#define __SPI_GENERAL_H_

View File

@@ -1,130 +0,0 @@
/**
**************************************************************************
* @file general_tim.h
* @brief Заголовочный файл для базовой работы с таймерами.
*************************************************************************/
#ifndef __TIM_GENERAL_H_
#define __TIM_GENERAL_H_
/////////////////////////////////////////////////////////////////////
/////////////////////////---USER SETTINGS---/////////////////////////
#define HAL_TIM_MODULE_ENABLED // need to uncomment this define in stm32f4xx_hal_conf.h
#define USE_TIM1
#define USE_TIM2
#define USE_TIM3
#define USE_TIM4
#define USE_TIM5
#define USE_TIM6
#define USE_TIM7
#define USE_TIM8
#define USE_TIM9
#define USE_TIM10
#define USE_TIM11
#define USE_TIM12
#define USE_TIM13
#define USE_TIM14
/* note: used uart defines in modbus.h */
/////////////////////////---USER SETTINGS---/////////////////////////
#include "mylibs_defs.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
#define TIM_IT_CONF_Pos 0
//#define TIM_PWM_CONF_Pos 1
//#define TIM_CLCK_SRC_CONF_Pos 2
//#define TIM_SLAVE_CONF_Pos 3
//#define TIM_MASTER_CONF_Pos 4
//#define TIM_BDTR_CONF_Pos 5
#define TIM_IT_CONF (1<<(TIM_IT_CONF_Pos))
//#define TIM_PWM_CONF (1<<(TIM_PWM_Pos))
#define TIM_Alternate_Mapping(INSTANCE) ((((INSTANCE) == TIM1) || ((INSTANCE) == TIM2))? GPIO_AF1_TIM1: \
(((INSTANCE) == TIM3) || ((INSTANCE) == TIM4) || ((INSTANCE) == TIM5))? GPIO_AF2_TIM3: \
(((INSTANCE) == TIM8) || ((INSTANCE) == TIM9) || ((INSTANCE) == TIM10) || ((INSTANCE) == TIM11))? GPIO_AF3_TIM8: \
(((INSTANCE) == TIM12) || ((INSTANCE) == TIM13) || ((INSTANCE) == TIM14))? GPIO_AF9_TIM12: \
(0))
////////////////////////////---DEFINES---////////////////////////////]
/////////////////////////////////////////////////////////////////////
///////////////////////---STRUCTURES & ENUMS---//////////////////////
typedef enum
{
TIM_DEFAULT = 0,
TIM_IT_MODE = TIM_IT_CONF,
// TIM_PWM_MODE = TIM_PWM_ENABLE,
// TIM_PWM_IT_MODE = TIM_PWM_ENABLE | TIM_IT_CONF,
}TIM_ITModeTypeDef;
typedef enum
{
TIM_Base_Disable = 0,
TIM_TickBase_1US = 1,
TIM_TickBase_10US = 10,
TIM_TickBase_100US = 100,
TIM_TickBase_1MS = 1000,
TIM_TickBase_10MS = 10000,
TIM_TickBase_100MS = 100000,
}TIM_MHzTickBaseTypeDef;
typedef struct // struct with settings for custom function
{
TIM_HandleTypeDef htim;
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_SlaveConfigTypeDef sSlaveConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
TIM_ITModeTypeDef sTimMode;
TIM_MHzTickBaseTypeDef sTickBaseUS;
uint8_t sTickBasePrescaler;
float sTimAHBFreqMHz;
float sTimFreqHz;
}TIM_SettingsTypeDef;
typedef struct // struct with variables for encoder
{
int16_t Encoder_Diff;
TIM_HandleTypeDef *htim;
TIM_Encoder_InitTypeDef sConfig;
GPIO_TypeDef *GPIOx;
uint32_t GPIO_PIN_TI1;
uint32_t GPIO_PIN_TI2;
uint32_t GPIO_PIN_SW;
}TIM_EncoderTypeDef;
///////////////////////---STRUCTURES & ENUMS---//////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////////---FUNCTIONS---///////////////////////////
/* Initialize TIM with TIM_SettingsTypeDef structure */
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef* stim);
/* Initialize PWM Channel and GPIO for output */
HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t PWM_PIN);
/* Initialize TIM Encoder functional */
HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc1, TIM_HandleTypeDef *htim);
/* Initialize OC Comparator */
HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL);
/* Start delay via TIM */
HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim);
/* Delay via TIM */
HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay);
/* Wait Delay via TIM without blocking app */
HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay);
/* Initialize TIMs clock and interrupt */
void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode);
/* DeInitialize TIMs clock and interrupt */
void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim);
///////////////////////////---FUNCTIONS---///////////////////////////
#endif // __TIM_GENERAL_H_

View File

@@ -1,8 +1,8 @@
/**
**************************************************************************
* @file general_uart.h
* @brief Заголовочный файл для модуля инициализации UART.
*************************************************************************/
**************************************************************************
* @file general_uart.h
* @brief Заголовочный файл для модуля инициализации UART.
*************************************************************************/
#ifndef __UART_GENERAL_H_
#define __UART_GENERAL_H_

View File

@@ -1,34 +1,34 @@
/**
**************************************************************************
* @file mylibs_defs.h
* @brief Заголочный файл для дефайнов библиотеки MyLibsGeneral.
* @file bit_access.h
* @brief Заголочный файл для дефайнов битового доступа.
**************************************************************************
* @defgroup BIT_ACCESS_DEFINES Bit access defines
* @ingroup MYLIBS_DEFINES
* @brief Макросы и typedef'ы для работы с битами в unsigned типах.
* @details
* В этом файле определены макросы для получения значения конкретного бита^
* - @ref uint8_bit
* - @ref uint16_bit
* - @ref uint32_bit
* - @ref uint64_bit
*
* Особенности использования:
* - Индекс бита должен быть **константой на этапе компиляции**.
* Пример верного использования:
* @code
* uint8_t val = 0x05;
* uint8_t b2 = uint8_bit(val, 2); // Получить бит 2
* uint8_bit(val, 6) = 1; // Записать бит 6
* @endcode
* - Нельзя использовать переменные в качестве индекса:
* @code
* uint8_t i = 2;
* uint8_bit(val, i); // Не сработает!
* @endcode
* - Макросы возвращают 0 или 1.
* - Доступ реализован через приведение к `union` с битовыми полями, поэтому это
* безопасный способ работы с отдельными битами без ручного сдвига и маскирования.
В этом файле определены макросы для получения значения конкретного бита^
- @ref uint8_bit
- @ref uint16_bit
- @ref uint32_bit
- @ref uint64_bit
Особенности использования:
- Индекс бита должен быть **константой на этапе компиляции**.
Пример верного использования:
@code
uint8_t val = 0x05;
uint8_t b2 = uint8_bit(val, 2); // Получить бит 2
uint8_bit(val, 6) = 1; // Записать бит 6
@endcode
- Нельзя использовать переменные в качестве индекса:
@code
uint8_t i = 2;
uint8_bit(val, i); // Не сработает!
@endcode
- Макросы возвращают 0 или 1.
- Доступ реализован через приведение к `union` с битовыми полями, поэтому это
безопасный способ работы с отдельными битами без ручного сдвига и маскирования.
* @{
*************************************************************************/
#ifndef __BIT_ACCESS_H_

View File

@@ -1,11 +1,19 @@
/**
**************************************************************************
* @file general_gpio.h
* @brief Заголовочный файл для модуля инициализации портов.
* @brief Заголовочный файл для модуля инициализации портов и работы с ними.
**************************************************************************
* @defgroup MY_LIBS_GPIO GPIO Tools
* @ingroup MYLIBS_PERIPHERAL
* @brief Функции и макросы для удобной работы с GPIO.
* @details
Модуль предоставляет универсальные инструменты для работы с GPIO):
- @ref MYLIBS_GPIO_GENERAL — инициализация и общие функции работы с портами.
- @ref MYLIBS_GPIO_SWITCH — работа с GPIO как с кнопкой: чтение состояния,
фильтрация дребезга, настройка активного уровня.
- @ref MYLIBS_GPIO_LEDS — работа с GPIO как со светодиодом: включение,
выключение, моргание и плавное затухание.
*************************************************************************/
#ifndef __GPIO_GENERAL_H_
#define __GPIO_GENERAL_H_
@@ -14,7 +22,7 @@
/**
* @addtogroup GPIO_INIT Init defines
* @ingroup GPIO_GENERAL
* @ingroup MYLIBS_GPIO_GENERAL
* @brief Настройка состояний кнопок и количества тиков в периоде ШИМ
* @{
*/
@@ -44,7 +52,7 @@
// /**
// * @brief Маппинг альтернативной функции SPI между GPIO
// * @ingroup GPIO_GENERAL
// * @ingroup MYLIBS_GPIO_GENERAL
// */
// #define SPI_Alternate_Mapping(INSTANCE) \
// ((((INSTANCE) == TIM1) || ((INSTANCE) == TIM2))? GPIO_AF1_TIM1: \
@@ -56,9 +64,9 @@
/**
* @brief Маппинг альтернативной функции TIM между GPIO
* @ingroup GPIO_GENERAL
* @ingroup MYLIBS_GPIO_GENERAL
*/
#define TIM_Alternate_Mapping(INSTANCE) \
#define GPIO_TIM_Alternate_Mapping(INSTANCE) \
((((INSTANCE) == TIM1) || ((INSTANCE) == TIM2))? GPIO_AF1_TIM1: \
(((INSTANCE) == TIM3) || ((INSTANCE) == TIM4) || ((INSTANCE) == TIM5))? GPIO_AF2_TIM3: \
(((INSTANCE) == TIM8) || ((INSTANCE) == TIM9) || ((INSTANCE) == TIM10) || ((INSTANCE) == TIM11))? GPIO_AF3_TIM8: \
@@ -68,7 +76,7 @@
/**
* @brief Режимы работы светодиода
* @ingroup GPIO_LEDS
* @ingroup MYLIBS_GPIO_LEDS
*/
typedef enum
{
@@ -80,7 +88,7 @@ typedef enum
/**
* @brief Структура светодиода
* @ingroup GPIO_LEDS
* @ingroup MYLIBS_GPIO_LEDS
*/
typedef struct
{
@@ -92,12 +100,12 @@ typedef struct
uint8_t LED_ActiveLvl; ///< Активный уровень ножки (при котором светодиод горит)
uint32_t LED_Period; ///< Период моргания светодиода
uint32_t tickprev;///< Период моргания светодиода
uint32_t tickprev;
}GPIO_LEDTypeDef;
/**
* @brief Структура кнопки
* @ingroup GPIO_SWITCH
* @ingroup MYLIBS_GPIO_SWITCH
*/
typedef struct
{
@@ -108,14 +116,14 @@ typedef struct
uint32_t Sw_PrevState; ///< Предыдущее состояние кнопки
uint32_t Sw_FilterDelay; ///< Фильтр от дребезга (в мс)
uint32_t tickprev;///< Период моргания светодиода
uint32_t tickprev;
}GPIO_SwitchTypeDef;
/////////////////////////////////////////////////////////////////////
///////////////////////////---FUNCTIONS---///////////////////////////
/**
* @addtogroup GPIO_GENERAL General tools
* @addtogroup MYLIBS_GPIO_GENERAL General tools
* @ingroup MY_LIBS_GPIO
* @brief Общие функции/макросы для работы с GPIO
* @{
@@ -123,12 +131,12 @@ typedef struct
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx);
/** GPIO_GENERAL
/** MYLIBS_GPIO_GENERAL
* @}
*/
/**
* @addtogroup GPIO_SWITCH Switch tools
* @addtogroup MYLIBS_GPIO_SWITCH Switch tools
* @ingroup MY_LIBS_GPIO
* @brief Функции для работы с GPIO, как с кнопкой
* @{
@@ -137,15 +145,15 @@ HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx);
/* Инициализировать кнопку (структуру кнопки) */
HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_On_State);
/* Считать состоянии кнопки запуска */
uint8_t GPIO_Read_Switch(GPIO_SwitchTypeDef *swstart);
int GPIO_Read_Switch(GPIO_SwitchTypeDef *swstart);
/** GPIO_SWITCH
/** MYLIBS_GPIO_SWITCH
* @}
*/
/**
* @addtogroup GPIO_LEDS LED tools
* @addtogroup MYLIBS_GPIO_LEDS LED tools
* @ingroup MY_LIBS_GPIO
* @brief Функции для работы с GPIO, для управления светодиодом
* @{
@@ -154,19 +162,19 @@ uint8_t GPIO_Read_Switch(GPIO_SwitchTypeDef *swstart);
/* Инициализировать светодиод (структуру светодиода) */
HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_On_State);
/* Включить светодиод */
HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led);
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_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period);
HAL_StatusTypeDef GPIO_LED_Blink_Start (GPIO_LEDTypeDef *led, uint32_t period);
/* Активировать моргание светодиодом */
HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period);
/* Управление динамическими режимами свечения светодиода */
void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led);
/** GPIO_LEDS
/** MYLIBS_GPIO_LEDS
* @}
*/
///////////////////////////---FUNCTIONS---///////////////////////////

View File

@@ -0,0 +1,224 @@
/**
**************************************************************************
* @file general_tim.h
* @brief Заголовочный файл для модуля инициализации таймеров и работы с ними.
**************************************************************************
* @defgroup MY_LIBS_TIM TIM Tools
* @ingroup MYLIBS_PERIPHERAL
* @brief Функции и макросы для удобной работы с TIM.
* @details
Модуль предоставляет универсальные инструменты для работы с TIM:
- @ref MYLIBS_TIM_GENERAL — базовая инициализация таймеров и прерываний.
- @ref MYLIBS_TIM_DELAY — функции задержки через таймеры (blocking и non-blocking).
- @ref MYLIBS_TIM_OC — настройка каналов Output Compare и PWM.
- @ref MYLIBS_TIM_ENCODER — работа с энкодерами, чтение положения и кнопки.
* @note Требуется подключение модуля TIM в библиотеке HAL
@code
#define HAL_TIM_MODULE_ENABLED
@endcode
*************************************************************************/
#ifndef __TIM_GENERAL_H_
#define __TIM_GENERAL_H_
/////////////////////////////////////////////////////////////////////
/////////////////////////---USER SETTINGS---/////////////////////////
/**
* @addtogroup TIM_INIT Init defines
* @ingroup MYLIBS_TIM_GENERAL
* @brief Настройка таймеров
* @{
*/
#define HAL_TIM_MODULE_ENABLED
#define USE_TIM1 ///< Включить TIM1 в @ref TIM_Base_MspInit
#define USE_TIM2 ///< Включить TIM2 в @ref TIM_Base_MspInit
#define USE_TIM3 ///< Включить TIM3 в @ref TIM_Base_MspInit
#define USE_TIM4 ///< Включить TIM4 в @ref TIM_Base_MspInit
#define USE_TIM5 ///< Включить TIM5 в @ref TIM_Base_MspInit
#define USE_TIM6 ///< Включить TIM6 в @ref TIM_Base_MspInit
#define USE_TIM7 ///< Включить TIM7 в @ref TIM_Base_MspInit
#define USE_TIM8 ///< Включить TIM8 в @ref TIM_Base_MspInit
#define USE_TIM9 ///< Включить TIM9 в @ref TIM_Base_MspInit
#define USE_TIM10 ///< Включить TIM10 в @ref TIM_Base_MspInit
#define USE_TIM11 ///< Включить TIM11 в @ref TIM_Base_MspInit
#define USE_TIM12 ///< Включить TIM12 в @ref TIM_Base_MspInit
#define USE_TIM13 ///< Включить TIM13 в @ref TIM_Base_MspInit
#define USE_TIM14 ///< Включить TIM14 в @ref TIM_Base_MspInit
/** TIM_INIT
* @}
*/
/////////////////////////---USER SETTINGS---/////////////////////////
#include "mylibs_defs.h"
#include "general_gpio.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
#define TIM_IT_CONF_Pos 0
//#define TIM_PWM_CONF_Pos 1
//#define TIM_CLCK_SRC_CONF_Pos 2
//#define TIM_SLAVE_CONF_Pos 3
//#define TIM_MASTER_CONF_Pos 4
//#define TIM_BDTR_CONF_Pos 5
#define TIM_IT_CONF (1<<(TIM_IT_CONF_Pos))
//#define TIM_PWM_CONF (1<<(TIM_PWM_Pos))
////////////////////////////---DEFINES---////////////////////////////]
/////////////////////////////////////////////////////////////////////
///////////////////////---STRUCTURES & ENUMS---//////////////////////
/**
* @brief Режим прерываний таймера
* @ingroup MYLIBS_TIM_GENERAL
*/
typedef enum
{
TIM_DEFAULT = 0, ///< Прерываний отключены
TIM_IT_MODE = TIM_IT_CONF, ///< Прерываний включены
// TIM_PWM_MODE = TIM_PWM_ENABLE,
// TIM_PWM_IT_MODE = TIM_PWM_ENABLE | TIM_IT_CONF,
}TIM_ITModeTypeDef;
/**
* @brief Длительность тика таймера (частота тактирования таймера)
* @ingroup MYLIBS_TIM_GENERAL
* @details enum дает базовые длительности, но можно выставить другие
* (напр 500 - 0.5 мс)
*/
typedef enum
{
TIM_Base_Disable = 0, ///< Таймер отключен
TIM_TickBase_1US = 1, ///< Таймер тактируется с частотой 1 МГц
TIM_TickBase_10US = 10, ///< Таймер тактируется с частотой 100 кГц
TIM_TickBase_100US = 100, ///< Таймер тактируется с частотой 10 кГц
TIM_TickBase_1MS = 1000, ///< Таймер тактируется с частотой 1 кГц
TIM_TickBase_10MS = 10000, ///< Таймер тактируется с частотой 100 Гц
TIM_TickBase_100MS = 100000, ///< Таймер тактируется с частотой 10 Гц
}TIM_MHzTickBaseTypeDef;
/**
* @brief Структура инициализации таймера
* @ingroup MYLIBS_TIM_GENERAL
* @details
* Содержит все базовые структуры, которые нужны для инициализации таймера.
* Если структуры настроек не заданы, то они заполнятся сами дефолтными параметрами
*
* Также высокоуровневые настройки частоты работы таймера.
* Если какая-либо высокоуровневая настройка не задана, то
* по возможности берется низкоуровневая настройка из структур
*/
typedef struct // struct with settings for custom function
{
TIM_HandleTypeDef htim; ///< HAL handle таймера
TIM_ClockConfigTypeDef sClockSourceConfig; ///< Настройки тактирования таймера
TIM_SlaveConfigTypeDef sSlaveConfig; ///< Настройки слейв режима таймера
TIM_MasterConfigTypeDef sMasterConfig; ///< Настройки мастер режима таймера
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; ///< Настройки дедтаймов таймера
TIM_ITModeTypeDef sTimMode; ///< Настройки прерывания таймера
TIM_MHzTickBaseTypeDef sTickBaseUS; ///< Длительность одного тика
uint8_t sTickBasePrescaler; ///< Дополнительный делитель, для удобного деления @ref sTickBaseUS
float sTimAHBFreqMHz; ///< Частота шины тактирования таймера
float sTimFreqHz; ///< Желаемая частота таймера
}TIM_SettingsTypeDef;
/**
* @brief Структура инициализации енкодера
* @ingroup MYLIBS_TIM_ENCODER
* @details
* Содержит все базовые структуры, которые нужны для инициализации таймера.
* Если структуры настроек не заданы, то они заполнятся сами дефолтными параметрами
*
* Также высокоуровневые настройки частоты работы таймера.
* Если какая-либо высокоуровневая настройка не задана, то
* по возможности берется низкоуровневая настройка из структур
*/
typedef struct // struct with variables for encoder
{
int16_t Encoder_Diff; ///< Считанная разница
uint16_t Encoder_Shdw; ///< Последние считанные тики
TIM_HandleTypeDef *htim; ///< Указатель на HAL handle таймера
TIM_Encoder_InitTypeDef sConfig; ///< Указатель на структуру настройки энкодера
GPIO_TypeDef *GPIOx; ///< Порт, куда подключается энкодер
uint32_t GPIO_PIN_TI1; ///< Пин, куда подключается канал TI1
uint32_t GPIO_PIN_TI2; ///< Пин, куда подключается канал TI2
uint32_t GPIO_PIN_SW; ///< Пин, куда кнопка энкодера (если есть)
GPIO_SwitchTypeDef Sw; ///< Структура кнопки
}TIM_EncoderTypeDef;
///////////////////////---STRUCTURES & ENUMS---//////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////////---FUNCTIONS---///////////////////////////
/**
* @addtogroup MYLIBS_TIM_OC PWM/OC Channels tools
* @ingroup MY_LIBS_TIM
* @brief Функции для инициализации базовых функций каналов таймера
* @{
*/
/* Initialize PWM Channel and GPIO for output */
HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t PWM_PIN);
/* Initialize OC Comparator */
HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL);
/** MYLIBS_TIM_ENCODER
* @}
*/
/**
* @addtogroup MYLIBS_TIM_ENCODER Encoder tools
* @ingroup MY_LIBS_TIM
* @brief Функции для считывания энкодера
* @{
*/
/* Initialize TIM Encoder functional */
HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc1, TIM_HandleTypeDef *htim);
/* Считать энкодер */
HAL_StatusTypeDef TIM_Encoder_Read(TIM_EncoderTypeDef *henc);
/* Считать кнопку энкодера */
int TIM_Encoder_ReadSwitch(TIM_EncoderTypeDef *henc);
/** MYLIBS_TIM_ENCODER
* @}
*/
/**
* @addtogroup MYLIBS_TIM_DELAY Delay tools
* @ingroup MY_LIBS_TIM
* @brief Функции для формирования задержек с помощью таймеров
* @{
*/
/* Start delay via TIM */
HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim);
/* Delay via TIM */
HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay);
/* Wait Delay via TIM without blocking app */
HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay);
/** MYLIBS_TIM_DELAY
* @}
*/
/**
* @addtogroup MYLIBS_TIM_GENERAL General tools
* @ingroup MY_LIBS_TIM
* @brief Функции для базовой инициализации таймеров
* @{
*/
/* Initialize TIM with TIM_SettingsTypeDef structure */
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef* stim);
/* Initialize TIMs clock and interrupt */
void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode);
/* DeInitialize TIMs clock and interrupt */
void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim);
/** MYLIBS_TIM_GENERAL
* @}
*/
///////////////////////////---FUNCTIONS---///////////////////////////
#endif // __TIM_GENERAL_H_

View File

@@ -6,7 +6,7 @@
* @defgroup MYLIBS_CONFIG Configs
* @ingroup MYLIBS_ALL
* @brief Конфигурации для библиотек MyLibs
@{
* @{
*************************************************************************/
#ifndef __MYLIBS_CONFIG_H_
#define __MYLIBS_CONFIG_H_
@@ -14,10 +14,6 @@
#include "stm32f4xx_hal.h"
// user includes
#include "mzkt_config.h"
#include "mzkt_trace_config.h"
#include "interface_config.h"
/**
* @addtogroup TRACE_CONFIG Trace configs
@@ -62,7 +58,7 @@
/**
* @addtogroup LIBS_CONFIG Libraries configs
* @ingroup MYLIBS_CONFIG
* @brief Включенные трекеры и трассировки в МЗКТЭ
* @brief Подключение различных модулей библиотеки
* @{
*/

View File

@@ -34,16 +34,20 @@ extern void Error_Handler(void);
#define MyLibs_Error_Handler(...)
#endif // MyLibs_Error_Handler
/** @brief Проверить указатель на NULL */
#define check_null_ptr_1(_p1_) (_p1_ == NULL)
/** @brief Проверить один указатель на NULL */
#define check_null_ptr_1(p1) (p1 == NULL)
/** @brief Проверить два указателя на NULL */
#define check_null_ptr_2(_p1_, _p2_) ((_p1_ == NULL) || (_p2_ == NULL))
#define check_null_ptr_2(p1, p2) ((p1 == NULL) || (p1 != NULL && p2 == NULL))
/** @brief Проверить три указателя на NULL */
#define check_null_ptr_3(_p1_, _p2_, _p3_) ((_p1_ == NULL) || (_p2_ == NULL) || (_p3_ == NULL))
#define check_null_ptr_3(p1, p2, p3) ((p1 == NULL) || (p1 != NULL && ((p2 == NULL) || (p2 != NULL && p3 == NULL))))
/** @brief Проверить четыре указателя на NULL */
#define check_null_ptr_4(_p1_, _p2_, _p3_, _p4_) ((_p1_ == NULL) || (_p2_ == NULL) || (_p3_ == NULL) || (_p4_ == NULL))
#define check_null_ptr_4(p1, p2, p3, p4) ((p1 == NULL) || (p1 != NULL && ((p2 == NULL) || (p2 != NULL && ((p3 == NULL) || (p3 != NULL && p4 == NULL))))))
/** @brief Проверить пять указателей на NULL */
#define check_null_ptr_5(_p1_, _p2_, _p3_, _p4_, _p5_) ((_p1_ == NULL) || (_p2_ == NULL) || (_p3_ == NULL) || (_p4_ == NULL) || (_p5_ == NULL))
#define check_null_ptr_5(p1, p2, p3, p4, p5) ((p1 == NULL) || (p1 != NULL && ((p2 == NULL) || (p2 != NULL && ((p3 == NULL) || (p3 != NULL && ((p4 == NULL) || (p4 != NULL && p5 == NULL))))))))
/** ERROR_HANDLER_DEFINES
* @}

View File

@@ -3,12 +3,19 @@
* @file mylibs_include.h
* @brief Заголочный файл для всех библиотек
**************************************************************************
@details
* @details
Здесь нужно собрать библиотеки и дефайны, которые должны быть видны во всем проекте,
чтобы не подключать 100 инклюдов в каждом ".c" файле
**************************************************************************
* @defgroup MYLIBS_ALL My Libs
* @brief Все используемые MyLibs библиотеки
* @details
Для подключения библиотеки необходимо:
- Сконфигурировать mylibs_config.h:
- Подключить заголовочный файл HAL библиотеки конкретного МК (напр. stm32f4xx_hal.h)
- Подключить другие заголовочные файлы которые общие для всего проекта и должны быть видны
-
- Подключить mylibs_include.h туда, где необходим доступ к библиотекам.
* @defgroup MYLIBS_PERIPHERAL Peripheral
* @ingroup MYLIBS_ALL
@@ -68,3 +75,110 @@
#endif // __MYLIBS_INCLUDE_H_
/**
@mainpage
@section overview Обзор
MyLibs - это набор библиотек для удобной работы с периферией микроконтроллеров STM32.
@subsection features Основные возможности
@subsubsection utils_module Общие утилиты @ref MYLIBS_DEFINES
- Битовый доступ к регистрам через union
- Трекеры для статистики и отладки
- Макросы для задержек и утилит
- Поддержка FreeRTOS
@subsubsection trace_module Трассировка @ref TRACE
- Serial трассировка через SWO и RTT
- GPIO трассировка для отладки
- Сохранение логов в Flash память
- Обработка HardFault с сохранением контекста
@subsubsection gpio_module Модуль GPIO @ref MY_LIBS_GPIO
- Управление светодиодами (включение/выключение, моргание, плавное затухание)
- Работа с кнопками (чтение состояния, фильтрация дребезга)
- Инициализация портов и тактирования
- Поддержка альтернативных функций
@subsubsection tim_module Модуль таймеров @ref MY_LIBS_TIM
- Базовая инициализация таймеров
- Режимы прерываний
- Формирование задержек (блокирующие и неблокирующие)
- Работа с энкодерами (чтение положения, обработка кнопок)
- Настройка ШИМ и Output Compare
@subsection structure Структура проекта
@code
├── inc/ # Заголовочные файлы
│ ├── mylibs_include.h # Главный include файл
│ ├── mylibs_config.h # Конфигурация библиотек
│ ├── mylibs_defs.h # Общие определения и макросы
│ ├── bit_access.h # Битовый доступ к регистрам
│ ├── trackers.h # Трекеры для отладки
│ ├── trace.h # Трассировка и логирование
│ ├── general_gpio.h # Работа с GPIO
│ └── general_tim.h # Работа с таймерами
└── src/ # Исходные файлы
├── general_gpio.c # Реализация GPIO
└── general_tim.c # Реализация TIM
@endcode
@subsection usage_basic Использование
Инструкция по подключению:
1. Настройте конфигурацию @ref MYLIBS_CONFIG в @ref mylibs_config.h
2. Подключите главный заголовочный файл:
@code
#include "mylibs_include.h"
@endcode
3. Используйте нужные модули в своем коде
@subsubsection gpio_example Пример работы с GPIO
@code
// Инициализация светодиода
MX_GPIO_Init();
GPIO_LEDTypeDef led;
GPIO_LED_Init(&led, GPIOA, GPIO_PIN_5, 1);
// Включение светодиода
GPIO_LED_On(&led);
// Запуск моргания
GPIO_LED_Blink_Start(&led, 500); // Период 500 мс
// В основном цикле
while (1) {
GPIO_LED_Dynamic_Handle(&led);
}
@endcode
@subsubsection tim_example Пример работы с таймером
@code
// Настройка таймера
TIM_SettingsTypeDef tim_settings = {0};
tim_settings.htim.Instance = TIM2;
tim_settings.sTimAHBFreqMHz = SystemCoreClock;
tim_settings.sTickBaseUS = TIM_TickBase_1MS;
tim_settings.sTimFreqHz = 1000; // 1 кГц
tim_settings.sTimMode = TIM_IT_CONF;
TIM_Base_Init(&tim_settings);
HAL_TIM_Base_Start(&tim_settings.htim);
@endcode
@subsection dependencies Зависимости
- HAL библиотека STM32
- SEGGER RTT (опционально, для RTT трассировки)
- FreeRTOS (опционально, для FreeRTOS задержек)
*/

View File

@@ -41,8 +41,6 @@
- Если трассировка @ref SERIAL_TRACE_ENABLE отключена, то все дефайны определяются как 'ничего'
и на производительность кода не влияют
Если трассировка отключена, все макросы пустые и не влияют на производительность
* @{
*
* @def my_printf(...)
@@ -386,10 +384,10 @@ __STATIC_FORCEINLINE int RTT_EraseFlash(void)
*/
#else // HAL_MODULE_ENABLED && RTT_TRACE_ENABLE
#define RTT_FlashPrepare()
#define RTT_EraseFlash() 0
#define RTT_SaveToFlash() 0
#define RTT_ReadFromFlash() 0
#define RTT_FlashPrepare(...)
#define RTT_EraseFlash(...) 0
#define RTT_SaveToFlash(...) 0
#define RTT_ReadFromFlash(...) 0
#endif // HAL_MODULE_ENABLED && RTT_TRACE_ENABLE
@@ -546,8 +544,8 @@ __STATIC_FORCEINLINE void HF_HandleFault(void)
RTT_SaveToFlash(HF_RTT_TAG_BASE, HF_RTT_TAIL_SIZE);
}
#else // HAL_MODULE_ENABLED && HARDFAULT_SERIAL_TRACE
#define HF_CheckRecovered() 0
#define HF_HandleFault()
#define HF_CheckRecovered(...) 0
#define HF_HandleFault(...)
#endif // HAL_MODULE_ENABLED && HARDFAULT_SERIAL_TRACE
/** TRACE_HARDFAULT
* @}

View File

@@ -6,49 +6,50 @@
* @addtogroup TRACKERS Trackers defines
* @ingroup MYLIBS_DEFINES
* @brief Дефайны для работы с трекерами
* @details Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars).
Структура состоит из следующих элементов:
- cnt_ok
- cnt_err
- cnt_warn
- user[num_user_vars]
Также есть ряд функций (дефайнов) для обращения к элементам этой структуры.
Если трекеры @ref TRACKERS_ENABLE отключены, то все дефайны определяются как ничего
и на производительность кода не влияют
@par Пример:
Определяем typedef трекера измерений Measure_TrackerTypeDef
* @details
Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars).
Структура состоит из следующих элементов:
- cnt_ok
- cnt_err
- cnt_warn
- user[num_user_vars]
Также есть ряд функций (дефайнов) для обращения к элементам этой структуры.
@verbatim
typedef TrackerTypeDef(MEASURE_USER_VARS_NUMB) Measure_TrackerTypeDef;
@endverbatim
И через @ref Measure_TrackerTypeDef структура подключается в другие структуры
Если трекеры @ref TRACKERS_ENABLE отключены, то все дефайны определяются как ничего
и на производительность кода не влияют
@par Пример:
Определяем typedef трекера измерений Measure_TrackerTypeDef
@verbatim
typedef TrackerTypeDef(MEASURE_USER_VARS_NUMB) Measure_TrackerTypeDef;
@endverbatim
И через @ref Measure_TrackerTypeDef структура подключается в другие структуры
Для работы с структурой можно использовать функции:
- Для получения значения:
- TrackerGet_Ok()
- TrackerGet_Err()
- TrackerGet_Warn()
- TrackerGet_User(n)
Для работы с структурой можно использовать функции:
- Для получения значения:
- TrackerGet_Ok()
- TrackerGet_Err()
- TrackerGet_Warn()
- TrackerGet_User(n)
- Для записи значения:
- TrackerCnt_Ok()
- TrackerCnt_Err()
- TrackerCnt_Warn()
- TrackerCnt_User()
- TrackerWrite_User(n)
- Для очищения значения:
- TrackerClear_All()
- TrackerClear_Ok()
- TrackerClear_Err()
- TrackerClear_Warn()
- TrackerClear_User(n)
- TrackerClear_UserAll()
- Для записи значения:
- TrackerCnt_Ok()
- TrackerCnt_Err()
- TrackerCnt_Warn()
- TrackerCnt_User()
- TrackerWrite_User(n)
- Для очищения значения:
- TrackerClear_All()
- TrackerClear_Ok()
- TrackerClear_Err()
- TrackerClear_Warn()
- TrackerClear_User(n)
- TrackerClear_UserAll()
* @{
*************************************************************************/
#ifndef __TRACKERS_H_

View File

@@ -1,20 +1,20 @@
/**
**************************************************************************
* @file general_spi.c
* @brief Модуль для инициализации SPI.
**************************************************************************
* //-------------------Функции-------------------//
* @verbatim
* Functions: users
* - SPI_Base_Init Инициализация SPI
*
* Functions: spi initialize
* - SPI_GPIO_Init Инициализация GPIO для SPI
* - SPI_DMA_Init Инициализация DMA для SPI
* - SPI_MspInit Аналог HAL_MspInit для SPI
* - SPI_MspDeInit Аналог HAL_MspDeInit для SPI
* @endverbatim
*************************************************************************/
**************************************************************************
* @file general_spi.c
* @brief Модуль для инициализации SPI.
**************************************************************************
* @details
*
* Функции:
* - SPI_Base_Init Инициализация SPI
*
* Functions: spi initialize
* - SPI_GPIO_Init Инициализация GPIO для SPI
* - SPI_DMA_Init Инициализация DMA для SPI
* - SPI_MspInit Аналог HAL_MspInit для SPI
* - SPI_MspDeInit Аналог HAL_MspDeInit для SPI
*
*************************************************************************/
#include "general_spi.h"
#include "general_gpio.h"

View File

@@ -1,13 +1,14 @@
/**
**************************************************************************
* @file general_gpio.c
* @brief Модуль для инициализации портов.
* @brief Модуль для инициализации портов и работы с ними.
**************************************************************************
* @details Реализация функций для работы с GPIO:
* - Включение тактирования портов
* - Инициализация светодиодов и кнопок
* - Управление светодиодами: включение, выключение, моргание, плавное затухание
* - Чтение состояния кнопок с фильтром от дребезга
* @details
Реализация функций для работы с GPIO:
- Включение тактирования портов
- Инициализация светодиодов и кнопок
- Управление светодиодами: включение, выключение, моргание, плавное затухание
- Чтение состояния кнопок с фильтром от дребезга
***************************************************************************/
#include "general_gpio.h"
@@ -20,6 +21,9 @@
*/
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
{
if(check_null_ptr_1(GPIOx))
return HAL_ERROR;
HAL_StatusTypeDef status = HAL_OK;
// choose port for enable clock
if (GPIOx==GPIOA)
@@ -68,7 +72,7 @@ HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
*/
HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_ActiveLevel)
{
if(check_null_ptr_2(led, GPIOx))
if(check_null_ptr_3(led, GPIOx, GPIO_PIN_X))
return HAL_ERROR;
led->LED_Port = GPIOx;
@@ -86,14 +90,12 @@ HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint3
*/
HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led)
{
if(check_null_ptr_1(led))
return HAL_ERROR;
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return HAL_ERROR;
led->state = LED_IS_ON;
if(led->LED_Port != NULL)
HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
else
return HAL_ERROR;
HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
return HAL_OK;
}
@@ -104,14 +106,12 @@ HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led)
*/
HAL_StatusTypeDef GPIO_LED_Off(GPIO_LEDTypeDef *led)
{
if(check_null_ptr_1(led))
return HAL_ERROR;
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return HAL_ERROR;
led->state = LED_IS_OFF;
if(led->LED_Port != NULL)
HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
else
return HAL_ERROR;
HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
return HAL_OK;
@@ -124,8 +124,8 @@ HAL_StatusTypeDef GPIO_LED_Off(GPIO_LEDTypeDef *led)
*/
HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state)
{
if(check_null_ptr_1(led))
return HAL_ERROR;
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return HAL_ERROR;
if(led_state)
{
@@ -145,7 +145,7 @@ HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state)
*/
HAL_StatusTypeDef GPIO_LED_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period)
{
if(check_null_ptr_2(led, led->LED_Port))
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return HAL_ERROR;
led->state = LED_IS_BLINKING;
@@ -163,7 +163,7 @@ HAL_StatusTypeDef GPIO_LED_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period)
*/
HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period)
{
if(check_null_ptr_2(led, led->LED_Port))
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return HAL_ERROR;
led->state = LED_IS_FADING;
@@ -183,7 +183,7 @@ HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period)
*/
void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led)
{
if(check_null_ptr_2(led, led->LED_Port))
if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
return;
/* Режим моргания светодиода */
@@ -257,7 +257,7 @@ void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led)
*/
HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_ActiveLevel)
{
if(check_null_ptr_2(sw, GPIOx))
if(check_null_ptr_3(sw, GPIOx, GPIO_PIN_X))
return HAL_ERROR;
sw->Sw_Port = GPIOx;
@@ -269,14 +269,16 @@ HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx,
/**
* @brief Считать состоянии кнопки
* @param sw Указатель на структуру кнопки
* @return 1 - если кнопка нажата, 0 - если отжата
* @return 1 - если кнопка нажата,
* 0 - если отжата,
* -1 - если ошибка
* @details Функция включает в себя неблокирующую проверку на дребезг
* Т.е. функцию надо вызывать постоянно, чтобы она мониторила состояние кнопки
*/
uint8_t GPIO_Read_Switch(GPIO_SwitchTypeDef *sw)
int GPIO_Read_Switch(GPIO_SwitchTypeDef *sw)
{
if(check_null_ptr_1(sw))
return 0;
if(check_null_ptr_3(sw, sw->Sw_Port, sw->Sw_Pin))
return -1;
if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
{

View File

@@ -1,39 +1,40 @@
/**
**************************************************************************
* @file general_tim.c
* @brief Модуль для инициализации таймеров.
**************************************************************************
@verbatim
//-------------------Функции-------------------//
Functions: user init
- TIM_Base_Init Инициализация TIM
- TIM_Encoder_Init Инициализация режима энкодера
- TIM_Output_PWM_Init Инициализация PWM с выводом на GPIO
- TIM_OC_Comparator_Init Инициализация TIM как компаратора
Functions: user
- TIM_Delay Задержка с помощью TIM
Functions: tim initialize
- TIM_Base_MspInit Аналог HAL_MspInit для таймера
- TIM_Base_MspDeInit Аналог HAL_MspDeInit для таймера
@endverbatim
*************************************************************************/
**************************************************************************
* @file general_tim.c
* @brief Модуль для инициализации таймеров и работы с ними.
**************************************************************************
Реализация функций для работы с TIM:
- Инициализация таймера и его каналов
- Формирование задержек через таймеры
- Считывание энкодера
*************************************************************************/
#include "general_tim.h"
#include "general_gpio.h"
//-------------------------------------------------------------------
//-------------------------TIM INIT FUNCTIONS------------------------
/**
* @brief Initialize TIM with TIM_SettingsTypeDef structure.
* @param stim - указатель на структуру с настройками таймера.
* @brief Инициализация таймера.
* @param stim Указатель на структуру с настройками таймера.
* @return HAL status.
* @note Данная структура содержит хендл таймера и структуры для его настройки.
* @details
* Инициализирует таймер исходя из настроек верхнего уровня:
* - Длительность одного тика @ref TIM_MHzTickBaseTypeDef
* - Частота таймера (в Гц, float)
* - Частота тактирования таймера от шины (в Гц, float)
*
* При невозможности выставления частоты при заданой длительности тика
* длительность тика увеличивается до тех пор, пока частота не будет достигнута.
*
* При выставлении дефайна @ref UPDATE_TIM_PARAMS_AFTER_INITIALIZATION
* новая длительность тика записывается в структуру.
*
* Также остается возможность низкоуровневой настройки по структурам @ref TIM_SettingsTypeDef.
* Для этого надо высокоуровневые настройки приравнять к нулю
*/
HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef *stim)
{ // function takes structure for init
// check that htim is defined
if (stim->htim.Instance == NULL)
if(check_null_ptr_2(stim, stim->htim.Instance))
return HAL_ERROR;
@@ -158,17 +159,19 @@ HAL_StatusTypeDef TIM_Base_Init(TIM_SettingsTypeDef *stim)
/**
* @brief Initialize TIM Encoder functional.
* @param htim - указатель на хендл таймера.
* @param sConfigOC - указатель на настрйоки канала таймера.
* @param GPIOx - порт для приема енкодера.
* @param GPIO_PIN1 - первый пин для енкодера.
* @param GPIO_PIN2 - второй пин для енкодера.
* @param GPIO_PIN_SW - пин для кнопки енкодера.
* @brief Инициализация режима энкодер у таймера.
* @param henc Указатель на хендл энкодера.
* @param htim Указатель на хендл таймера.
* @return HAL status.
* @note Предварительно надо инициализировать таймер @ref TIM_Base_Init.
*/
HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc, TIM_HandleTypeDef *htim)
{
if(check_null_ptr_3(henc, htim, htim->Instance))
return HAL_ERROR;
if(check_null_ptr_3(henc->GPIOx, henc->GPIO_PIN_TI1, henc->GPIO_PIN_TI2))
return HAL_ERROR;
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_StatusTypeDef RES = HAL_ERROR;
henc->htim = htim;
@@ -192,7 +195,7 @@ HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc, TIM_HandleTypeDef *
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = TIM_Alternate_Mapping(henc->htim->Instance);
GPIO_InitStruct.Alternate = GPIO_TIM_Alternate_Mapping(henc->htim->Instance);
if(GPIO_InitStruct.Alternate)
HAL_GPIO_Init(henc->GPIOx, &GPIO_InitStruct);
@@ -202,23 +205,31 @@ HAL_StatusTypeDef TIM_Encoder_Init(TIM_EncoderTypeDef *henc, TIM_HandleTypeDef *
GPIO_InitStruct.Pin = henc->GPIO_PIN_SW;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(henc->GPIOx, &GPIO_InitStruct);
GPIO_Switch_Init(&henc->Sw, henc->GPIOx, henc->GPIO_PIN_SW, 0);
}
return HAL_OK;
}
/**
* @brief Initialize PWM Channel and GPIO for output.
* @param htim - указатель на хендл таймера.
* @param sConfigOC - указатель на настрйоки канала таймера.
* @param TIM_CHANNEL - канал таймера для настройки.
* @param GPIOx - порт для вывода ШИМ.
* @param GPIO_PIN - пин для вывода ШИМ.
* @brief Инициализация выхода ШИМ таймера.
* @param htim Указатель на хендл таймера.
* @param sConfigOC Указатель на настрйоки канала таймера.
* @param TIM_CHANNEL Канал таймера для настройки.
* @param GPIOx Порт для вывода ШИМ.
* @param GPIO_PIN Пин для вывода ШИМ.
* @return HAL status.
* @note Предварительно надо инициализировать таймер @ref TIM_Base_Init.
*/
HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfigOC, uint32_t TIM_CHANNEL, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN)
{
if(check_null_ptr_3(htim, htim->Instance, sConfigOC))
return HAL_ERROR;
if(check_null_ptr_2(GPIOx, GPIO_PIN))
return HAL_ERROR;
GPIO_InitTypeDef GPIO_InitStruct = {0};
HAL_StatusTypeDef RES = HAL_ERROR;
@@ -244,7 +255,7 @@ HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDe
else
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = TIM_Alternate_Mapping(htim->Instance);
GPIO_InitStruct.Alternate = GPIO_TIM_Alternate_Mapping(htim->Instance);
if(GPIO_InitStruct.Alternate)
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
@@ -252,13 +263,17 @@ HAL_StatusTypeDef TIM_Output_PWM_Init(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDe
}
/**
* @brief Initialize OC Comparator.
* @param htim - указатель на хендл таймера.
* @param TIM_CHANNEL - канал таймера для настройки.
* @brief Инициализация OC компаратора таймера.
* @param htim Указатель на хендл таймера.
* @param TIM_CHANNEL Канал таймера для настройки.
* @return HAL status.
* @note Предварительно надо инициализировать таймер @ref TIM_Base_Init.
*/
HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_CHANNEL)
{
if(check_null_ptr_2(htim, htim->Instance))
return HAL_ERROR;
TIM_OC_InitTypeDef sConfigOC = {0};
HAL_StatusTypeDef RES = HAL_ERROR;
@@ -276,18 +291,54 @@ HAL_StatusTypeDef TIM_OC_Comparator_Init(TIM_HandleTypeDef *htim, uint32_t TIM_C
}
//-------------------------------------------------------------------
//-------------------------TIM USER FUNCTIONS------------------------
/**
* @brief Delay via TIM.
* @param htim - указатель на хендл таймера.
* @param delay - задержка в тиках таймера.
* @brief Считать энкодер.
* @param henc Указатель на хендл энкодера.
* @return HAL status.
* @note Таймер должен быть уже запущен.
* @details Читает разницу энкодера, которую он накопил после
* предыдущего вызова этой функции.
*/
HAL_StatusTypeDef TIM_Encoder_Read(TIM_EncoderTypeDef *henc)
{
if(check_null_ptr_3(henc, henc->htim, henc->htim->Instance))
return HAL_ERROR;
uint16_t cnt_now = (uint16_t)henc->htim->Instance->CNT;
int16_t diff = (int16_t)(cnt_now - henc->Encoder_Shdw); // переполнение корректно обрабатывается
henc->Encoder_Diff = diff;
henc->Encoder_Shdw = cnt_now;
return HAL_OK;
}
/**
* @brief Считать кнопку энкодера.
* @param henc Указатель на хендл энкодера.
* @return 1 - если кнопка нажата,
* 0 - если отжата,
* -1 - если ошибка
*/
int TIM_Encoder_ReadSwitch(TIM_EncoderTypeDef *henc)
{
if(check_null_ptr_1(henc))
return -1;
return GPIO_Read_Switch(&henc->Sw);
}
/**
* @brief Задержка в тиках таймера (блокирующая).
* @param htim Указатель на хендл таймера.
* @param delay Задержка в тиках таймера.
* @return HAL status.
* @details Формирует задержку с блокировкой программы.
*/
HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay)
{
if(check_null_ptr_2(htim, htim->Instance))
return HAL_ERROR;
if(delay >= htim->Instance->ARR)
{
return HAL_ERROR;
@@ -303,28 +354,36 @@ HAL_StatusTypeDef TIM_Delay(TIM_HandleTypeDef *htim, uint16_t delay)
}
/**
* @brief Start delay via TIM.
* @param htim - указатель на хендл таймера.
* @brief Начать отсчет неблокирующей задержки.
* @param htim Указатель на хендл таймера.
* @return HAL status.
* @note Таймер должен быть уже запущен.
* @details Сбрасывает счетчик для начала отсчета неблокирующей задержки.
* @ref TIM_Delay_NonBlocking для проверки статуса задержки
*/
HAL_StatusTypeDef TIM_Delay_Start(TIM_HandleTypeDef *htim)
{
if(check_null_ptr_2(htim, htim->Instance))
return HAL_ERROR;
htim->Instance->CNT = 0;
return HAL_OK;
}
/**
* @brief Wait Delay via TIM without blocking app.
* @param htim - указатель на хендл таймера.
* @param delay - задержка в тиках таймера.
* @brief Задержка в тиках таймера (неблокирующая).
* @param htim Указатель на хендл таймера.
* @param delay Задержка в тиках таймера.
* @return HAL status.
* @note Перед ожиданием задержки надо запутстить таймер её @ref TIM_Delay_Start
* @note Таймер не должен использоваться на время этой задержки
* @details Формирует задержку с блокировкой программы.
* Перед ожиданием задержки надо запутстить таймер @ref TIM_Delay_Start
* @note Таймер не должен использоваться на время этой задержки
*/
HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay)
{
if(check_null_ptr_2(htim, htim->Instance))
return HAL_ERROR;
if(delay >= htim->Instance->ARR)
{
return HAL_ERROR;
@@ -341,13 +400,16 @@ HAL_StatusTypeDef TIM_Delay_NonBlocking(TIM_HandleTypeDef *htim, uint16_t delay)
}
/**
* @brief Initialize TIMs clock and interrupt.
* @param htim - указатель на хендл таймера.
* @brief Инициализация CLK и NVIC таймеров.
* @param htim Указатель на хендл таймера.
* @note Чтобы не генерировать функцию с иницилизацией неиспользуемых таймеров,
дефайнами в general_tim.h определяются используемые таймеры.
*/
void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode)
{
if(check_null_ptr_2(htim, htim->Instance))
return;
it_mode = it_mode&TIM_IT_CONF;
#ifdef USE_TIM1
if(htim->Instance==TIM1)
@@ -547,13 +609,16 @@ void TIM_Base_MspInit(TIM_HandleTypeDef* htim, TIM_ITModeTypeDef it_mode)
#endif
}
/**
* @brief DeInitialize TIMs clock and interrupt.
* @param htim - указатель на хендл таймера.
* @brief Деинициализация CLK и NVIC таймеров.
* @param htim Указатель на хендл таймера.
* @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых таймеров,
дефайнами в general_tim.h определяются используемые таймеры.
*/
void TIM_Base_MspDeInit(TIM_HandleTypeDef* htim)
{
if(check_null_ptr_2(htim, htim->Instance))
return;
#ifdef USE_TIM1
if(htim->Instance==TIM1)
{