Compare commits

...

26 Commits

Author SHA1 Message Date
a81cb98e88 итог? 2025-06-09 22:46:38 +03:00
6da9b2e05a исправлена цель исследования
исправлена структурная схема
2025-06-09 20:20:18 +03:00
cc0ecad790 проверка findjobj для внешней консоли 2025-06-09 10:48:38 +03:00
8b7ea8cc24 сделаны относительные пути 2025-06-09 10:40:15 +03:00
879e0a4f48 начата работа над графическим интерфейсом оболочки 2025-06-09 10:15:19 +03:00
3ddfacefa6 обновлен матлаб 2025-06-07 18:38:39 +03:00
21f11324c4 +проверка на реал мк (шим как с компаратора на tim1)
вторая посылка ляшенко

добавлен файл с схемами draw.io
2025-06-07 18:37:06 +03:00
334c1f74ba Добавлены госы 2025-06-02 08:22:25 +03:00
e42a60816a Обновить readme.md 2025-06-01 19:36:05 +03:00
dcee38c6bc Обновить readme.md 2025-06-01 12:51:56 +03:00
f45ebd1fd4 ADD ГОСЫ 2025-05-31 21:40:55 +03:00
668699f04f Основное сделано: картинки пронумерованы, список литры сделан, приложения тоже
Сделаны 2 праткики для ЛК
2025-05-25 16:48:56 +03:00
8bc67478c9 Удален zero_cross по АЦП 2025-05-25 16:48:19 +03:00
ef58fe8b7b ну типа... базово готово наверное
осталось титульники и всякое такое
2025-05-19 08:52:33 +03:00
010e165fbf ну предварительно осталось только сделать первую главу про ад 2025-05-18 21:26:46 +03:00
3e8889feb9 добавлена модель симулинк 2021 2025-05-18 18:05:41 +03:00
6de80ee36f Диплом разделен на ворд с пч и без пч
Пока делаю без пч - добавлены фрагменты кода и более подробное описание оболочки
2025-05-17 14:29:23 +03:00
95a022d6c1 Добавлены комменты 2025-05-17 14:28:50 +03:00
416260c9e1 еще диплом текст 2025-05-16 15:26:36 +03:00
d00c7a111c Диплом текст 2025-05-16 13:48:03 +03:00
4b0f6db86b Добавлен ForceDisconnect 2025-05-16 13:47:41 +03:00
30adaef420 Апдейт матлаб+диплом 2025-05-16 08:07:56 +03:00
1044182d0f Структурирована литра 2025-05-16 08:06:54 +03:00
69b343aea2 диплом 2 главы (гптшка) 2025-05-15 08:32:34 +03:00
4edb1d5350 добавлена и структурирована всякая литра, но надо еще доделать 2025-05-15 08:32:10 +03:00
942cb12948 КУЧА ВСЕГО
добавлены параметры работы упп (частота сети, максимальный и минимальный угол открытия тиристора, длительность плавного пуска)
добавлены всякие режимы по флагам (отключение, остановка, подготовка, го)
добавлен флаг для безопасным управлением упп (GoSafe)
добавлен режим торможения
параметры угла (angleInit) унифицированы для всех фаз
2025-05-10 22:11:39 +03:00
109 changed files with 12096 additions and 342 deletions

Binary file not shown.

BIN
beta/Диплом_out.docx Normal file

Binary file not shown.

@ -1 +1 @@
Subproject commit 08719ffc055e27b3b22a9c37742add86ece43ea4
Subproject commit 59b4f9cffc026fca1f1a1b7670a5031b8fa228af

File diff suppressed because one or more lines are too long

View File

@ -55,6 +55,9 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void EXTI0_IRQHandler(void);
void EXTI1_IRQHandler(void);
void EXTI2_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

View File

@ -32,14 +32,19 @@ extern "C" {
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM1_Init(void);
void MX_TIM2_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */

View File

@ -42,10 +42,59 @@
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PA5 PA6 PA7 */
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB0 PB1 PB2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PB12 PB13 PB14 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
}

View File

@ -18,7 +18,7 @@
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
//#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
@ -89,11 +89,15 @@ int main(void)
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
//MX_ADC1_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
//MX_USART1_UART_Init();
//MX_TIM1_Init();
/* USER CODE BEGIN 2 */
upp_init();
//HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
//Upp.Duration = 8;
//Upp.sine_freq = 50;
/* USER CODE END 2 */
/* Infinite loop */
@ -114,48 +118,49 @@ int main(void)
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
//RCC_OscInitTypeDef RCC_OscInitStruct = {0};
//RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
//RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
///** Initializes the RCC Oscillators according to the specified parameters
//* in the RCC_OscInitTypeDef structure.
//*/
//RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
//RCC_OscInitStruct.HSEState = RCC_HSE_ON;
//RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
//RCC_OscInitStruct.HSIState = RCC_HSI_ON;
//RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
//RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
//RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
//if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
//{
// Error_Handler();
//}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
///** Initializes the CPU, AHB and APB buses clocks
//*/
//RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
// |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
//RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
//RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
//RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
//RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
//if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
//{
// Error_Handler();
//}
//PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
//PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
//if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
//{
// Error_Handler();
//}
}
/* USER CODE BEGIN 4 */
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {}
/* USER CODE END 4 */
/**

View File

@ -22,6 +22,7 @@
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "upp.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -198,6 +199,48 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/**
* @brief This function handles EXTI line0 interrupt.
*/
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
zero_cross_update_EXTI(&phase_A.zc_detector);
/* USER CODE END EXTI0_IRQn 1 */
}
/**
* @brief This function handles EXTI line1 interrupt.
*/
void EXTI1_IRQHandler(void)
{
/* USER CODE BEGIN EXTI1_IRQn 0 */
/* USER CODE END EXTI1_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
/* USER CODE BEGIN EXTI1_IRQn 1 */
zero_cross_update_EXTI(&phase_B.zc_detector);
/* USER CODE END EXTI1_IRQn 1 */
}
/**
* @brief This function handles EXTI line2 interrupt.
*/
void EXTI2_IRQHandler(void)
{
/* USER CODE BEGIN EXTI2_IRQn 0 */
/* USER CODE END EXTI2_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
/* USER CODE BEGIN EXTI2_IRQn 1 */
zero_cross_update_EXTI(&phase_C.zc_detector);
/* USER CODE END EXTI2_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@ -24,8 +24,79 @@
/* USER CODE END 0 */
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
/* TIM1 init function */
void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 72-1;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 20000;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 10000;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
}
/* TIM2 init function */
void MX_TIM2_Init(void)
{
@ -70,7 +141,18 @@ void MX_TIM2_Init(void)
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM2)
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
/* USER CODE END TIM1_MspInit 0 */
/* TIM1 clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */
@ -82,11 +164,47 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM2_MspInit 1 */
}
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(timHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspPostInit 0 */
/* USER CODE END TIM1_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM1 GPIO Configuration
PA8 ------> TIM1_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN TIM1_MspPostInit 1 */
/* USER CODE END TIM1_MspPostInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM2)
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspDeInit 0 */
/* USER CODE END TIM1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();
/* USER CODE BEGIN TIM1_MspDeInit 1 */
/* USER CODE END TIM1_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspDeInit 0 */

View File

@ -1,35 +1,63 @@
#include "adc_filter.h"
/**
* @brief Привязка структуры фильтра к конкретному АЦП
* @param hfilter Указатель на структуру ADCFilter_t
* @param hadc Указатель на структуру HAL АЦП
*/
void adc_Attach(ADCFilter_t *hfilter, ADC_HandleTypeDef *hadc)
{
// Связываем фильтр с конкретным аппаратным АЦП для чтения данных
hfilter->hadc = hadc;
}
// фильтрация
/**
* @brief Обновление и фильтрация новых данных АЦП методом усреднения
* @param hfilter Указатель на структуру ADCFilter_t
* @return int Возвращает 1, если произведено обновление отфильтрованных данных, иначе 0
*/
int adc_filterring(ADCFilter_t *hfilter)
{
// Добавляем текущее значение из регистра данных АЦП в сумму
hfilter->sum += hfilter->hadc->Instance->DR;
// Увеличиваем счётчик накопленных выборок
hfilter->count++;
// Если набрано достаточное количество выборок для усреднения
if (hfilter->count >= hfilter->bufferSize)
{
// Вычисляем среднее значение и сохраняем как отфильтрованный результат
hfilter->AdcResult = hfilter->sum / hfilter->bufferSize;
// Сбрасываем сумму и счётчик для следующего цикла
hfilter->sum = 0;
hfilter->count = 0;
hfilter->f.DataUpdated = 1;
// Отмечаем, что новые данные отфильтрованы и готовы к чтению
hfilter->f.DataUpdated = 1;
return 1;
}
// Если ещё недостаточно данных, возвращаем 0 — фильтрация не завершена
return 0;
}
/**
* @brief Чтение последнего отфильтрованного значения АЦП
* @param hfilter Указатель на структуру ADCFilter_t
* @return uint16_t Последнее отфильтрованное значение
*/
uint16_t adc_read_data(ADCFilter_t *hfilter)
{
hfilter->f.DataUpdated = 0;
return hfilter->AdcResult;
// После чтения сбрасываем флаг обновления данных
hfilter->f.DataUpdated = 0;
return hfilter->AdcResult;
}
/**
* @brief Проверка, обновились ли данные АЦП после фильтрации
* @param hfilter Указатель на структуру ADCFilter_t
* @return int Возвращает 1, если данные были обновлены, иначе 0
*/
int adc_is_data_updated(ADCFilter_t *hfilter)
{
return hfilter->f.DataUpdated;
}
return hfilter->f.DataUpdated;
}

