/* USER CODE BEGIN Header */
/****************************************************************************************
	* @author  尚知物理
	* @哔哩哔哩链接：https://shop598739109.taobao.com
	* @file           : Function.c
  * @brief          : Function 功能函数集合
  * @version V1.0
  * @date    06-26-2023
  * @LegalDeclaration ：本文档内容难免存在Bug，仅限于交流学习，禁止用于任何的商业用途
	* @Copyright   著作权尚知物理所有
  * @attention
  ******************************************************************************
  */
/* USER CODE END Header */

#include "stdio.h"
#include "function.h"//功能函数头文件
#include "CtlLoop.h"//控制环路头文件
#include "svpwm.h"


//struct  _ADI 		SADC={0,  0,0,2048,0,0,2048,  0,0,0,  0,0,2048,0,0,2048,0,  0,0,0,0,2048};	//输入输出参数采样值和平均值

uint16_t ADC1_RESULT[8]={0,0,0,0,0,0,0,0};								//ADC采样外设到内存的DMA数据保存寄存器


SADC adc;
void SADC_Init(void)
{
	adc.Uref = 0.0;
	adc.Uref = 0.0;				//1.65V基准电压
	
	adc.Uab = 0.0;				//AB相线电压
	adc.UabAvg = 0.0;			//AB相线电压平均值
	adc.UabOffset = 1.5;	//AB相线电压采样偏置
	adc.Ubc = 0.0;				//BC相线电压
	adc.UbcAvg = 0.0;			//BC相线电压平均值
	adc.UbcOffset = 1.5;	//BC相线电压采样偏置

	adc.Ua = 0.0;					//A相相电压
	adc.Ub = 0.0;					//B相相电压
	adc.Uc = 0.0;					//C相相电压
	
	adc.Ia = 0.0;					//A相电流
	adc.IaAvg = 0.0;			//A相电流平均值
	adc.IaOffset = 1.5;		//A相电流采样偏置
	adc.Ib = 0.0;					//B相电流
	adc.IbAvg = 0.0;			//B相电流平均值
	adc.IbOffset = 1.5;		//B相电流采样偏置
	adc.Ic = 0.0;					//C相电流
	adc.IcAvg = 0.0;			//B相电流平均值
	adc.IcOffset = 1.5;		//B相电流采样偏置
	
	adc.Udc = 0.0;				//直流母线电压
	adc.UdcAvg = 0.0;			//直流母线电压平均值
	adc.Idc = 0.0;				//直流母线电流
	adc.IdcAvg = 0.0;			//直流母线电流平均值
	adc.IdcOffset = 1.65;	//直流母线电流采样偏置
}



/*******************************************************************************
 * @fn Init_lowPass_alpha
 * @brief 初始化低通滤波器滤波系数
 * @param filter 滤波器
 * @param ts 采用周期 单位s
 * @return fc 截至频率 单位hz
 ******************************************************************************/
low_pass_filter_t  low_pass_filter1={0};  //定义滤波器
low_pass_filter_t  low_pass_filter2={0};  //定义滤波器
low_pass_filter_t  low_pass_filter3={0};  //定义滤波器
low_pass_filter_t  low_pass_filter4={0};  //定义滤波器
void Init_lowPass_alpha(low_pass_filter_t* const filter,const float ts, const float fc)
{
  float b=2*M_PI*fc*ts;
  filter->ts=ts;
  filter->fc=fc;
  filter->lastYn=0;
  filter->alpha=b/(b+1);
}
/*******************************************************************************
 * @fn Low_pass_filter
 * @brief 低通滤波函数
 * @param data 采样数据
 * @return 滤波结果
 ******************************************************************************/
float Low_pass_filter(low_pass_filter_t* const filter, const float data)
{
  float tem=filter->lastYn+(filter->alpha*(data-filter->lastYn));
  filter->lastYn=tem;
  return tem;
}






