This commit is contained in:
2025-05-09 21:26:59 +03:00
commit 5e1364447e
2936 changed files with 2471676 additions and 0 deletions

View File

@@ -0,0 +1,239 @@
#include "pwm.h"
TIM_SettingsTypeDef TIM_CTRL = {0};
// variables for filling arrays
int Numb_Of_Peroids = 2; // number of periods
int Samples_Per_Peroid = 0; // how many samples in one period
int Size_Of_Log = 0; // size of written data to log
int log_ind = 0; // index of log arrays
int cnt_to_cnt_log = 0; // counter for log_cnt
int sine_ind_prev = 0;
/**
* @brief Filling logs.
* @note Заполнение логов: синус, шим, пила.
* @note This called from TIM_CTRL_Handler
*/
void Fill_Logs_with_Data(void)
{
// calc pwm duty from timer
float PWM_Duty;
if(PWM_Get_Mode(&hpwm1, PWM_DC_MODE) == 0) // if sinus need to be written
{
if(PWM_Get_Mode(&hpwm1, PWM_BRIDGE_MODE)) // if its signed sine mode (two channels)
{
if(hpwm1.Duty_Table_Ind < hpwm1.Duty_Table_Size/2) // first half get from channel 1
PWM_Duty = (((float)PWM_Get_Compare1(&hpwm1))/(PWM_Get_Autoreload(&hpwm1)))+1;
else // second half get from channel 2
PWM_Duty = 1-(((float)PWM_Get_Compare2(&hpwm1))/(PWM_Get_Autoreload(&hpwm1)));
}
else // if its unsigned sine mode (single channel)
{ // just get current pwm duty
PWM_Duty = ((float)PWM_Get_Compare1(&hpwm1)/PWM_Get_Autoreload(&hpwm1));
}
}
else // if its dc pwm mode
{ // just get current pwm duty
if(PWM_Get_Mode(&hpwm1, PWM_BRIDGE_MODE)) // if its second channels mode
PWM_Duty = ((float)PWM_Get_Compare2(&hpwm1)/PWM_Get_Autoreload(&hpwm1));
else // if its first channel mode
PWM_Duty = ((float)PWM_Get_Compare1(&hpwm1)/PWM_Get_Autoreload(&hpwm1));
}
// WRITE SINUS TO WHOLE ARRAY
// sine_log[log_ind] = sin_val;
if(PWM_Get_Mode(&hpwm1,PWM_DC_MODE) == 0) // in table mode write PWM Duty (write sine) with scale 1/2 from sin table max value (0xFFFF/2)
sine_log[log_ind] = PWM_Duty*(0x8000-1);
else // in dc mode write PWM Duty (write sine)
sine_log[log_ind] = 0;
// WRITE PWM
if(PWM_Get_Mode(&hpwm1,PWM_DC_MODE)) // in DC mode
{
// write 1 - if log_ind < Size_Of_Period*PWM_Dury
// write 0 - otherwise
pwm_log[log_ind] = (log_ind%(Size_Of_Log/Numb_Of_Peroids) < (Size_Of_Log/Numb_Of_Peroids+1)*hpwm1.PWM_Value/100)? 1: 0;
}
else // in table mode
{
// write fill whole pwm array at one interrupt
int PWM_Period_End_Ind = (Size_Of_Log/Numb_Of_Peroids);
int PWM_Step_End_Ind;
if(PWM_Get_Mode(&hpwm1,PWM_BRIDGE_MODE))
PWM_Step_End_Ind = PWM_Period_End_Ind*fabs(PWM_Duty-1);
else
PWM_Step_End_Ind = PWM_Period_End_Ind*PWM_Duty;
for(int i = 0; i <= PWM_Step_End_Ind; i++)
{
for (int j = 0; j < Numb_Of_Peroids; j++)
pwm_log[i+j*PWM_Period_End_Ind] = 1;
}
for(int i = PWM_Step_End_Ind+1; i < PWM_Period_End_Ind; i++)
for (int j = 0; j < Numb_Of_Peroids; j++)
pwm_log[i+j*PWM_Period_End_Ind] = 0;
}
// WRITE COUNTER
cnt_log[log_ind] = cnt_to_cnt_log;
cnt_to_cnt_log++;
if(cnt_to_cnt_log>=Size_Of_Log/2)
cnt_to_cnt_log = 0;
// INCREMENT AND RESET COUNTER
log_ind++;
if(PWM_Get_Mode(&hpwm1,PWM_DC_MODE) == 0) // if its PWM table mode
{
// SYNCHRONIZE PERIOD OF SIN IN LOG
// (это надо, чтобы данные не съезжали из-за несинхронизированного периода)
// wait until period ended
if(log_ind>Size_Of_Log-1) // if logs are filled
{
if((unsigned)hpwm1.Duty_Table_Ind < sine_ind_prev) // and if new period started
{
log_ind = 0; // reset counter
sine_ind_prev = (unsigned)hpwm1.Duty_Table_Ind;
}
}
// update prev variable only if log currently writing
else
sine_ind_prev = (unsigned)hpwm1.Duty_Table_Ind;
}
else // if its PWM DC mode
{
// if logs are filled
if(log_ind>Size_Of_Log-1)
log_ind = 0;
}
// if its overflow log array size - reset log_ind
if(log_ind>LOG_SIZE-1)
{
log_ind = 0;
sine_ind_prev = (unsigned)hpwm1.Duty_Table_Ind;
}
}
/**
* @brief Update log parameters.
* @note Проверка надо ли обновлять параметры логов, и если надо - обновляет их.
* @note This called from TIM_CTRL_Handler
*/
void Update_Params_For_Log(void)
{
unsigned UpdateLog = 0;
// READ NUMB OF PERIOD IN LOGS
if(Numb_Of_Peroids != log_ctrl[R_LOG_CTRL_LOG_PWM_NUMB])
{
Numb_Of_Peroids = log_ctrl[R_LOG_CTRL_LOG_PWM_NUMB];
// update logs params
UpdateLog = 1;
}
// READ SIZE OF LOGS
if(Size_Of_Log != log_ctrl[R_LOG_CTRL_LOG_SIZE])
{
Size_Of_Log = log_ctrl[R_LOG_CTRL_LOG_SIZE];
// update logs params
UpdateLog = 1;
}
// UPDATE LOG PARAMS
if(UpdateLog)
{
// set logs params
Set_Log_Params();
}
}
/**
* @brief Set up log parameters.
* @note Устанавливает настройки логов и проверяет их на корректность.
*/
void Set_Log_Params(void)
{
// SET LOG PARAMS
log_ind = 0;
Samples_Per_Peroid = TIM_CTRL.sTimFreqHz/hpwm1.PWM_Value;
if(Size_Of_Log > LOG_SIZE) // if its too much data in log
{
Numb_Of_Peroids = (LOG_SIZE/Samples_Per_Peroid);
log_ctrl[R_LOG_CTRL_LOG_SIZE] = Numb_Of_Peroids;
Size_Of_Log = Numb_Of_Peroids*Samples_Per_Peroid;
}
// clear logs arrays
for(int i = Size_Of_Log; i < LOG_SIZE; i++)
{
sine_log[i] = 0;
pwm_log[i] = 0;
cnt_log[i] = 0;
}
}
/**
* @brief reInitialization of control timer.
* @note Перенастраивает таймер согласно принятным настройкам в log_ctrl.
* @note This called from main while
*/
void Control_Timer_ReInit(TIM_SettingsTypeDef *stim)
{
TIM_Base_MspDeInit(&stim->htim);
hpwm1.stim.sTickBaseMHz = PROJSET_MEM->TIM_CTRL_TICKBASE;
TIM_Base_Init(stim);
HAL_TIM_Base_Start_IT(&stim->htim); // timer for sinus
HAL_NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 1, 1);
}
/**
* @brief First initialization of Control Timer.
* @note Первый управляющего таймера. Таймер записывает логи и обновляет параметры ШИМ.
* @note This called from main
*/
void Control_Timer_FirstInit(void)
{
//-------CONTROL TIMER INIT----------
// tim settings
TIM_CTRL.htim.Instance = TIMER_CTRL_INSTANCE;
TIM_CTRL.sTimMode = TIM_IT_MODE;
TIM_CTRL.sTickBaseMHz = PROJSET.TIM_CTRL_TICKBASE;
TIM_CTRL.sTimAHBFreqMHz = PROJSET.TIM_CTRL_AHB_FREQ;
TIM_CTRL.sTimFreqHz = HZ_TIMER_CTRL;
TIM_Base_Init(&TIM_CTRL);
HAL_NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 1, 1);
HAL_TIM_Base_Start_IT(&TIM_CTRL.htim); // timer for sinus
// FILL TIME ARRAY WITH TIME
for(int i = 0; i <= R_TIME_LOG_QNT; i++)
time_log[i] = i;
}
//-------------------------------------------------------------------
//------------------------HANDLERS FUNCTIONS-------------------------
//-------------CONTROL TIMER---------------
void TIM8_UP_TIM13_IRQHandler(void)
{
/* TIM_CTRL_Handler */
Trace_CTRL_TIM_Enter();
HAL_TIM_IRQHandler(&TIM_CTRL.htim);
Fill_Logs_with_Data();
Update_Params_For_Log();
Update_Params_For_PWM(&hpwm1);
WriteSettingsToMem();
Trace_CTRL_TIM_Exit();
}