View File

@ -3,25 +3,37 @@
#include "main.h"
/**
* @brief Флаги состояния фильтра АЦП
*/
typedef struct
{
unsigned DataUpdated:1;
}AdcFilterFlags;
unsigned DataUpdated : 1; /**< Флаг обновления данных */
} AdcFilterFlags;
// структура для ацп
/**
* @brief Структура фильтрации данных АЦП
*/
typedef struct
{
AdcFilterFlags f;
uint16_t AdcResult;
ADC_HandleTypeDef *hadc;
uint32_t sum;
uint16_t count;
uint16_t bufferSize;
AdcFilterFlags f; /**< Флаги состояния */
uint16_t AdcResult; /**< Отфильтрованное значение АЦП */
ADC_HandleTypeDef *hadc; /**< Указатель на структуру HAL АЦП */
uint32_t sum; /**< Сумма накопленных значений для усреднения */
uint16_t count; /**< Текущий счётчик накопленных значений */
uint16_t bufferSize; /**< Размер буфера для усреднения (число выборок) */
} ADCFilter_t;
/** Привязка структуры фильтра к конкретному АЦП */
void adc_Attach(ADCFilter_t *hfilter, ADC_HandleTypeDef *hadc);
/** Обновление и фильтрация нового значения АЦП */
int adc_filterring(ADCFilter_t *hfilter);
/** Чтение последнего отфильтрованного значения АЦП */
uint16_t adc_read_data(ADCFilter_t *hfilter);
/** Проверка, обновились ли данные АЦП после фильтрации */
int adc_is_data_updated(ADCFilter_t *hfilter);
#endif //__ADC_FILTER_H
#endif //__ADC_FILTER_H

View File

