note: - модбас не моделируется, в s-function просто передаются константы режимов. - лишние файлы убраны в outdate. - два канала одной фазы переключаются немного криво: на один такт симуляции проскакивает высокий уровень предыдущего канала и только потом включается текущий канал
		
			
				
	
	
		
			324 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			324 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/********************************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 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_]
 | 
						||
						к регистру автозагрузки с диапазоном [0,ARR].
 | 
						||
	* @note		Если задана минимальная длительность импульса в тактах n, она вычитается из ARR: [0, ARR-2*n]
 | 
						||
						И потом регистр ARR заполняется так, что диапазон его значений будет [n, ARR-n] @ref PWM_Get_Table_Element_Unsigned
 | 
						||
	*/
 | 
						||
#define PWM_Calc_Duty_Scale(_hpwm_, _scale_) 								((float)PWM_Get_Autoreload(_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_ 		- канал для выставления скважности.
 | 
						||
	* @param 	_ind_ 				- номер элемента из таблицы скважностей.
 | 
						||
	*/
 | 
						||
#define PWM_Set_Duty_From_Percent(_hpwm_, _channel_)				__HAL_TIM_SET_COMPARE(&((_hpwm_)->stim.htim), _channel_, ((_hpwm_)->PWM_Value/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_, _ind_)							(PWM_Set_Compare1(_hpwm_, (PWM_Get_Table_Element_Unsigned((_hpwm_), (_ind_))+1)))
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Set PWM Duty From table
 | 
						||
	* @param 	_hpwm_ 				- указатель на хендл pwm.
 | 
						||
	* @param 	_channel_ 		- канал для выставления скважности.
 | 
						||
	* @param 	_ind_ 				- номер элемента из таблицы скважностей.
 | 
						||
	*/
 | 
						||
#define PWM_Set_SlaveDuty_From_Table(_hpwm_, _ind_)					(PWM_Set_Compare1(_hpwm_, (PWM_Get_Table_Element_Unsigned((_hpwm_)->hMasterPWM, (_ind_))+1)))
 | 
						||
 | 
						||
 | 
						||
// MODE DEFINES
 | 
						||
#define PWM_DC_MODE_Pos					(0)
 | 
						||
#define PWM_CH_MODE_Pos					(1)
 | 
						||
#define PWM_PHASE_MODE_Pos			(2)
 | 
						||
 | 
						||
#define PWM_DC_MODE							(1<<(PWM_DC_MODE_Pos))		// 0 - set pwm duty from table with PWM_Value period, 1 - set pwm duty PWM_Value (in percent)
 | 
						||
#define PWM_CH_MODE							(1<<(PWM_CH_MODE_Pos))	
 | 
						||
// DC MODE: 		0 - pwm on channel 1, 1 - pwm on channel 2
 | 
						||
// TABLE MODE: 	0 - signed mode,	 		1 - unsigned mode
 | 
						||
#define PWM_PHASE_MODE							(1<<(PWM_PHASE_MODE_Pos))	
 | 
						||
 | 
						||
#define PWM_Get_Mode(_hpwm_, _mode_)	((_hpwm_)->sPWM_Mode&(_mode_))
 | 
						||
/* Structure for PWM modes */
 | 
						||
typedef enum
 | 
						||
{
 | 
						||
	PWM_TABLE_UNSIGN = 		0,													/* set pwm duty from table with PWM_Value period */
 | 
						||
	PWM_TABLE_SIGN = 			PWM_CH_MODE,								/* set pwm duty from table with PWM_Value period on two channels (positive and negative halfes) */
 | 
						||
	PWM_DC_POS = 					PWM_DC_MODE,								/* set pwm duty PWM_Value (in percent) on first channel */
 | 
						||
	PWM_DC_NEG = 					PWM_DC_MODE|PWM_CH_MODE,		/* set pwm duty PWM_Value (in percent) on second channel */
 | 
						||
	
 | 
						||
	PWM_PHASE_UNSIGN = 		PWM_PHASE_MODE,								/* set pwm table duty on three pins, with requested shift */
 | 
						||
	PWM_PHASE_SIGN = 			PWM_CH_MODE|PWM_PHASE_MODE,		/* set pwm table duty on six pins (two pins = one phase (positive and negative halfes)) */
 | 
						||
}PWM_ModeTypeDef;
 | 
						||
 | 
						||
 | 
						||
/** 
 | 
						||
	* @brief 	Handle for PWM.
 | 
						||
	* @note 	Prefixes: h - handle, s - settings, f - flag
 | 
						||
	*/
 | 
						||
typedef struct // PWM_HandleTypeDef
 | 
						||
{
 | 
						||
	/* PWM VARIABLES */
 | 
						||
	PWM_ModeTypeDef 				sPWM_Mode;						/* PWM Mode: 0 - DC mode, 1 - Table mode */
 | 
						||
	float 									PWM_Value;						/* DC mode: PWM duty, Table mode: frequency*/
 | 
						||
	uint32_t 								PWM_MinPulseDur;			/* minimum pulse duration for PWM in us*/
 | 
						||
	uint32_t 								PWM_DeadTime;					/* dead-Time between switches half waves (channels) in us */
 | 
						||
	
 | 
						||
	/* 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_Table_Ind;				/* current ind of duty table */
 | 
						||
	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 	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		Индекс для свейл ШИМ расчитывается в самой функции.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_Set_DutyTable_Unsigned(PWM_SlaveHandleTypeDef *hspwm, uint16_t sin_ind);
 | 
						||
/** 
 | 
						||
	* @brief 	Set Duty from table on Slave PWM at two channel by sin_ind of the Master PWM.
 | 
						||
	* @param	hspwm 		- указатель на хендл слейв ШИМ.
 | 
						||
	* @param	sin_ind 	- индекс таблицы для Мастер ШИМ.
 | 
						||
	* @note		Индекс для свейл ШИМ расчитывается в самой функции.
 | 
						||
	*/
 | 
						||
void PWM_SlavePhase_Set_DutyTable_Signed(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);
 | 
						||
 | 
						||
 | 
						||
//---------------------------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_
 |