View File

@@ -0,0 +1,52 @@
#ifndef __CONTROL_H_
#define __CONTROL_H_
#include "periph_general.h"
#include "modbus.h"
#include "math.h"
#include "settings.h"
#include "i2c_lcd.h"
#define M_PI 3.14159265358979323846 /* pi */
extern TIM_SettingsTypeDef TIM_CTRL;
//---------------------this called from TIM_CTRL_Handler()-----------------------
/**
* @brief Update log parameters.
* @note Проверка надо ли обновлять параметры логов, и если надо - обновляет их.
* @note This called from TIM_CTRL_Handler
*/
void Update_Params_For_Log(void);
/**
* @brief Filling logs.
* @note заполнение логов: синус, шим, пила.
* @note this called from TIM_CTRL_Handler
*/
void Fill_Logs_with_Data(void);
/**
* @brief Set up log parameters.
* @note Устанавливает настройки логов и проверяет их на корректность.
*/
void Set_Log_Params(void);
// this called from main while(1)
/**
* @brief reInitialization of control timer.
* @param stim - указатель на настройки таймера.
* @note Перенастраивает таймер согласно принятным настройкам в log_ctrl.
* @note This called from main while
*/
void Control_Timer_ReInit(TIM_SettingsTypeDef *stim);
/**
* @brief First initialization of Control Timer.
* @note Первый управляющего таймера. Таймер записывает логи и обновляет параметры ШИМ.
* @note This called from main
*/
void Control_Timer_FirstInit(void);
/**
* @brief First initialization of Encoder Timer.
* @note This called from main
*/
void EncoderFirstInit(void);
#endif // __CONTROL_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,471 @@
/********************************MODBUS*************************************
Данный файл содержит объявления базовых функции и дефайны для реализации
MODBUS.
Данный файл необходимо подключить в rs_message.h. После подключать rs_message.h
к основному проекту.
***************************************************************************/
#ifndef __PWM_H_
#define __PWM_H_
#include "control.h"
extern uint32_t sin_table[SIN_TABLE_SIZE_MAX];
#define int_to_percent(_int_) ((float)_int_/100)
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
//----------------------------PWM HANDLE----------------------------//
/**
* @brief Calc duration of maximum pulse in ticks.
* @param _hpwm_ - указатель на хендл pwm.
* @return _val_ - количество тиков кратчайшего импульса.
*/
#define PWM_Calc_Max_Duty(_hpwm_) ((_hpwm_)->PWM_MaxPulseDur/(_hpwm_)->stim.sTickBaseMHz)
/**
* @brief Calc duration of minimum pulse in ticks.
* @param _hpwm_ - указатель на хендл pwm.
* @return _val_ - количество тиков кратчайшего импульса.
*/
#define PWM_Calc_Min_Duty(_hpwm_) ((_hpwm_)->PWM_MinPulseDur/(_hpwm_)->stim.sTickBaseMHz)
/**
* @brief Calc Scale Koef for Table & AUTORELOAD REGISTER
* @param _hpwm_ - указатель на хендл pwm.
* @param _scale_ - верхняя граница диапазона значений.
* @return _koef_ - коэффициент для масштабирования.
* @note Данный макрос рассчитывает коэффициент для приведения значений с диапазоном [0,_scale_]
к регистру автозагрузки с диапазоном [min, max], где min, max - минимальная и максимальная длительность импульса в тактах.
*/
#define PWM_Calc_Duty_Scale(_hpwm_, _scale_) ((float)(PWM_Calc_Max_Duty(_hpwm_)-PWM_Calc_Min_Duty(_hpwm_))/(_scale_))
/**
* @brief Get Table Element Scaled corresponding to TIM ARR register
* @param _hpwm_ - указатель на хендл pwm.
* @param _ind_ - номер элемента из таблицы скважностей.
* @return _val_ - масштабированный под регистры таймера значение.
* @note Если задана минимальная длительность импульса в тактах n,
то регистр ARR заполняется так, что диапазон его значений будет [n, ARR-n]
*/
#define PWM_Get_Table_Element_Unsigned(_hpwm_,_ind_) (*((_hpwm_)->pDuty_Table_Origin+_ind_)*((_hpwm_)->Duty_Table_Scale))
/**
* @brief Get Table Element Scaled and Shifted corresponding to TIM ARR register
* @param _hpwm_ - указатель на хендл pwm.
* @param _ind_ - номер элемента из таблицы скважностей.
* @return _val_ - масштабированный под регистры таймера значение.
* @note По сути такая же как PWM_Get_Table_Element_Unsigned но добавляется сдвиг на одну амплитуду для учитывания знака.
(если точнее, то сдвиг добавляется для компенсации сдвига, который имитирует знак)
* @note 0x8000*(_hpwm_)->Duty_Table_Scale - т.к. первая полуволна находится в диапазоне (0x8000-0xFFFF) вычитаем константу 0x8000 с масштабированием
*/
#define PWM_Get_Table_Element_Signed(_hpwm_,_ind_) ((int)(*((_hpwm_)->pDuty_Table_Origin+_ind_)*((_hpwm_)->Duty_Table_Scale))-0x8000*(_hpwm_)->Duty_Table_Scale)
/**
* @brief Create pointer to slave PWM from pointer to void in PWM_HandleTypeDef.
* @param _hpwm_ - указатель на хендл pwm.
* @param _slavepwm_ - имя слейв pwm.
* @return _pslavepwm_ - указатель на структуру PWM_SlaveHandleTypeDef.
*/
#define PWM_Set_pSlaveHandle(_hpwm_,_slavepwm_) ((PWM_SlaveHandleTypeDef *)_hpwm_->_slavepwm_)
/**
* @brief Copy setting from master TIM_SettingsTypeDef to slave TIM_SettingsTypeDef.
* @param _hpwm_ - указатель на хендл pwm.
* @return _set_ - имя настройки.
*/
#define PWM_Slave_CopyTimSetting(_hspwm_, _set_) ((_hspwm_)->stim._set_ = (_hspwm_)->hMasterPWM->stim._set_)
//---------------------------TIMER REGS----------------------------//
/**
* @brief Set PWM autoreload value (max duty value).
* @param _hpwm_ - указатель на хендл pwm.
* @param _val_ - значение, которое нужно записать в Compare.
*/
#define PWM_Get_Autoreload(_hpwm_) __HAL_TIM_GET_AUTORELOAD(&((_hpwm_)->stim.htim))
/**
* @brief Get PWM Duty on corresponding channel.
* @param _hpwm_ - указатель на хендл pwm.
* @param _val_ - значение, которое нужно записать в Compare.
*/
#define PWM_Get_Compare1(_hpwm_) __HAL_TIM_GET_COMPARE(&((_hpwm_)->stim.htim), (_hpwm_)->PWM_Channel1)
#define PWM_Get_Compare2(_hpwm_) __HAL_TIM_GET_COMPARE(&((_hpwm_)->stim.htim), (_hpwm_)->PWM_Channel2)
/**
* @brief Set PWM Duty on corresponding channel.
* @param _hpwm_ - указатель на хендл pwm.
* @param _val_ - значение, которое нужно записать в Compare.
*/
#define PWM_Set_Compare1(_hpwm_, _val_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), (_hpwm_)->PWM_Channel1, (_val_))
#define PWM_Set_Compare2(_hpwm_, _val_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), (_hpwm_)->PWM_Channel2, (_val_))
/**
* @brief Set PWM Duty From PWM_Value Percent
* @param _hpwm_ - указатель на хендл pwm.
* @param _channel_ - канал для выставления скважности.
*/
#define PWM_Set_Duty_From_Value(_hpwm_, _channel_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, ((_hpwm_)->PWM_Value/100)*(PWM_Get_Autoreload(_hpwm_)+1))
/**
* @brief Set PWM Duty From PWM_DutyBridge Percent
* @param _hpwm_ - указатель на хендл pwm.
* @param _channel_ - канал для выставления скважности.
*/
#define PWM_Set_Duty_From_DutyBridge(_hpwm_, _channel_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, ((_hpwm_)->PWM_DutyBridge/100)*(PWM_Get_Autoreload(_hpwm_)+1))
/**
* @brief Set PWM Duty From table
* @param _hpwm_ - указатель на хендл pwm.
* @param _channel_ - канал для выставления скважности.
* @param _ind_ - номер элемента из таблицы скважностей.
*/
#define PWM_Set_Duty_From_Table(_hpwm_, _channel_, _ind_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, (PWM_Get_Table_Element_Unsigned((_hpwm_), (_ind_))+1))
/**
* @brief Set PWM Duty From PWM_Value Percent
* @param _hpwm_ - указатель на хендл pwm.
* @param _channel_ - канал для выставления скважности.
*/
#define PWM_Set_SlaveDuty_From_Value(_hpwm_, _channel_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, ((_hpwm_)->hMasterPWM->PWM_Value/100)*(PWM_Get_Autoreload(_hpwm_)+1))
/**
* @brief Set PWM Duty From PWM_DutyBridge Percent
* @param _hpwm_ - указатель на хендл pwm.
* @param _channel_ - канал для выставления скважности.
*/
#define PWM_Set_SlaveDuty_From_DutyBridge(_hpwm_, _channel_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, ((_hpwm_)->hMasterPWM->PWM_DutyBridge/100)*(PWM_Get_Autoreload(_hpwm_)+1))
/**
* @brief Set PWM Duty From table
* @param _hpwm_ - указатель на хендл pwm.
* @param _channel_ - канал для выставления скважности.
* @param _ind_ - номер элемента из таблицы скважностей.
*/
#define PWM_Set_SlaveDuty_From_Table(_hpwm_, _channel_, _ind_) __HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, (PWM_Get_Table_Element_Unsigned((_hpwm_)->hMasterPWM, (_ind_))+1))
// MODE DEFINES
#define PWM_DC_MODE_Pos (0) // 0 - PWM has Sine form duty, 1 - PWM has DC duty
#define PWM_BRIDGE_MODE_Pos (1) // 0 - PWM generated only on one channel (@ref PWM_ACTIVECHANNEL_MODE)
// 1 - PWM generated at two channels of phase (@ref PWM_PHASE_MODE)
#define PWM_PHASE_MODE_Pos (2) // 0 - PWM generated only at phase "A", 1 - PWM generated and three phase "A", "B", "C"
#define PWM_ACTIVECHANNEL_MODE_Pos (3) // 0 - One channel PWM doesnt generated, 1 - PWM generated on corresponting channel № "PWM_ACTIVECHANNEL_MODE"
#define PWM_DC_MODE (1<<(PWM_DC_MODE_Pos)) // 0 - PWM has Sine form duty, 1 - PWM has DC duty
#define PWM_BRIDGE_MODE (1<<(PWM_BRIDGE_MODE_Pos)) // 0 - PWM generated only on one channel (@ref PWM_ACTIVECHANNEL_MODE)
// 1 - PWM generated at two channels of phase (@ref PWM_PHASE_MODE)
#define PWM_PHASE_MODE (1<<(PWM_PHASE_MODE_Pos)) // 0 - PWM generated only at phase "A", 1 - PWM generated and three phase "A", "B", "C"
#define PWM_ACTIVECHANNEL_MODE (0x7<<(PWM_ACTIVECHANNEL_MODE_Pos)) // 0 - One channel PWM doesnt generated, 1 - PWM generated on corresponting channel № "PWM_ACTIVECHANNEL_MODE"
#define PWM_ACTIVECHANNEL_DISABLE (0x0<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_ACTIVECHANNEL_A0 (0x1<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_ACTIVECHANNEL_A1 (0x2<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_ACTIVECHANNEL_B0 (0x3<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_ACTIVECHANNEL_B1 (0x4<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_ACTIVECHANNEL_C0 (0x5<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_ACTIVECHANNEL_C1 (0x6<<(PWM_ACTIVECHANNEL_MODE_Pos))
#define PWM_Get_Mode(_hpwm_, _mode_) ((_hpwm_)->sPWM_Mode&(_mode_))
/* Structure for PWM modes */
typedef enum
{
// SINE MODES
PWM_SINE_SINGLE = 0, /* set pwm duty from table with PWM_Value Hz */
PWM_SINE_BRIDGE = PWM_BRIDGE_MODE, /* set pwm duty from table with PWM_Value Hz on two channels (positive and negative halfes) */
PWM_SINE_3PHASE = PWM_BRIDGE_MODE|PWM_PHASE_MODE, /* set pwm table duty on three phase with PWM_Value Hz */
// DC MODES
PWM_DC_SINGLE = PWM_DC_MODE, /* set pwm duty PWM_Value (in percent) on one channel (@ref PWM_ACTIVECHANNEL_MODE) */
PWM_DC_BRIDGE = PWM_DC_MODE|PWM_BRIDGE_MODE, /* set pwm duty PWM_DutyBridge (in percent) on two channel with PWM_Value Hz */
PWM_DC_3PHASE = PWM_DC_MODE|PWM_BRIDGE_MODE|PWM_PHASE_MODE, /* set pwm PWM_DutyBridge duty on three phase with PWM_Value Hz, with requested shift */
// Variables of signel channel modes
PWM_SINE_SINGLE_A0 = PWM_ACTIVECHANNEL_A0, /* set sine pwm on Phase A channel 0 */
PWM_SINE_SINGLE_A1 = PWM_ACTIVECHANNEL_A1, /* set sine pwm on Phase A channel 1 */
PWM_SINE_SINGLE_B0 = PWM_ACTIVECHANNEL_B0, /* set sine pwm on Phase B channel 0 */
PWM_SINE_SINGLE_B1 = PWM_ACTIVECHANNEL_B1, /* set sine pwm on Phase B channel 1 */
PWM_SINE_SINGLE_C0 = PWM_ACTIVECHANNEL_C0, /* set sine pwm on Phase C channel 0 */
PWM_SINE_SINGLE_C1 = PWM_ACTIVECHANNEL_C1, /* set sine pwm on Phase C channel 1 */
PWM_SINE_BRIDGE_A0 = PWM_DC_MODE|PWM_ACTIVECHANNEL_A0, /* set DC pwm on Phase A channel 0) */
PWM_SINE_BRIDGE_A1 = PWM_DC_MODE|PWM_ACTIVECHANNEL_A1, /* set DC pwm on Phase A channel 1) */
PWM_SINE_BRIDGE_B0 = PWM_DC_MODE|PWM_ACTIVECHANNEL_B0, /* set DC pwm on Phase B channel 0) */
PWM_SINE_BRIDGE_B1 = PWM_DC_MODE|PWM_ACTIVECHANNEL_B1, /* set DC pwm on Phase B channel 1) */
PWM_SINE_BRIDGE_C0 = PWM_DC_MODE|PWM_ACTIVECHANNEL_C0, /* set DC pwm on Phase C channel 0) */
PWM_SINE_BRIDGE_C1 = PWM_DC_MODE|PWM_ACTIVECHANNEL_C1, /* set DC pwm on Phase C channel 1) */
}PWM_ModeTypeDef;
/**
* @brief Structure for PWM modbus coils.
*/
typedef struct // PWM_ModeCoilsTypeDef
{
unsigned reserved:1; /* reserved bits */
unsigned DC:1; /* DC mode: PWM duty, Sine mode: frequency*/
unsigned BRIDGE:1; /* Bridge mode: */
unsigned PHASE:1; /* minimum pulse duration for PWM in us*/
unsigned POLARITY:1; /* minimum pulse duration for PWM in us*/
unsigned ACTIVECHANNEL:3; /* minimum pulse duration for PWM in us*/
}PWM_ModeCoilsTypeDef;
/**
* @brief Structure for PWM modbus registers.
*/
typedef struct // PWM_ModeRegsTypeDef
{
uint16_t Value; /* DC mode: PWM duty, Table mode: frequency*/
uint16_t TIMFreqHz; /* frequency of pwm timer */
uint16_t DutyBridge; /* frequency of pwm timer */
uint16_t MaxPulseDur; /* maximum pulse duration for PWM in us*/
uint16_t MinPulseDur; /* minimum pulse duration for PWM in us*/
uint16_t DeadTime; /* dead-Time between switches half waves (channels) in us */
uint16_t TableSize; /* */
}PWM_ModeRegsTypeDef;
/**
* @brief Structure for PWM config.
*/
typedef struct // PWM_ConfigTypeDef
{
PWM_ModeCoilsTypeDef *PWM_Mode;
PWM_ModeRegsTypeDef *PWM_Settings;
}PWM_ConfigTypeDef;
typedef struct {
/* Controller gains */
float Kp;
float Ki;
float Kd;
/* Derivative low-pass filter time constant */
float tau;
/* Output limits */
float limMin;
float limMax;
/* Integrator limits */
float limMinInt;
float limMaxInt;
/* Sample time (in seconds) */
float SampleT;
/* Controller "memory" */
float integrator;
float prevError; /* Required for integrator */
float differentiator;
float prevMeasurement; /* Required for differentiator */
/* input */
float setpoint;
} PWM_RampHandleTypeDef;
/**
* @brief Handle for PWM.
* @note Prefixes: h - handle, s - settings, f - flag
*/
typedef struct // PWM_HandleTypeDef
{
/* PWM VARIABLES */
PWM_ModeTypeDef sPWM_Mode; /* PWM current mode */
PWM_ConfigTypeDef sPWM_Config; /* PWM modbus config */
float PWM_Value; /* DC mode: PWM duty, Table mode: frequency*/
float PWM_DutyBridge; /* Duty for DC bridge mode */
uint32_t PWM_MaxPulseDur; /* maximum pulse duration for PWM in us*/
uint32_t PWM_MinPulseDur; /* minimum pulse duration for PWM in us*/
uint32_t PWM_DeadTime; /* dead-Time between switches half waves (channels) in us */
PWM_RampHandleTypeDef hramp; /* handle for ramp */
uint8_t PWM_enHardware; /* enable PWM output on transistor */
/* SETTINGS FOR TIMER */
TIM_SettingsTypeDef stim; /* settings for TIM */
TIM_OC_InitTypeDef sConfigOC; /* settings for oc channel */
unsigned fActiveChannel; /* flag for active oc channel: 0 - first channel, 1 - second channel */
uint16_t PWM_Channel1; /* instance of first channel */
uint16_t PWM_Channel2; /* instance of second channel */
/* VARIABLES FOR TABLE DUTY PARAMETERS */
uint32_t *pDuty_Table_Origin; /* pointer to table of pwm duties */
uint32_t Duty_Table_Size; /* size of duty table */
float Duty_Table_Ind; /* current ind of duty table */
float Duty_Table_Scale; /* scale for TIM ARR register */
/* SETTIGNS FOR PWM OUTPUT */
GPIO_TypeDef *GPIOx; /* GPIO port for PWM output */
uint32_t GPIO_PIN_X1; /* GPIO pin for PWM output */
uint32_t GPIO_PIN_X2; /* GPIO pin for PWM output (second half wave) */
/* SLAVES PWM */
void *hpwm2;
void *hpwm3;
}PWM_HandleTypeDef;
extern PWM_HandleTypeDef hpwm1;
/**
* @brief Handle for Slave PWM.
* @note Prefixes: h - handle, s - settings, f - flag
*/
typedef struct // PWM_SlaveHandleTypeDef
{
/* MASTER PWM*/
PWM_HandleTypeDef *hMasterPWM; /* master pwm handle */
/* SETTINGS FOR TIMER */
TIM_SettingsTypeDef stim; /* slave tim handle */
unsigned fActiveChannel; /* flag for active oc channel: 0 - first channel, 1 - second channel */
uint16_t PWM_Channel1; /* instance of first channel */
uint16_t PWM_Channel2; /* instance of second channel */
/* VARIABLES FOR TABLE DUTY PARAMETERS */
float Duty_Shift_Ratio; /* Ratio of table shift: 0.5 shift - shift = Table_Size/2 */
/* SETTIGNS FOR PWM OUTPUT */
GPIO_TypeDef *GPIOx; /* GPIO port for PWM output */
uint32_t GPIO_PIN_X1; /* GPIO pin for PWM output */
uint32_t GPIO_PIN_X2; /* GPIO pin for PWM output (second half wave) */
}PWM_SlaveHandleTypeDef;
extern PWM_SlaveHandleTypeDef hpwm2;
extern PWM_SlaveHandleTypeDef hpwm3;
//--------------------------------PWM FUNCTIONS----------------------------------
/**
* @brief reInitialization of PWM TIM.
* @param hpwm - указатель на хендл ШИМ.
* @note Перенастраивает таймер согласно принятным настройкам в pwm_ctrl.
*/
void PWM_Sine_ReInit(PWM_HandleTypeDef *hpwm);
/**
* @brief Initialization of Slave PWM TIM.
* @param hspwm - указатель на хендл слейв ШИМ.
* @note Вызывает функции инициализации и включения слейв ШИМ.
*/
void PWM_SlavePhase_Init(PWM_SlaveHandleTypeDef *hspwm);
/**
* @brief reInitialization of Slave PWM TIM.
* @param hspwm - указатель на хендл слейв ШИМ.
* @note Перенастраивает таймер согласно принятным настройкам в pwm_ctrl.
*/
void PWM_SlavePhase_reInit(PWM_SlaveHandleTypeDef *hspwm);
/**
* @brief Filling table with one period of sinus values.
* @param hpwm - указатель на хендл ШИМ.
* @param table_size - размер таблицы.
* @note Формирует таблицу синусов размером table_size.
*/
uint32_t PWM_Fill_Sine_Table(PWM_HandleTypeDef *hpwm, uint32_t table_size);
/**
* @brief Calc and update new Duty Table Scale.
* @param hpwm - указатель на хендл ШИМ.
* @note Используется, когда изменяется значение регистра ARR.
*/
void PWM_Update_DutyTableScale(PWM_HandleTypeDef *hpwm);
//---------------------this called from TIM_PWM_Handler()------------------------
// MASTER PWM FUNCTIONS
/**
* @brief PWM Handler.
* @param hpwm - указатель на хендл ШИМ.
* @note Управляет скважность ШИМ в режиме PWM_TABLE.
* @note This called from TIM_PWM_Handler
*/
void PWM_Handler(PWM_HandleTypeDef *hpwm);
/**
* @brief .
* @param hspwm - указатель на хендл слейв ШИМ.
* @param sin_ind - индекс таблицы для Мастер ШИМ.
* @note Индекс для свейл ШИМ расчитывается в самой функции.
*/
void PWM_Sine_Bridge_Mode(PWM_HandleTypeDef *hpwm, uint16_t rotate_ind_A, uint16_t rotate_ind_B, uint16_t rotate_ind_C);
/**
* @brief .
* @param hspwm - указатель на хендл слейв ШИМ.
* @param sin_ind - индекс таблицы для Мастер ШИМ.
* @note Индекс для свейл ШИМ расчитывается в самой функции.
*/
void PWM_SingleChannel_Mode(PWM_HandleTypeDef *hpwm, uint16_t rotate_ind_A, uint8_t SineOrDC);
/**
* @brief .
* @param hspwm - указатель на хендл слейв ШИМ.
* @param sin_ind - индекс таблицы для Мастер ШИМ.
* @note Индекс для свейл ШИМ расчитывается в самой функции.
*/
void PWM_DC_Bridge_Mode(PWM_HandleTypeDef *hpwm, uint16_t rotate_ind_A, uint16_t rotate_ind_B, uint16_t rotate_ind_C);
/**
* @brief Getting ind for Duty Table.
* @param hpwm - указатель на хендл ШИМ.
* @param FreqTIM - частота таймера ШИМ.
* @note Рассчитывает индекс для таблицы скважностей.
* PWM_Value в hpwm - частота с которой эта таблица должна выводиться на ШИМ
* @note This called from TIM_PWM_Handler
*/
uint32_t PWM_Get_Duty_Table_Ind(PWM_HandleTypeDef *hpwm, float FreqTIM);
/**
* @brief Create Dead Time when switches channels.
* @param hpwm - указатель на хендл ШИМ.
* @param LocalDeadTimeCnt - указатель на переменную для отсчитывания дедтайма.
* @param LocalActiveChannel - указатель на переменную для отслеживания смены канала.
*/
void PWM_CreateDeadTime(PWM_HandleTypeDef *hpwm, float *LocalDeadTimeCnt, unsigned *LocalActiveChannel);
// SLAVE PWM FUNCTIONS
/**
* @brief Set Duty from table on Slave PWM at one channel by sin_ind of the Master PWM.
* @param hspwm - указатель на хендл слейв ШИМ.
* @param sin_ind - индекс таблицы для Мастер ШИМ.
* @note Индекс для свейл ШИМ расчитывается в самой функции.
*/
uint16_t PWM_SlavePhase_Calc_TableInd(PWM_SlaveHandleTypeDef *hspwm, uint16_t sin_ind);
/**
* @brief Check is all Slave channels works properly.
* @param hspwm - указатель на хендл слейв ШИМ.
* @note Проверка работает ли только один из каналов, и проверка чтобы CCRx <= ARR
* @note В мастере проверка происходит напрямую в PWM_Handler.
*/
void PWM_SlavePhase_Check_Channels(PWM_SlaveHandleTypeDef *hspwm);
/**
* @brief Create Dead Time for Slave PWM when switches channels.
* @param hspwm - указатель на хендл слейв ШИМ.
* @param LocalDeadTimeCnt - указатель на переменную для отсчитывания дедтайма.
* @param LocalActiveChannel - указатель на переменную для отслеживания смены канала.
* @note Аналог функции PWM_CreateDeadTime но для слейв ШИМов.
*/
void PWM_SlavePhase_CreateDeadTime(PWM_SlaveHandleTypeDef *hspwm, float *LocalDeadTimeCnt, unsigned *LocalActiveChannel);
//---------------------this called from TIM_CTRL_Handler()-----------------------
/**
* @brief Update PWM parameters.
* @param hpwm - указатель на хендл ШИМ.
* @note Проверка надо ли обновлять параметры ШИМ, и если надо - обновляет их.
* @note This called from TIM_CTRL_Handler
*/
void Update_Params_For_PWM(PWM_HandleTypeDef *hpwm);
/**
* @brief PID for ramp.
* @param hpwm - указатель на хендл ШИМ.
* @note ПИД-регулятор, который управляет скважностью ШИМ и не дает её изменяться резко.
*/
void PWM_Ramp_ControlPWMValue(PWM_HandleTypeDef *hpwm);
/**
* @brief Reset PID for ramp.
* @param hpwm - указатель на хендл ШИМ.
* @note Сбрасывает переменные ПИД-регулятора, чтобы потом его запустить "с чистого листа".
*/
void PWM_Ramp_Reset(PWM_HandleTypeDef *hpwm);
//---------------------------this called from main()-----------------------------
/**
* @brief First set up of PWM Two Channel.
* @note Первый инит ШИМ. Заполняет структуры и инициализирует таймер для генерации синуоидального ШИМ.
* Скважность ШИМ меняется по закону синусоиды, каждый канал генерирует свой полупериод синуса (от -1 до 0 И от 0 до 1)
* ШИМ генерируется на одном канале.
* @note This called from main OR by setted coil
*/
void PWM_Sine_FirstInit(void);
#endif // __PWM_H_