@ -1,91 +1,143 @@
#include "upp.h"
#include "tiristor.h"
// управление тиристором
/**
* @brief Управление состоянием тиристора (включение/выключение) по флагам и времени открытия
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_control(TiristorControl_t *ctrl)
{
if(ctrl->f.EnableTiristor)
{
if(ctrl->f.TiristorIsEnable == 0)
{
tiristor_enable(ctrl);
ctrl->enable_start_tick = HAL_GetTick();
}
else
{
if(HAL_GetTick() - ctrl->enable_start_tick > ctrl->open_time)
{
tiristor_disable(ctrl);
ctrl->f.EnableTiristor = 0;
}
}
}
else
{
if(ctrl->f.TiristorIsEnable)
tiristor_disable(ctrl);
}
if(ctrl->f.EnableTiristor) // Если разрешено включить тиристор
{
if(ctrl->f.TiristorIsEnable == 0) // Если тиристор еще выключен
{
tiristor_enable(ctrl); // Включить тиристор
ctrl->enable_start_tick = HAL_GetTick(); // Запомнить время включения для отсчёта длительности открытия
}
else
{
// Если время с момента включения превысило заданное время открытия
if(HAL_GetTick() - ctrl->enable_start_tick > ctrl->open_time)
{
tiristor_disable(ctrl); // Выключить тиристор
ctrl->f.EnableTiristor = 0; // Снять разрешение на включение, чтобы не включался снова без команды
}
}
}
else // Если тиристор не должен быть включен
{
if(ctrl->f.TiristorIsEnable) // Если тиристор включен
tiristor_disable(ctrl); // Выключить тиристор
}
}
/**
* @brief Обновление значения задержки угла открытия тиристора в соответствии с направлением и шагом
* @param angle Указатель на структуру управления углом тиристора
*/
void tiristor_angle_update(TiristorAngleControl_t *angle)
{
uint32_t current_time_ms = HAL_GetTick();
if ((current_time_ms - angle->last_update_ms) >= angle->sample_time_ms)
{
angle->last_update_ms = current_time_ms;
{
uint32_t current_time_ms = HAL_GetTick(); // Текущее время в миллисекундах
if (angle->delay_us > angle->delay_min_us)
{
angle->delay_us -= angle->delay_step_us;
if (angle->delay_us < angle->delay_min_us)
angle->delay_us = angle->delay_min_us;
}
}
// Проверяем, прошло ли нужное время с последнего обновления
if ((current_time_ms - angle->last_update_ms) >= angle->Init->sample_time_ms)
{
angle->last_update_ms = current_time_ms; // Обновляем время последнего изменения задержки
// Изменяем задержку в зависимости от направления (разгон или торможение)
if(angle->Init->direction)
angle->delay_us += angle->Init->delay_step_us; // Увеличиваем задержку (увеличиваем угол)
else
angle->delay_us -= angle->Init->delay_step_us; // Уменьшаем задержку (уменьшаем угол)
// Ограничиваем задержку в пределах минимального и максимального значения
if (angle->delay_us < angle->Init->delay_min_us)
{
angle->delay_us = angle->Init->delay_min_us;
}
else if (angle->delay_us > angle->Init->delay_max_us)
{
angle->delay_us = angle->Init->delay_max_us;
}
}
}
/**
* @brief Контроль угла открытия тиристора с проверкой таймера и флага готовности
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_angle_control(TiristorControl_t *ctrl)
{
tiristor_angle_update(&ctrl->angle);
if ((uint16_t)((uint16_t)TIMER->CNT - ctrl->angle.start_delay_us) > ctrl->angle.delay_us)
{
if(ctrl->f.TiristorDone == 0)
{
ctrl->f.EnableTiristor = 1;
ctrl->f.TiristorDone = 1;
}
}
tiristor_angle_update(&ctrl->angle); // Обновляем задержку угла открытия
if(ctrl->angle.delay_us != 0) // Если задержка не нулевая
{
// Проверяем, прошла ли задержка с момента старта отсчёта таймера
if ((uint16_t)((uint16_t)TIMER->CNT - ctrl->angle.start_delay_tick) > ctrl->angle.delay_us)
{
if(ctrl->f.TiristorReady) // Если тиристор готов к включению
{
ctrl->f.EnableTiristor = 1; // Разрешаем включение тиристора
ctrl->f.TiristorReady = 0; // Снимаем флаг готовности, чтобы не включать повторно сразу
}
}
}
}
/**
* @brief Запуск отсчёта задержки для открытия тиристора
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_start_angle_delay(TiristorControl_t *ctrl)
{
ctrl->f.TiristorDone = 0;
ctrl->angle.start_delay_us = TIMER->CNT;
ctrl->f.TiristorReady = 1; // Устанавливаем флаг готовности тиристора к включению
ctrl->angle.start_delay_tick = TIMER->CNT; // Запоминаем текущее значение счётчика таймера
}
/**
* @brief Включение тиристора путём установки GPIO в состояние открытия
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_enable(TiristorControl_t *ctrl)
{
//HAL_GPIO_WritePin(ctrl->gpiox, ctrl->gpio_pin, GPIO_TIRISTOR_OPEN);
ctrl->gpiox->ODR |= ctrl->gpio_pin;
ctrl->f.TiristorIsEnable = 1;
// Открываем тиристор, установив соответствующий пин в высокое состояние
ctrl->gpiox->ODR |= ctrl->gpio_pin;
ctrl->f.TiristorIsEnable = 1; // Устанавливаем флаг, что тиристор включен
}
/**
* @brief Выключение тиристора путём установки GPIO в состояние закрытия
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_disable(TiristorControl_t *ctrl)
{
ctrl->gpiox->ODR &= ~ctrl->gpio_pin;
//HAL_GPIO_WritePin(ctrl->gpiox, ctrl->gpio_pin, GPIO_TIRISTOR_CLOSE);
ctrl->f.TiristorIsEnable = 0;
// Закрываем тиристор, сбросив соответствующий пин в низкое состояние
ctrl->gpiox->ODR &= ~ctrl->gpio_pin;
ctrl->f.TiristorIsEnable = 0; // Снимаем флаг включения тиристора
}
/**
* @brief Сброс значения задержки угла открытия тиристора к начальному в зависимости от направления
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_angle_reset(TiristorControl_t *ctrl)
{
// В зависимости от направления устанавливаем задержку на минимальное или максимальное значение
if(ctrl->angle.Init->direction)
ctrl->angle.delay_us = ctrl->angle.Init->delay_min_us;
else
ctrl->angle.delay_us = ctrl->angle.Init->delay_max_us;
}
/**
* @brief Инициализация структуры управления тиристором, установка GPIO и сброс угла открытия
* @param ctrl Указатель на структуру управления тиристором
* @param gpiox Указатель на порт GPIO
* @param gpio_pin Номер пина GPIO
*/
void tiristor_init(TiristorControl_t *ctrl, GPIO_TypeDef *gpiox, uint32_t gpio_pin)
{
ctrl->gpiox = gpiox;
ctrl->gpio_pin = gpio_pin;
ctrl->angle.delay_max_us = 8000;
ctrl->angle.delay_min_us = 100;
ctrl->angle.delay_us = 7000;
ctrl->angle.delay_step_us = 500;
ctrl->angle.sample_time_ms = 100;
ctrl->open_time = 1;
TIMER->CR1 |= TIM_CR1_CEN;
}
ctrl->open_time = 1; // Сохраняем порт GPIO
ctrl->gpiox = gpiox; // Сохраняем порт GPIO
ctrl->gpio_pin = gpio_pin; // Сохраняем номер пина GPIO
tiristor_angle_reset(ctrl); // Сбрасываем угол открытия тиристора на начальное значение
}

View File

@ -5,50 +5,108 @@
#include "tim.h"
#define GPIO_TIRISTOR_OPEN GPIO_PIN_SET
#define GPIO_TIRISTOR_CLOSE GPIO_PIN_RESET
#define GPIO_TIRISTOR_OPEN GPIO_PIN_SET /**< Состояние GPIO для открытия тиристора */
#define GPIO_TIRISTOR_CLOSE GPIO_PIN_RESET /**< Состояние GPIO для закрытия тиристора */
#define TIMER TIM2 /**< Таймер, используемый для управления тиристором */
#define TIMER TIM2
/**
* @brief Флаги состояния управления тиристором
*/
typedef struct
{
unsigned EnableTiristor:1;
unsigned TiristorIsEnable:1;
unsigned TiristorDone:1;
}TiristorControlFlags;
unsigned EnableTiristor:1; /**< Флаг разрешения управления тиристором */
unsigned TiristorIsEnable:1; /**< Флаг, указывающий, что тиристор включен */
unsigned TiristorReady:1; /**< Флаг готовности тиристора к работе */
} TiristorControlFlags;
/**
* @brief Параметры инициализации угла открытия тиристора
*/
typedef struct
{
uint32_t delay_us; // Текущая задержка (в микросекундах)
uint32_t delay_min_us; // Минимальная задержка (максимальное открытие тиристора)
uint32_t delay_max_us; // Начальная задержка (практически закрыт)
uint32_t delay_step_us; // Шаг уменьшения задержки
uint32_t last_update_ms; // Время последнего обновления
uint32_t sample_time_ms; // Интервал между шагами (например, 200 мс)
uint32_t delay_min_us; /**< Минимальная задержка (микросекунды), соответствует максимальному открытию тиристора */
uint32_t delay_max_us; /**< Начальная задержка (микросекунды), соответствует практически закрытому тиристору */
uint32_t delay_step_us; /**< Шаг уменьшения задержки (микросекунды) */
uint32_t sample_time_ms; /**< Интервал времени между шагами регулировки (миллисекунды) */
unsigned direction; /**< Направление регулировки: разгон (увеличение открытого угла) или торможение */
} AngleInit_t;
uint16_t start_delay_us;
}TiristorAngleControl_t;
/**
* @brief Структура управления углом открытия тиристора
*/
typedef struct
{
AngleInit_t *Init; /**< Указатель на структуру параметров инициализации угла */
uint32_t last_update_ms; /**< Время последнего обновления (миллисекунды) */
uint32_t delay_us; /**< Текущая задержка (микросекунды) */
uint16_t start_delay_tick; /**< Значение таймера при старте задержки */
} TiristorAngleControl_t;
typedef struct TiristorControl_t TiristorControl_t;
/**
* @brief Основная структура управления тиристором
*/
struct TiristorControl_t
{
TiristorControlFlags f;
TiristorAngleControl_t angle;
GPIO_TypeDef *gpiox;
uint32_t gpio_pin;
uint32_t open_time;
uint32_t enable_start_tick;
void (*start_delay)(TiristorControl_t *ctrl); // Указатель на функцию запуска задержки включения
TiristorControlFlags f; /**< Флаги состояния тиристора */
TiristorAngleControl_t angle; /**< Управление углом открытия */
GPIO_TypeDef *gpiox; /**< Порт GPIO для управления тиристором */
uint32_t gpio_pin; /**< Номер пина GPIO */
uint32_t open_time; /**< Время открытия тиристора */
uint32_t enable_start_tick; /**< Время включения тиристора по таймеру */
};
/**
* @brief Управление состоянием тиристора (включение/выключение)
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_control(TiristorControl_t *ctrl);
/**
* @brief Обновление угла открытия тиристора согласно параметрам
* @param angle Указатель на структуру управления углом тиристора
*/
void tiristor_angle_update(TiristorAngleControl_t *angle);
/**
* @brief Контроль угла открытия тиристора, включая обновление состояния
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_angle_control(TiristorControl_t *ctrl);
/**
* @brief Запуск задержки открытия тиристора
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_start_angle_delay(TiristorControl_t* ctrl);
/**
* @brief Сброс угла открытия тиристора к начальному состоянию
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_angle_reset(TiristorControl_t *ctrl);
/**
* @brief Включение тиристора
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_enable(TiristorControl_t *ctrl);
/**
* @brief Выключение тиристора
* @param ctrl Указатель на структуру управления тиристором
*/
void tiristor_disable(TiristorControl_t *ctrl);
/**
* @brief Инициализация структуры управления тиристором
* @param ctrl Указатель на структуру управления тиристором
* @param gpiox Указатель на GPIO порт
* @param gpio_pin Номер GPIO пина
*/
void tiristor_init(TiristorControl_t *ctrl, GPIO_TypeDef *gpiox, uint32_t gpio_pin);
#endif //__TIRISTORS_H
#endif //__TIRISTORS_H