/* ===================================================================
**     Funtion Name :   void ADCSample(void)
**     Description :    采样输出电压、输出电流、输入电压、输入电流
** ===================================================================*/
void ADCSample(void)
{

//从DMA缓冲器中获取数据 Q15,并对其进行线性矫正-采用线性矫正
	adc.Uab   = (int32_t )ADC1_RESULT[0] * CAL_Uab_K - adc.UabOffset + CAL_Uab_B;
	adc.Ubc   = (int32_t )ADC1_RESULT[1] * CAL_Ubc_K - adc.UbcOffset + CAL_Ubc_B;
	adc.Ia    = ((int32_t )ADC1_RESULT[2] * 0.000805664062 - adc.IaOffset ) * CAL_Ia_K + CAL_Ia_B;
	adc.Ib    = ((int32_t )ADC1_RESULT[3] * 0.000805664062 - adc.IbOffset ) * CAL_Ib_K  + CAL_Ib_B;
	adc.Ic    = ((int32_t )ADC1_RESULT[4] * 0.000805664062 - adc.IcOffset ) * CAL_Ic_K  + CAL_Uab_B;
	adc.Uref  = (int32_t )ADC1_RESULT[5] * CAL_Udc_K  + CAL_Ubc_B;
	adc.Udc   = (int32_t )ADC1_RESULT[6] * CAL_Udc_K  + CAL_Udc_B;
	adc.Idc   = (int32_t )ADC1_RESULT[7] * CAL_Idc_K - adc.IdcOffset + CAL_Ib_B;
//低通滤波
	adc.Ubc = Low_pass_filter(&low_pass_filter1,adc.Ubc);//获取滤波数据
	adc.Idc = Low_pass_filter(&low_pass_filter2,adc.Idc);//获取滤波数据
	adc.Ib = Low_pass_filter(&low_pass_filter3,adc.Ib);//获取滤波数据
	adc.Ic = Low_pass_filter(&low_pass_filter4,adc.Ic);//获取滤波数据

	
	
	
//	if(SADC.Uref   <0.01 )//采样有零偏离，采样值很小时，直接为0
//		SADC.Uref   = 0;	
//	if(SADC.Udc   <0.01 )//对电流采样限制，当采样值小于SADC.IinOffset时
//		SADC.Udc   =0;
//	if(SADC.Idc   <0.01 )//对电流采样限制，当采样值小于SADC.IinOffset时
//		SADC.Idc   =0;

}



/** ===================================================================
**     Funtion Name :void OLEDShow(void)
**     Description : OLED显示函数		 
** ===================================================================*/
//OLED刷新计数 mS计数一次，在mS中断里累加
uint16_t OLEDShowCnt=0;
void OLEDShow(void)
{
	
	OLED_ShowFNum(0,0, adc.Udc );
	OLED_ShowFNum(0,2, adc.Idc );
	OLED_ShowFNum(0,4, adc.Ib  );
	OLED_ShowFNum(0,6, adc.Ic  );
//	OLED_ShowFNum(0,4, adc.Idc );
//	OLED_ShowFNum(0,6, adc.Uab);
	
	printf("%f,%f,%f,%f \r\n",adc.Udc,adc.Idc,adc.Ib,adc.Ic);
//	printf("%f,%f,%f,%f,%f\n",adc.Uab,adc.Ubc,adc.Ia,adc.Ib,adc.Ic );
	
//	printf("%d,%d,%d,%d,%d,%d\n",ADC1_RESULT[2],ADC1_RESULT[3],ADC1_RESULT[4],ADC1_RESULT[5],ADC1_RESULT[6],ADC1_RESULT[7] );
//	printf("%d,%d,%d\n",ADC1_RESULT[5],ADC1_RESULT[6],ADC1_RESULT[7] );
//	printf("%d,%d,%d\n",TIM4_CCR1,TIM4_CCR2,TIM4_CCR3);

	
}


/** ===================================================================
**     Funtion Name :void PWM_ON_OFF(uint16_t EN)
**     Description : PWM输出使能函数，给1使能，给0失能
** ===================================================================*/
void PWM_ON_OFF(uint16_t EN)
{
	if(EN == 1)
	{
		HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_SET);
	}else
	{
		HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);
	}
}