View File

@@ -0,0 +1,220 @@
#include "control.h"
ProjectSettings_TypeDef PROJSET;
uint32_t PageError = 0x00;
uint8_t UpdateSettings = 0;
void WriteSettingsToMem(void)
{
HAL_FLASH_Unlock();
CheckSettingsInFLASH();
if(CheckIsSettingsValid(&PROJSET)) // if new settings are invalid
PROJSET = *PROJSET_MEM; // take the old settings from mem
else // if new settings are valid
SetFlagUpdateSettingsInMem(); // save the new settings in mem (set flag to do this)
HAL_FLASH_Lock();
}
void SetFlagUpdateSettingsInMem(void)
{
UpdateSettings = 0;
// MODBUS settings
if(PROJSET_MEM->MB_DEVICE_ID != PROJSET.MB_DEVICE_ID)
UpdateSettings = 1;
if(PROJSET_MEM->MB_SPEED != PROJSET.MB_SPEED)
UpdateSettings = 1;
if(PROJSET_MEM->MB_GPIOX != PROJSET.MB_GPIOX)
UpdateSettings = 1;
if(PROJSET_MEM->MB_GPIO_PIN_RX != PROJSET.MB_GPIO_PIN_RX)
UpdateSettings = 1;
if(PROJSET_MEM->MB_GPIO_PIN_RX != PROJSET.MB_GPIO_PIN_RX)
UpdateSettings = 1;
if(PROJSET_MEM->MB_MAX_TIMEOUT != PROJSET.MB_MAX_TIMEOUT)
UpdateSettings = 1;
// PWM settings
if(PROJSET_MEM->TIM_PWM_TICKBASE != PROJSET.TIM_PWM_TICKBASE)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM_AHB_FREQ != PROJSET.TIM_PWM_AHB_FREQ)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL1 != PROJSET.TIM_PWM1_TIM_CHANNEL1)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL2 != PROJSET.TIM_PWM1_TIM_CHANNEL2)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM1_GPIOx != PROJSET.TIM_PWM1_GPIOx)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X1 != PROJSET.TIM_PWM1_GPIO_PIN_X1)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X2 != PROJSET.TIM_PWM1_GPIO_PIN_X2)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM2_INSTANCE != PROJSET.TIM_PWM2_INSTANCE)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL1 != PROJSET.TIM_PWM2_TIM_CHANNEL1)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL2 != PROJSET.TIM_PWM2_TIM_CHANNEL2)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM2_GPIOx != PROJSET.TIM_PWM2_GPIOx)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X1 != PROJSET.TIM_PWM2_GPIO_PIN_X1)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X2 != PROJSET.TIM_PWM2_GPIO_PIN_X2)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM3_INSTANCE != PROJSET.TIM_PWM3_INSTANCE)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL1 != PROJSET.TIM_PWM3_TIM_CHANNEL1)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL2 != PROJSET.TIM_PWM3_TIM_CHANNEL2)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM3_GPIOx != PROJSET.TIM_PWM3_GPIOx)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X1 != PROJSET.TIM_PWM3_GPIO_PIN_X1)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X2 != PROJSET.TIM_PWM3_GPIO_PIN_X2)
UpdateSettings = 1;
// CTRL settings
if(PROJSET_MEM->TIM_CTRL_TICKBASE != PROJSET.TIM_CTRL_TICKBASE)
UpdateSettings = 1;
if(PROJSET_MEM->TIM_CTRL_AHB_FREQ != PROJSET.TIM_CTRL_AHB_FREQ)
UpdateSettings = 1;
}
void UpdateSettingsInMem(void)
{
if(UpdateSettings)
{
FLASH_EraseInitTypeDef EraseInitStruct;
PageError = 0x00;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;// erase pages
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Sector = FLASH_SECTOR_4; //first sector for erase
EraseInitStruct.NbSectors = 1;// num of sector that need to be erased
HAL_FLASH_Unlock();
HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
/* Wait for last operation to be completed */
if(FLASH_WaitForLastOperation((uint32_t)50000U) == HAL_OK)
{
/* If the previous operation is completed, proceed to program the new data */
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
FLASH->CR |= FLASH_PSIZE_WORD;
FLASH->CR |= FLASH_CR_PG;
*PROJSET_MEM = PROJSET; // save the new settings in mem
}
HAL_FLASH_Lock();
UpdateSettings = 0;
}
}
void FillSettingsWithDefines(void)
{
// rewrite all setting corresponding to defines
FLASH_EraseInitTypeDef EraseInitStruct;
PageError = 0x00;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;// erase pages
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Sector = FLASH_SECTOR_4; //first sector for erase
EraseInitStruct.NbSectors = 1;// num of sector that need to be erased
HAL_FLASH_Unlock();
HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
// MODBUS settings
FLASH_WRITE_SETTING(PROJSET_MEM->MB_DEVICE_ID, MODBUS_DEVICE_ID);
FLASH_WRITE_SETTING(PROJSET_MEM->MB_SPEED, MODBUS_SPEED);
FLASH_WRITE_SETTING(PROJSET_MEM->MB_GPIOX, (uint32_t)MODBUS_GPIOX);
FLASH_WRITE_SETTING(PROJSET_MEM->MB_GPIO_PIN_RX, MODBUS_GPIO_PIN_RX);
FLASH_WRITE_SETTING(PROJSET_MEM->MB_GPIO_PIN_TX, MODBUS_GPIO_PIN_TX);
FLASH_WRITE_SETTING(PROJSET_MEM->MB_MAX_TIMEOUT, MODBUS_MAX_TIMEOUT);
FLASH_WRITE_SETTING(PROJSET_MEM->MB_TIM_AHB_FREQ, MODBUS_TIM_AHB_FREQ);
// PWM settings
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM_TICKBASE, TIMER_PWM_TICKBASE);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM_AHB_FREQ, TIMER_PWM_AHB_FREQ);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL1, TIMER_PWM1_TIM_CHANNEL1);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_TIM_CHANNEL2, TIMER_PWM1_TIM_CHANNEL2);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_GPIOx, (uint32_t)TIMER_PWM1_GPIOx);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X1, TIMER_PWM1_GPIO_PIN_X1);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM1_GPIO_PIN_X2, TIMER_PWM1_GPIO_PIN_X2);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_INSTANCE, (uint32_t)TIMER_PWM2_INSTANCE);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL1, TIMER_PWM2_TIM_CHANNEL1);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_TIM_CHANNEL2, TIMER_PWM2_TIM_CHANNEL2);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_GPIOx, (uint32_t)TIMER_PWM2_GPIOx);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X1, TIMER_PWM2_GPIO_PIN_X1);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM2_GPIO_PIN_X2, TIMER_PWM2_GPIO_PIN_X2);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_INSTANCE, (uint32_t)TIMER_PWM3_INSTANCE);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL1, TIMER_PWM3_TIM_CHANNEL1);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_TIM_CHANNEL2, TIMER_PWM3_TIM_CHANNEL2);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_GPIOx, (uint32_t)TIMER_PWM3_GPIOx);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X1, TIMER_PWM3_GPIO_PIN_X1);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_PWM3_GPIO_PIN_X2, TIMER_PWM3_GPIO_PIN_X2);
// CTRL settings
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_CTRL_TICKBASE, TIMER_CTRL_TICKBASE);
FLASH_WRITE_SETTING(PROJSET_MEM->TIM_CTRL_AHB_FREQ, TIMER_CTRL_AHB_FREQ);
HAL_FLASH_Lock();
}
void CheckSettingsInFLASH(void)
{
if(CheckIsSettingsValid(PROJSET_MEM))
FillSettingsWithDefines();
PROJSET = *PROJSET_MEM;
}
int CheckIsSettingsValid(ProjectSettings_TypeDef *set_struct)
{
// if some of setting are missing
// chech MODBUS
if((!IS_UART_BAUDRATE(set_struct->MB_SPEED) || (set_struct->MB_SPEED ) == 0) ||
(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->MB_GPIOX)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->MB_GPIO_PIN_TX)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->MB_GPIO_PIN_RX)) ||
((set_struct->MB_TIM_AHB_FREQ) == 0))
{
return 1;
}
// chech control tim
if((set_struct->TIM_CTRL_AHB_FREQ) == 0)
{
return 1;
}
// chech PWM tims
if((set_struct->TIM_PWM_AHB_FREQ) == 0 ||
(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->TIM_PWM1_GPIOx)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM1_GPIO_PIN_X1)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM1_GPIO_PIN_X2)) ||
(!IS_TIM_CHANNELS(set_struct->TIM_PWM1_TIM_CHANNEL1)) ||
(!IS_TIM_CHANNELS(set_struct->TIM_PWM1_TIM_CHANNEL2)) ||
(!IS_TIM_INSTANCE((TIM_TypeDef *)set_struct->TIM_PWM2_INSTANCE)) ||
(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->TIM_PWM2_GPIOx)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM2_GPIO_PIN_X1)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM2_GPIO_PIN_X2)) ||
(!IS_TIM_CHANNELS(set_struct->TIM_PWM2_TIM_CHANNEL1)) ||
(!IS_TIM_CHANNELS(set_struct->TIM_PWM2_TIM_CHANNEL2)) ||
(!IS_TIM_INSTANCE((TIM_TypeDef *)set_struct->TIM_PWM3_INSTANCE)) ||
(!IS_GPIO_ALL_INSTANCE((GPIO_TypeDef *)set_struct->TIM_PWM3_GPIOx)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM3_GPIO_PIN_X1)) ||
(!IS_GPIO_PIN((GPIO_TypeDef *)set_struct->TIM_PWM3_GPIO_PIN_X2)) ||
(!IS_TIM_CHANNELS(set_struct->TIM_PWM3_TIM_CHANNEL1)) ||
(!IS_TIM_CHANNELS(set_struct->TIM_PWM3_TIM_CHANNEL2)))
{
return 1;
}
return 0;
}