View File

@ -1,50 +1,410 @@
#include "upp.h"
Phase_t phase_A;
Phase_t phase_B;
Phase_t phase_C;
// главная функция
void upp_main(void)
{
upp_phase_routine(&phase_A);
upp_phase_routine(&phase_B);
upp_phase_routine(&phase_C);
Phase_t phase_A; /*< Фаза управления тиристорами A */
Phase_t phase_B; /*< Фаза управления тиристорами B */
Phase_t phase_C; /*< Фаза управления тиристорами C */
UPP_Control_t Upp; /*< Структура управления УПП */
/**
* @brief Главная функция управления УПП
*
* @details Выполняет основную логику управления пускателем:
* инициализация углов, безопасный запуск,
* проверка флагов остановки/отключения,
* управление фазами и тиристорами.
*/void upp_main(void)
{
// Проверяем необходимость обновления параметров угла управления тиристорами
if(GetAngleInit(&Upp.angleInit))
{
// Если параметры изменились, сбрасываем углы для всех фаз
tiristor_angle_reset(&phase_A.ctrl);
tiristor_angle_reset(&phase_B.ctrl);
tiristor_angle_reset(&phase_C.ctrl);
}
upp_phase_control(&phase_A);
upp_phase_control(&phase_B);
upp_phase_control(&phase_C);
// Выполняем безопасный запуск (обработка изменения направления и стартового состояния)
upp_safe_go();
// Если установлен флаг принудительной остановки, выключаем питание УПП и подключаем выход
if(Upp.ForceStop)
{
Upp.Go = 0; // Останавливаем работу
connect_upp(); // Подключаем УПП (прямое питание)
return; // Выход из функции, дальнейшая логика не выполняется
}
// Если установлен флаг принудительного отключения, выставляем готовность тиристоров и отключаем УПП
if(Upp.ForceDisconnect)
{
phase_A.ctrl.f.TiristorReady = 1;
phase_B.ctrl.f.TiristorReady = 1;
phase_C.ctrl.f.TiristorReady = 1;
Upp.Go = 0; // Останавливаем работу
disconnect_upp(); // Отключаем УПП (снимаем питание с выхода)
return;
}
// Если установлен флаг плавного отключения УПП, готовим тиристоры и отключаем УПП
if(Upp.GoDisconnect)
{
phase_A.ctrl.f.TiristorReady = 1;
phase_B.ctrl.f.TiristorReady = 1;
phase_C.ctrl.f.TiristorReady = 1;
Upp.Go = 0;
disconnect_upp();
}
// Если установлен флаг остановки, останавливаем работу и подключаем УПП (прямое питание)
if(Upp.GoStop)
{
Upp.Go = 0;
connect_upp();
}
// Если в режиме подготовки (запуска)
if(Upp.Prepare)
{
// Если УПП в состоянии отключения, подключаем его (готовим к работе)
if(Upp.Disconnected)
{
connect_upp();
}
// Обрабатываем каждую фазу (детектирование нуля, управление углом тиристора)
upp_phase_routine(&phase_A);
upp_phase_routine(&phase_B);
upp_phase_routine(&phase_C);
}
// Если работа разрешена (флаг Go)
if(Upp.Go)
{
// Если всё ещё в подготовке, проверяем готовность тиристоров
if(Upp.Prepare)
{
// Если все тиристоры готовы — снимаем флаг подготовки и продолжаем работу
if(phase_A.ctrl.f.TiristorReady && phase_B.ctrl.f.TiristorReady && phase_C.ctrl.f.TiristorReady)
{
Upp.Prepare = 0;
}
else
{
// Если хоть один тиристор не готов — выходим, не продолжая управление
return;
}
}
// Если во время работы произошло отключение УПП — ставим флаг принудительной остановки
if(Upp.Disconnected)
{
Upp.ForceStop = 1;
return;
}
// Проверяем условие достижения минимального угла (минимальная задержка) во время запуска (direction == 0)
// Это значит, что тиристоры открыты максимально рано — можно перейти на прямое питание двигателя
if( (phase_A.ctrl.angle.delay_us == phase_A.ctrl.angle.Init->delay_min_us) &&
(phase_B.ctrl.angle.delay_us == phase_B.ctrl.angle.Init->delay_min_us) &&
(phase_C.ctrl.angle.delay_us == phase_C.ctrl.angle.Init->delay_min_us) && (Upp.angleInit.direction == 0))
{
Upp.GoDisconnect = 1; // Флаг для отключения УПП и подачи питания напрямую
}
else
{
Upp.GoDisconnect = 0;
}
// Проверяем условие достижения максимального угла (максимальная задержка) во время торможения (direction == 1)
// Это значит, что тиристоры максимально закрыты — нужно остановить питание двигателя
if( (phase_A.ctrl.angle.delay_us == phase_A.ctrl.angle.Init->delay_max_us) &&
(phase_B.ctrl.angle.delay_us == phase_B.ctrl.angle.Init->delay_max_us) &&
(phase_C.ctrl.angle.delay_us == phase_C.ctrl.angle.Init->delay_max_us) && (Upp.angleInit.direction == 1))
{
Upp.GoStop = 1; // Флаг для остановки УПП и отключения питания
}
else
{
Upp.GoStop = 0;
}
// Продолжаем обработку фаз — обновляем состояние и проверяем условия управления тиристорами
upp_phase_routine(&phase_A);
upp_phase_routine(&phase_B);
upp_phase_routine(&phase_C);
// Управляем тиристорами каждой фазы с помощью функций контроля угла и самого тиристора
upp_phase_control(&phase_A);
upp_phase_control(&phase_B);
upp_phase_control(&phase_C);
}
else
{
// Если флаг Go не установлен, сбрасываем углы управления тиристорами для всех фаз
tiristor_angle_reset(&phase_A.ctrl);
tiristor_angle_reset(&phase_B.ctrl);
tiristor_angle_reset(&phase_C.ctrl);
}
}
/**
* @brief Функция безопасного запуска УПП
*
* @details Следит за изменениями флага GoSafe и запускает или останавливает пускатель,
* сбрасывая угол задержки тиристоров в зависимости от направления.
*/
void upp_safe_go(void)
{
static int prev_gosafe; // Статическая переменная для хранения предыдущего значения флага GoSafe
// Если текущее значение GoSafe больше предыдущего — это сигнал о старте в режиме запуска (направление 0)
if(Upp.GoSafe > prev_gosafe)
{
Upp.angleInit.direction = 0; // Устанавливаем направление пуска (разгон)
Upp.Prepare = 1; // Включаем режим подготовки
Upp.Go = 1; // Включаем основной флаг запуска работы УПП
// Сбрасываем углы управления тиристорами для всех фаз — начинаем с начального состояния
tiristor_angle_reset(&phase_A.ctrl);
tiristor_angle_reset(&phase_B.ctrl);
tiristor_angle_reset(&phase_C.ctrl);
}
// Если текущее значение GoSafe меньше предыдущего — это сигнал о старте в режиме торможения (направление 1)
else if (Upp.GoSafe < prev_gosafe)
{
Upp.angleInit.direction = 1; // Устанавливаем направление торможения
Upp.Prepare = 1; // Включаем режим подготовки
Upp.Go = 1; // Включаем основной флаг запуска работы УПП
// Сбрасываем углы управления тиристорами для всех фаз — начинаем с начального состояния
tiristor_angle_reset(&phase_A.ctrl);
tiristor_angle_reset(&phase_B.ctrl);
tiristor_angle_reset(&phase_C.ctrl);
}
// Обновляем сохранённое предыдущее значение GoSafe для отслеживания изменений в следующем вызове
prev_gosafe = Upp.GoSafe;
}
/**
* @brief Отключение питания УПП (разрыв всех фаз)
*
* @details Если тиристор готов, вызывает макросы отключения фаз,
* после чего выставляет соответствующие флаги состояния.
*/
void disconnect_upp(void)
{
// Если тиристоры фазы A открыты, подключаем фазу напрямую
if(phase_A.ctrl.f.TiristorReady)
{
disconnect_phase(&phase_A);
}
// Аналогично для фазы B
if(phase_B.ctrl.f.TiristorReady)
{
disconnect_phase(&phase_B);
}
// Аналогично для фазы C
if(phase_C.ctrl.f.TiristorReady)
{
disconnect_phase(&phase_C);
}
// Если УПП на всех трех фазах отключены
if(phase_A.disconnect.Disconnected && phase_B.disconnect.Disconnected && phase_C.disconnect.Disconnected)
{
Upp.Disconnected = 1; // Устанавливаем флаг, что УПП полностью отключена
Upp.GoDisconnect = 0; // Сбрасываем флаг запроса на отключение
Upp.Go = 0; // Прекращаем работу УПП
}
}
/**
* @brief Подключение питания УПП (соединение всех фаз)
*
* @details Вызывает отключение тиристоров и макросы подключения фаз,
* сбрасывает флаг отключения.
*/
void connect_upp(void)
{
// Отключаем управление тиристорами для всех фаз
tiristor_disable(&phase_A.ctrl);
tiristor_disable(&phase_B.ctrl);
tiristor_disable(&phase_C.ctrl);
// Подключаем УПП к каждой фазе)
connect_phase(&phase_A);
connect_phase(&phase_B);
connect_phase(&phase_C);
// Сбрасываем флаг, указывающий на то, что УПП было отключено
Upp.Disconnected = 0;
}
/**
* @brief Управление одной фазой УПП
* @param phase Указатель на структуру фазы Phase_t
*
* @details Контролирует угол и включает/отключает тиристор для данной фазы.
*/
void upp_phase_control(Phase_t *phase)
{
tiristor_angle_control(&phase->ctrl);
tiristor_control(&phase->ctrl);
}
/**
* @brief Обработка фазы при каждом нулевом переходе синусоиды
* @param phase Указатель на структуру фазы Phase_t
*
* @details Обновляет состояние детектора нулевого перехода,
* запускает задержку угла тиристора,
* отключает тиристор, если он был включен.
*/
void upp_phase_routine(Phase_t *phase)
{
// Обновляем детектор нулевого перехода по текущему состоянию входного сигнала
zero_cross_update(&phase->zc_detector);
// Если обнаружен нулевой переход (синусоида пересекла 0)
if(is_zero_cross(&phase->zc_detector))
{
// Запускаем отсчёт задержки до открытия тиристора (по углу)
tiristor_start_angle_delay(&phase->ctrl);
// Если тиристор был включён в предыдущем полупериоде — отключаем его
if (phase->ctrl.f.TiristorIsEnable)
tiristor_disable(&phase->ctrl);
}
}
void upp_phase_routine(Phase_t *phase)
/**
* @brief Расчёт параметров угла запуска тиристора
* @param angle Указатель на структуру AngleInit_t для записи параметров
* @return int 1, если произошли изменения параметров, иначе 0
*
* @details Проверяет изменения в параметрах управления и при необходимости
* пересчитывает максимальные и минимальные задержки, шаг изменения угла,
* а также изменяет прескалер таймера.
*/
int GetAngleInit(AngleInit_t *angle)
{
tiristor_angle_control(&phase->ctrl);
tiristor_control(&phase->ctrl);
zero_cross_update(&phase->zc_detector);
static float sine_freq_old = 0;
static float Duration_old = 0;
static float max_duty_old = 0, min_duty_old = 0; // Задаются в процентах
int update = 0;
// Проверка, изменились ли параметры: частота, скважности
if( (Upp.sine_freq != sine_freq_old) &&
(Upp.max_duty != max_duty_old) &&
(Upp.min_duty != min_duty_old) )
{
update = 1;
min_duty_old = Upp.min_duty;
max_duty_old = Upp.max_duty;
sine_freq_old = Upp.sine_freq;
}
// Проверка, изменились ли длительность
if(Upp.Duration != Duration_old)
{
update = 1;
Duration_old = Upp.Duration;
}
if(update)
{
// Расчёт длительности полупериода в микросекундах (с учётом вычета резерва на открытие тиристора)
uint32_t half_period_us = (500000.0f / Upp.sine_freq) - 1000;
// Расчёт максимальной и минимальной задержки (в мкс) по процентам скважности
angle->delay_max_us = (uint32_t)(Upp.max_duty * half_period_us);
angle->delay_min_us = (uint32_t)(Upp.min_duty * half_period_us);
// Проверка, помещаются ли значения задержек в 16-битный таймер
if((angle->delay_max_us > 0xFFFF) || (angle->delay_min_us > 0xFFFF))
{
// Если нет — увеличиваем прескалер в 10 раз (точность 10 мкс)
angle->delay_max_us /= 10;
angle->delay_min_us /= 10;
TIMER->PSC = 719;
if((angle->delay_max_us > 0xFFFF) || (angle->delay_min_us > 0xFFFF))
{
// Если всё ещё не помещается — ещё в 10 раз (точность 0.1 мс)
angle->delay_max_us /= 10;
angle->delay_min_us /= 10;
TIMER->PSC = 7299;
if ((angle->delay_max_us > 0xFFFF) || (angle->delay_min_us > 0xFFFF))
{
// Если даже при этом переполнение — аварийная остановка
Upp.ForceStop = 1;
}
}
}
else
{
// Задержки помещаются — устанавливаем стандартный прескалер (1 мкс)
TIMER->PSC = 71;
}
// Перевод длительности разгона/торможения из секунд в миллисекунды
float duration_ms = Duration_old * 1000.0f;
uint32_t steps = duration_ms / angle->sample_time_ms;
if (steps == 0) steps = 1;
// Вычисление шага изменения задержки на каждом шаге
if (angle->delay_max_us > angle->delay_min_us)
angle->delay_step_us = (angle->delay_max_us - angle->delay_min_us) / steps;
else
angle->delay_step_us = 0;
}
return update;
}
/**
* @brief Инициализация УПП и связанных структур
*
* @details Настраивает параметры управления, GPIO для фаз,
* инициализирует тиристоры, запускает таймер и настраивает детектор нулевого перехода.
*/
void upp_init(void)
{
Upp.max_duty = 0.9;
Upp.min_duty = 0.1;
Upp.angleInit.sample_time_ms = 100;
phase_A.disconnect.gpiox = GPIOA;
phase_A.disconnect.gpio_pin = GPIO_PIN_5;
phase_B.disconnect.gpiox = GPIOA;
phase_B.disconnect.gpio_pin = GPIO_PIN_6;
phase_C.disconnect.gpiox = GPIOA;
phase_C.disconnect.gpio_pin = GPIO_PIN_7;
phase_A.ctrl.angle.Init = &Upp.angleInit;
phase_B.ctrl.angle.Init = &Upp.angleInit;
phase_C.ctrl.angle.Init = &Upp.angleInit;
tiristor_init(&phase_A.ctrl, GPIOB, GPIO_PIN_12);
tiristor_init(&phase_B.ctrl, GPIOB, GPIO_PIN_13);
tiristor_init(&phase_C.ctrl, GPIOB, GPIO_PIN_14);
#ifndef HARDWARE_ZERO_CROSS_DETECT
adc_Attach(&phase_A.zc_detector.AdcFilter, &hadc);
zero_cross_Init(&phase_A.zc_detector, ADC_INITIAL_ZERO_LEVEL);
TIMER->CR1 |= TIM_CR1_CEN;
adc_Attach(&phase_A.zc_detector.AdcFilter, &hadc);
zero_cross_Init(&phase_A.zc_detector, ADC_INITIAL_ZERO_LEVEL);
#endif
tiristor_angle_reset(&phase_A.ctrl);
tiristor_angle_reset(&phase_B.ctrl);
tiristor_angle_reset(&phase_C.ctrl);
//Upp.GoSafe = 1;
}

View File

@ -9,23 +9,98 @@
#include "zero_cross.h"
#include "tiristor.h"
#define hadc hadc1
#define ADC_INITIAL_ZERO_LEVEL 2048
/**
* @brief Определение используемого ADC
*/
#define hadc hadc1
/**
* @brief Начальный уровень отсчёта для определения нуля в ADC (обычно середина диапазона)
*/
#define ADC_INITIAL_ZERO_LEVEL 2048
/**
* @brief Макрос для разрыва (отключения) фазы устанавливает GPIO в высокий уровень и флаг Disconnected
* @param _ph_ Указатель на структуру фазы Phase_t
*/
#define disconnect_phase(_ph_) { (_ph_)->disconnect.gpiox->ODR |= (_ph_)->disconnect.gpio_pin; (_ph_)->disconnect.Disconnected = 1;}
/**
* @brief Макрос для подключения фазы сбрасывает GPIO в низкий уровень и флаг Disconnected
* @param _ph_ Указатель на структуру фазы Phase_t
*/
#define connect_phase(_ph_) { (_ph_)->disconnect.gpiox->ODR &= ~(_ph_)->disconnect.gpio_pin; (_ph_)->disconnect.Disconnected = 0;}
/**
* @struct Phase_t
* @brief Структура, описывающая одну фазу с состоянием тиристора и детектом нуля
*/
typedef struct
{
ZeroCrossDetector_t zc_detector;
TiristorControl_t ctrl;
} Phase_t; // структура для фазы
struct
{
unsigned Disconnected:1; /**< Флаг разрыва фазы */
GPIO_TypeDef *gpiox; /**< Порт GPIO для разрыва */
uint32_t gpio_pin; /**< Пин GPIO для разрыва */
}disconnect;
ZeroCrossDetector_t zc_detector; /**< Детектор пересечения нуля */
TiristorControl_t ctrl; /**< Управление тиристором */
} Phase_t;
/**
* @struct UPP_Control_t
* @brief Основная структура управления устройством плавного пуска
*/
typedef struct
{
unsigned GoSafe:1; /**< Флаг безопасного запуска */
unsigned Go:1; /**< Флаг запуска */
unsigned GoStop:1; /**< Флаг остановки */
unsigned Prepare:1; /**< Флаг подготовки */
unsigned Disconnected:1; /**< Флаг разрыва */
unsigned GoDisconnect:1; /**< Флаг отключения */
unsigned ForceStop:1; /**< Флаг форсированной остановки */
unsigned ForceDisconnect:1; /**< Флаг форсированного отключения */
unsigned PreGoDone:1; /**< Флаг завершения подготовки */
float Duration; /**< Время нарастания и спада напряжение через УПП */
float sine_freq; /**< Частота сети */
float max_duty; /**< Максимальная скважность угла открытия */
float min_duty; /**< Минимальная скважность угла открытия */
AngleInit_t angleInit; /**< Настройки угла открытия тиристора */
} UPP_Control_t;
extern Phase_t phase_A;
extern Phase_t phase_B;
extern Phase_t phase_C;
extern UPP_Control_t Upp;
/** Основной цикл работы устройства плавного пуска */
void upp_main(void);
/** Выполнение безопасного запуска устройства */
void upp_safe_go(void);
/** Отключение устройства плавного пуска (разрыв фаз) */
void disconnect_upp(void);
/** Подключение устройства плавного пуска (восстановление фаз) */
void connect_upp(void);
/** Выполнение обработки одной фазы в цикле */
void upp_phase_routine(Phase_t *phase);
/** Управление фазой с контролем тиристора и нуля */
void upp_phase_control(Phase_t *phase);
/** Получение настроек угла открытия тиристора */
int GetAngleInit(AngleInit_t *angle);
/** Инициализация устройства плавного пуска */
void upp_init(void);
#endif //__UPP_H
#endif //__UPP_H

View File

@ -1,56 +1,53 @@
#include "zero_cross.h"
ADCFilter_t AdcFilter;
/**
* @brief Инициализация структуры детектора перехода через ноль
* @param zc Указатель на структуру ZeroCrossDetector_t
* @param zeroLevel Значение уровня АЦП, соответствующее нулю (mid-scale)
*/
void zero_cross_Init(ZeroCrossDetector_t *zc, uint16_t zeroLevel)
{
zc->lastSample = 0;
zc->f.ZeroCrossDetected = 0;
zc->zeroLevel = zeroLevel;
// Сбрасываем флаг обнаружения перехода через ноль
zc->f.ZeroCrossDetected = 0;
}
// апдейт флага зерокросс детектед
/**
* @brief Обновление флага перехода через ноль
* @param zc Указатель на структуру ZeroCrossDetector_t
* @details Просто переносим флаг EXTI с аппаратного детектора.
*/
void zero_cross_update(ZeroCrossDetector_t *zc)
{
#ifdef HARDWARE_ZERO_CROSS_DETECT
zc->f.ZeroCrossDetected = zc->f.EXTIZeroCrossDetected;
#else
uint16_t adcValue;
if(adc_is_data_updated(&zc->AdcFilter))
{
adcValue = adc_read_data(&zc->AdcFilter);
}
else
{
return;
}
zc->currSample = (int16_t)adcValue - (int16_t)zc->zeroLevel;
if ((zc->lastSample < 0 && zc->currSample >= 0) ||
(zc->lastSample > 0 && zc->currSample <= 0))
{
zc->f.ZeroCrossDetected = 1;
}
zc->lastSample = zc->currSample;
#endif
// Используем флаг аппаратного прерывания EXTI для установки флага перехода через ноль
zc->f.ZeroCrossDetected = zc->f.EXTIZeroCrossDetected;
}
/**
* @brief Проверка наличия перехода через ноль и сброс флагов
* @param zc Указатель на структуру ZeroCrossDetector_t
* @return int 1 переход через ноль обнаружен, 0 нет
* @details Если переход обнаружен, сбрасываем флаги и возвращаем 1,
* иначе возвращаем 0.
*/
int is_zero_cross(ZeroCrossDetector_t *zc)
{
if(zc->f.ZeroCrossDetected)
{
zc->f.ZeroCrossDetected = 0;
zc->f.EXTIZeroCrossDetected = 0;
return 1;
}
return 0;
if(zc->f.ZeroCrossDetected)
{
// Сброс флагов после обнаружения
zc->f.ZeroCrossDetected = 0;
zc->f.EXTIZeroCrossDetected = 0;
return 1;
}
return 0;
}
#ifdef HARDWARE_ZERO_CROSS_DETECT
/**
* @brief Обработчик прерывания EXTI для аппаратного детектора перехода через ноль
* @param zc Указатель на структуру ZeroCrossDetector_t
* @details Устанавливает флаг аппаратного перехода через ноль.
*/
void zero_cross_update_EXTI(ZeroCrossDetector_t *zc)
{
zc->f.EXTIZeroCrossDetected = 1;
zc->f.EXTIZeroCrossDetected = 1;
}
#endif