View File

@@ -0,0 +1,160 @@
/********************************MODBUS*************************************
Данный файл содержит объявления базовых функции и дефайны для реализации
MODBUS.
Данный файл необходимо подключить в rs_message.h. После подключать rs_message.h
к основному проекту.
***************************************************************************/
#ifndef __PROJ_SETTINGS_H_
#define __PROJ_SETTINGS_H_
#include "stm32f4xx_hal.h"
//--------DEFINES FOR SETTING OF SETTINGS-----------
#define SETTINGS_FLASH_ADDRESS_SHIFT (0x10000)
#define SETTINGS_FLASH_ADDRESS (FLASH_BASE + SETTINGS_FLASH_ADDRESS_SHIFT)
#define EEPROM_BASE
#define SETTINGS_EEPROM_ADDRESS_SHIFT
#define SETTINGS_EEPROM_ADDRESS (EEPROM_BASE + SETTINGS_EEPROM_ADDRESS_SHIFT)
#ifdef USE_EEPROM
#define SETTINGS_ADDRESS SETTINGS_EEPROM_ADDRESS
#else // USE_EEPROM
#define SETTINGS_ADDRESS SETTINGS_FLASH_ADDRESS
#endif // USE_EEPROM
//--------------------------------------------------
//------------DEFINES FOR PWM SETTING---------------
// settings defines
#define HZ_TIMER_CTRL 400
#define HZ_TIMER_PWM 1000
#define PWM_RAMP_SPEED 20
// TIM PWM1 SETTINGS
#define PWM_MASTER_TIM_NUMB 4
#define TIMER_PWM_TICKBASE TIM_TickBase_1US
#define TIMER_PWM_AHB_FREQ 84
#define TIMER_PWM1_INSTANCE TIM4
#define TIMER_PWM1_TIM_CHANNEL1 TIM_CHANNEL_1
#define TIMER_PWM1_TIM_CHANNEL2 TIM_CHANNEL_2
#define TIMER_PWM1_GPIOx GPIOD
#define TIMER_PWM1_GPIO_PIN_X1 GPIO_PIN_12
#define TIMER_PWM1_GPIO_PIN_X2 GPIO_PIN_13
// TIM PWM2 SETTINGS
#define TIMER_PWM2_INSTANCE TIM3
#define TIMER_PWM2_TIM_CHANNEL1 TIM_CHANNEL_3
#define TIMER_PWM2_TIM_CHANNEL2 TIM_CHANNEL_4
#define TIMER_PWM2_GPIOx GPIOB
#define TIMER_PWM2_GPIO_PIN_X1 GPIO_PIN_0
#define TIMER_PWM2_GPIO_PIN_X2 GPIO_PIN_1
// TIM PWM3 SETTINGS
#define TIMER_PWM3_INSTANCE TIM1
#define TIMER_PWM3_TIM_CHANNEL1 TIM_CHANNEL_1
#define TIMER_PWM3_TIM_CHANNEL2 TIM_CHANNEL_2
#define TIMER_PWM3_GPIOx GPIOE
#define TIMER_PWM3_GPIO_PIN_X1 GPIO_PIN_9
#define TIMER_PWM3_GPIO_PIN_X2 GPIO_PIN_11
// TIM CTRL SETTINGS
#define TIMER_CTRL_INSTANCE TIM13
#define TIMER_CTRL_TICKBASE TIM_TickBase_1US
#define TIMER_CTRL_AHB_FREQ 84
// TIM ENCODER SETTINGS
#define TIMER_ENCODER_INSTANCE TIM5
#define TIMER_ENCODER_TICKBASE (TIM_TickBase_1US)
#define TIMER_ENCODER_AHB_FREQ 84
#define TIMER_ENCODER_PORT GPIOA
#define TIMER_ENCODER_PIN1 GPIO_PIN_0
#define TIMER_ENCODER_PIN2 GPIO_PIN_1
#define TIMER_ENCODER_PIN_SW GPIO_PIN_2
// PWM SETTINGS
#define SIN_TABLE_ORIGIN sin_table
#define SIN_TABLE_SIZE_MAX 1000
//--------------------------------------------------
//----------DEFINES FOR MODBUS SETTING--------------
#define MODBUS_UART_NUMB 3 // number of used uart
#define MODBUS_SPEED 115200
#define MODBUS_GPIOX GPIOB
#define MODBUS_GPIO_PIN_RX GPIO_PIN_11
#define MODBUS_GPIO_PIN_TX GPIO_PIN_10
/* accord to this define sets define USED_MB_UART = USARTx */
#define MODBUS_TIM_NUMB 7 // number of used uart
#define MODBUS_TIM_AHB_FREQ 84
/* accord to this define sets define USED_MB_TIM = TIMx */
/* defines for modbus behaviour */
#define MODBUS_DEVICE_ID 1 // number of used uart
#define MODBUS_MAX_TIMEOUT 5000 // is ms
// custom define for size of receive message
//--------------------------------------------------
typedef struct
{
// ctrl periph settings
uint32_t TIM_CTRL_TICKBASE;
uint32_t TIM_CTRL_AHB_FREQ;
// pwm peripth settings
uint32_t TIM_PWM_TICKBASE;
uint32_t TIM_PWM_AHB_FREQ;
// uint32_t TIM_PWM1_INSTANCE;
uint32_t TIM_PWM1_TIM_CHANNEL1;
uint32_t TIM_PWM1_TIM_CHANNEL2;
uint32_t TIM_PWM1_GPIOx;
uint32_t TIM_PWM1_GPIO_PIN_X1;
uint32_t TIM_PWM1_GPIO_PIN_X2;
uint32_t TIM_PWM2_INSTANCE;
uint32_t TIM_PWM2_TIM_CHANNEL1;
uint32_t TIM_PWM2_TIM_CHANNEL2;
uint32_t TIM_PWM2_GPIOx;
uint32_t TIM_PWM2_GPIO_PIN_X1;
uint32_t TIM_PWM2_GPIO_PIN_X2;
uint32_t TIM_PWM3_INSTANCE;
uint32_t TIM_PWM3_TIM_CHANNEL1;
uint32_t TIM_PWM3_TIM_CHANNEL2;
uint32_t TIM_PWM3_GPIOx;
uint32_t TIM_PWM3_GPIO_PIN_X1;
uint32_t TIM_PWM3_GPIO_PIN_X2;
// modbus peripth settings
uint32_t MB_DEVICE_ID;
uint32_t MB_SPEED;
uint32_t MB_GPIOX;
uint32_t MB_GPIO_PIN_RX;
uint32_t MB_GPIO_PIN_TX;
uint32_t MB_MAX_TIMEOUT;
uint32_t MB_TIM_AHB_FREQ;
// uint32_t MB_UART_NUMB;
// uint32_t MB_TIM_NUMB;
}ProjectSettings_TypeDef;
extern ProjectSettings_TypeDef PROJSET;
#define PROJSET_MEM ((ProjectSettings_TypeDef *)SETTINGS_ADDRESS)
//#define HAL_FLASH_GET_TYPEPROGRAM(_val_) (sizeof(PROJSET_MEM->MB_DEVICE_ID)/2 - 1)
#define HAL_FLASH_GET_TYPEPROGRAM(_val_) FLASH_TYPEPROGRAM_WORD
#define FLASH_WRITE_SETTING(_setting_, _val_) HAL_FLASH_Program(HAL_FLASH_GET_TYPEPROGRAM(_setting_), (uint32_t)(&_setting_), (uint32_t)_val_);
void SetFlagUpdateSettingsInMem(void);
void UpdateSettingsInMem(void);
void WriteSettingsToMem(void);
void FillSettingsWithDefines(void);
void CheckSettingsInFLASH(void);
int CheckIsSettingsValid(ProjectSettings_TypeDef *set_struct);
#endif // __PROJ_SETTINGS_H_