View File

@ -4,38 +4,31 @@
#include "main.h"
#include "adc_filter.h"
#define hadc hadc1
#define HARDWARE_ZERO_CROSS_DETECT // аппаратный детект зеро кросс (альтернатива - считывая через ацп)
/**
* @brief Флаги состояния детектора нуля
*/
typedef struct
{
unsigned WaitForZeroCrossDetected : 1;
#ifdef HARDWARE_ZERO_CROSS_DETECT
unsigned EXTIZeroCrossDetected:1;
#endif
unsigned ZeroCrossDetected:1;
}ZeroCrossFlags;
unsigned WaitForZeroCrossDetected : 1; /**< Ожидание обнаружения перехода через ноль */
unsigned EXTIZeroCrossDetected : 1; /**< Флаг обнаружения нуля аппаратным прерыванием EXTI */
unsigned ZeroCrossDetected : 1; /**< Флаг обнаружения перехода через ноль */
} ZeroCrossFlags;
/**
* @brief Структура детектора перехода через ноль
*/
typedef struct
{
ZeroCrossFlags f;
int currSample;
int16_t lastSample; // предыдущее значение (относительно нуля)
uint16_t zeroLevel; // уровень, соответствующий "нулю", обычно mid-scale
ADCFilter_t AdcFilter;
ZeroCrossFlags f; /**< Флаги состояния детектора */
} ZeroCrossDetector_t;
/** Инициализация структуры детектора перехода через ноль */
void zero_cross_Init(ZeroCrossDetector_t *zc, uint16_t zeroLevel);
/** Обновление состояния детектора перехода через ноль */
void zero_cross_update(ZeroCrossDetector_t *zc);
/** Проверка, был ли обнаружен переход через ноль */
int is_zero_cross(ZeroCrossDetector_t *zc);
#ifdef HARDWARE_ZERO_CROSS_DETECT
/** Обновление состояния детектора перехода через ноль при аппаратном прерывании EXTI */
void zero_cross_update_EXTI(ZeroCrossDetector_t *zc);
#endif
#endif //__ZERO_CROSS_H
#endif //__ZERO_CROSS_H

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component-->
<events>
</events>
</component_viewer>

File diff suppressed because one or more lines are too long

View File

@ -117,6 +117,26 @@
<pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name>(105=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
@ -125,10 +145,22 @@
<SetRegEntry>
<Number>0</Number>
<Key>ST-LINKIII-KEIL_SWO</Key>
<Name>-U-O142 -O2254 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128 -FS08000000 -FL08000 -FP0($$Device:STM32F103C6$Flash\STM32F10x_128.FLM)</Name>
<Name>-U-O142 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(1BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL08000 -FP0($$Device:STM32F103C6$Flash\STM32F10x_128.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>Upp</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>phase_A</ItemText>
</Ww>
</WatchWindow1>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
@ -171,9 +203,15 @@
<pszMrulep></pszMrulep>
<pSingCmdsp></pSingCmdsp>
<pMultCmdsp></pMultCmdsp>
<SystemViewers>
<Entry>
<Name>System Viewer\TIM1</Name>
<WinId>35905</WinId>
</Entry>
</SystemViewers>
<DebugDescription>
<Enable>1</Enable>
<EnableFlashSeq>1</EnableFlashSeq>
<EnableFlashSeq>0</EnableFlashSeq>
<EnableLog>0</EnableLog>
<Protocol>2</Protocol>
<DbgClock>10000000</DbgClock>

View File

@ -82,7 +82,7 @@
</BeforeMake>
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<RunUserProg2>1</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
@ -315,7 +315,7 @@
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>4</Optim>
<Optim>1</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
@ -341,7 +341,7 @@
<MiscControls></MiscControls>
<Define>USE_HAL_DRIVER,STM32F103x6</Define>
<Undefine></Undefine>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;..\Core\upp</IncludePath>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Core/upp</IncludePath>
</VariousControls>
</Cads>
<Aads>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -30,4 +30,7 @@ upp/stm32f1xx_it.o: ..\Core\Src\stm32f1xx_it.c ..\Core\Inc\main.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h \
..\Core\Inc\stm32f1xx_it.h
..\Core\Inc\stm32f1xx_it.h ..\Core\upp\upp.h ..\Core\Inc\adc.h \
..\Core\Inc\tim.h ..\Core\Inc\usart.h ..\Core\Inc\gpio.h \
..\Core\upp\zero_cross.h ..\Core\upp\adc_filter.h \
..\Core\upp\tiristor.h

Binary file not shown.

View File

@ -1,4 +1,4 @@
upp/tiristor.o: ..\Core\upp\tiristor.c ..\Core\upp\upp.h \
upp/tiristor.o: ..\Core\upp\tiristor.c ..\Core\upp\tiristor.h \
..\Core\Inc\main.h ..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h \
..\Core\Inc\stm32f1xx_hal_conf.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h \
@ -30,6 +30,4 @@ upp/tiristor.o: ..\Core\upp\tiristor.c ..\Core\upp\upp.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h \
..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h \
..\Core\Inc\adc.h ..\Core\Inc\tim.h ..\Core\Inc\usart.h \
..\Core\Inc\gpio.h ..\Core\upp\zero_cross.h ..\Core\upp\adc_filter.h \
..\Core\upp\tiristor.h
..\Core\Inc\tim.h

Binary file not shown.

View File

@ -9,7 +9,7 @@ CAD.formats=
CAD.pinconfig=
CAD.provider=
File.Version=6
GPIO.groupedBy=
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
Mcu.CPN=STM32F103C6T6A
Mcu.Family=STM32F1
@ -17,23 +17,36 @@ Mcu.IP0=ADC1
Mcu.IP1=NVIC
Mcu.IP2=RCC
Mcu.IP3=SYS
Mcu.IP4=TIM2
Mcu.IP5=USART1
Mcu.IPNb=6
Mcu.IP4=TIM1
Mcu.IP5=TIM2
Mcu.IP6=USART1
Mcu.IPNb=7
Mcu.Name=STM32F103C(4-6)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PC14-OSC32_IN
Mcu.Pin1=PC15-OSC32_OUT
Mcu.Pin10=VP_TIM2_VS_ClockSourceINT
Mcu.Pin2=PD0-OSC_IN
Mcu.Pin3=PD1-OSC_OUT
Mcu.Pin4=PA0-WKUP
Mcu.Pin5=PA9
Mcu.Pin6=PA10
Mcu.Pin7=PA13
Mcu.Pin8=PA14
Mcu.Pin9=VP_SYS_VS_Systick
Mcu.PinsNb=11
Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PC14-OSC32_IN
Mcu.Pin10=PB1
Mcu.Pin11=PB2
Mcu.Pin12=PB12
Mcu.Pin13=PB13
Mcu.Pin14=PB14
Mcu.Pin15=PA8
Mcu.Pin16=PA9
Mcu.Pin17=PA10
Mcu.Pin18=PA13
Mcu.Pin19=PA14
Mcu.Pin2=PC15-OSC32_OUT
Mcu.Pin20=VP_SYS_VS_Systick
Mcu.Pin21=VP_TIM1_VS_ClockSourceINT
Mcu.Pin22=VP_TIM2_VS_ClockSourceINT
Mcu.Pin3=PD0-OSC_IN
Mcu.Pin4=PD1-OSC_OUT
Mcu.Pin5=PA0-WKUP
Mcu.Pin6=PA5
Mcu.Pin7=PA6
Mcu.Pin8=PA7
Mcu.Pin9=PB0
Mcu.PinsNb=23
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103C6Tx
@ -41,6 +54,9 @@ MxCube.Version=6.12.1
MxDb.Version=DB.6.0.121
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.EXTI0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.EXTI1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.EXTI2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@ -57,8 +73,35 @@ PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA5.Locked=true
PA5.Signal=GPIO_Output
PA6.Locked=true
PA6.Signal=GPIO_Output
PA7.Locked=true
PA7.Signal=GPIO_Output
PA8.Signal=S_TIM1_CH1
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB0.GPIOParameters=GPIO_ModeDefaultEXTI
PB0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING
PB0.Locked=true
PB0.Signal=GPXTI0
PB1.GPIOParameters=GPIO_ModeDefaultEXTI
PB1.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING
PB1.Locked=true
PB1.Signal=GPXTI1
PB12.Locked=true
PB12.Signal=GPIO_Output
PB13.Locked=true
PB13.Signal=GPIO_Output
PB14.Locked=true
PB14.Signal=GPIO_Output
PB2.GPIOParameters=GPIO_ModeDefaultEXTI
PB2.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING
PB2.Locked=true
PB2.Signal=GPXTI2
PC13-TAMPER-RTC.Locked=true
PC13-TAMPER-RTC.Signal=GPIO_Output
PC14-OSC32_IN.Mode=LSE-External-Oscillator
PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
@ -98,7 +141,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_TIM2_Init-TIM2-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_TIM2_Init-TIM2-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true
RCC.ADCFreqValue=12000000
RCC.ADCPresc=RCC_ADCPCLK2_DIV6
RCC.AHBFreq_Value=72000000
@ -123,10 +166,27 @@ RCC.USBFreq_Value=72000000
RCC.VCOOutput2Freq_Value=8000000
SH.ADCx_IN0.0=ADC1_IN0,IN0
SH.ADCx_IN0.ConfNb=1
SH.GPXTI0.0=GPIO_EXTI0
SH.GPXTI0.ConfNb=1
SH.GPXTI1.0=GPIO_EXTI1
SH.GPXTI1.ConfNb=1
SH.GPXTI2.0=GPIO_EXTI2
SH.GPXTI2.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Period,Pulse-PWM Generation1 CH1
TIM1.Period=20000
TIM1.Prescaler=72-1
TIM1.Pulse-PWM\ Generation1\ CH1=10000
TIM2.IPParameters=Prescaler
TIM2.Prescaler=72-1
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM1_VS_ClockSourceINT.Mode=Internal
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
VP_TIM2_VS_ClockSourceINT.Mode=Internal
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
board=custom

1314
readme.md Normal file

File diff suppressed because it is too large Load Diff

BIN
Диплом bare.docx Normal file

Binary file not shown.

Binary file not shown.

BIN
Диплом.docx Normal file

Binary file not shown.

BIN
Литра.docx Normal file

Binary file not shown.

BIN
Приложения.docx Normal file

Binary file not shown.

BIN
госы/gos.docx Normal file

Binary file not shown.

BIN
госы/gos.pdf Normal file

Binary file not shown.

1314
госы/readme.md Normal file

File diff suppressed because it is too large Load Diff

943
итог/diplom.drawio Normal file

File diff suppressed because one or more lines are too long

792
итог/out/diplom.drawio Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More