/******************************************************************************
版权所有：	
文件名称：	switch.c
文件版本：	01.01
创建作者:	sunxi
创建日期：	2013-04-15
功能说明：	DTU核心处理程序以开关为单位，循环处理。
其它说明：
修改记录：
*/
/*------------------------------- 头文件 --------------------------------------
*/
#include "head.h"
#ifdef CPU_FUXI
#include "rt_clib.h"
#include "fourier.h"
#endif

/*------------------------------- 宏定义 --------------------------------------
*/
#ifdef CPU_FUXI
#define AUTO_ADJUST_NUM 	1	// 自动校准时平均的次数
#else
#define AUTO_ADJUST_NUM 	50	// 自动校准时平均的次数
#endif
#define MEA_CAL_NUMBER  	5	// 实际测量时平均的次数

//#define MEA_CAL_HARMONIC  	14	//(CFG_ADC_DOTS_PER_PERIOD/2)	// 谐波计算的次数

/*------------------------------ 全局变量 -------------------------------------
*/
int g_sw_init;				// SW是否初始化

struct ui 	g_ui[UI_NUM];	// 电压电流模拟量计算的综合结构
struct ui_jy   g_ui_jy[3];           // 方向判断中的记忆电压

struct ui120 Us1_120,Us2_120;
struct ui_p0 g_ui_p0[SWITCH_NUM_MAX]; //零序功率

int 		g_ui_angle0;	// 角度计算时，作为参考电压通道在g_ui中的索引
int  		g_prot_index;	// 保护计算时，采样通道中采样点的索引

struct sw g_sw[SWITCH_NUM_EXT];	// 开关综合结构
struct sw_public g_sw_pub;		// 开关公共部分综合结构

int g_mea_cnt = 0;	// 测量计数

int g_harmonic_num = 13;	// 默认计算13次谐波
// 谐波系数修正
float g_harmonic_factor[CFG_ADC_DOTS_PER_PERIOD/2] = 
{
	1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
	1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
};

// 开关开入名称
const s8 *g_sw_di_name[SW_DI_NUM] =
{
    "开关合位", // 1
    "开关分位",
    "未储能",
    "已储能",
    "隔离刀合位",
    "隔离刀分位",
    "接地刀合位",
    "接地刀分位",
    "气压低告警",
    "气压低闭锁", // 10
    "自动化投入",
    "常规保护",
    "集中式",
    "重合闸投入",
    "重合闸停用",
    "馈线自动化",
    "智能分布式",
    "就地FA闭锁",
    "联络/分段模式",
    "带电显示器有压",
    "分闸出口压板状态", // 20
    "合闸出口压板状态",
    "手动合闸",
    "手动分闸",
    "驱动器异常",
    "母线侧硬件残压",
    "线路侧硬件残压",
    "控制回路断线",
    "合闸回路监视",
    "分闸回路监视",
    "HQ开入", // 30
    "TQ开入",
    "电源侧瞬压",
    "负荷侧瞬压",
    "开关远方",
    "脉冲计数1",
    "脉冲计数2",

#ifdef DO_KOUT_CHECK
    "开出自检",
#else
    "开入3",
#endif

#if defined GD_AREA_ZHUHAI_V2 || defined GD_AREA_JIEYANG || defined GD_AREA_LIAONING_2021
    "对侧开关位置",
#else
    "开入4",
#endif

#ifdef CUSTOMIZE_BZT // 备自投
    "备自投",
    "#1进线合位",
    "#1进线分位",
    "#2进线合位",
    "#2进线分位",
    "备自投-合位",
    "备自投-分位",
    "闭锁备自投",
    "备自投-失压分闸"
#endif
};

// 开关开出名称
const s8 * g_sw_do_name[SW_DO_NUM] =
{
	"合闸",
	"跳闸",
	"保护合闸",
	"保护分闸",
	"遥控合闸",
	"遥控分闸",
	"瞬压复归",
	"瞬压复归1",
	"瞬压闭锁",
	"储能信号",//"开出11",
	"保护动作开出",
#ifdef GD_AREA_CHAOZHOU_CHAOAN_FUYANG
	"同期合闸开出-常闭",
	"同期合闸开出-常开",
#else	
	"同期合闸开出",
#endif
#ifdef	CUSTOMIZE_BZT //备自投
	"备自投-#1进线合闸", 
	"备自投-#1进线分闸",
	"备自投-#2进线合闸",
	"备自投-#2进线分闸",
	"备自投-分段合闸",
	"备自投-分段分闸",

	"备自投-进线1失压分闸",
	"备自投-进线2失压分闸",
#endif

#if defined GD_AREA_MAIN_2020 || defined SW_FAIL_SINGLE_OUT
    "开关失灵",
#endif

#ifdef GD_AREA_YUNAN_LP	
	"电源消失开出",
#else
	"开出14",
#endif	

#ifdef GD_AREA_PROTECTOR
	"装置异常告警动作",
#endif

};

const s8 * g_sw_led_name[SW_LED_NUM]=
{
	"综合合位灯",
	"综合分位灯",
	"合位灯",
	"分位灯",
	"过流灯",
	"接地灯",
	"重合闸灯",
	"充电灯",
	"闭锁灯",
	"XT灯",
	"YT灯",
	"动作灯",
	"重合闭锁灯",
	"未储能灯",
	"联络灯",
	"分段灯",
	"重合+FA闭锁灯",
#ifdef GD_AREA_MAIN_2020
    "常规保护模式灯",
#else
	"保护模式灯",	
#endif	
	"就地FA模式灯",
	"分布式模式灯",
	"X+Y灯",
#if defined GD_AREA_GUANGZHOU_FTU 
	"故障告警灯",
#elif defined GD_AREA_ZHUHAI_V2
	"告警灯",
#endif
#ifdef GD_AREA_ZHUHAI_V2    
    "通讯异常灯"	//珠海局针对的是智能分布式通信异常
#endif
//#ifdef GD_AREA_ECZD_2020
#if defined GD_AREA_ECZD_2020 || defined GD_AREA_MAIN_2020
	"自动解列功能灯",
	"同期合闸功能灯",
	"停用保护及FA灯",
	"停用自动解列灯",
	"停用同期合闸灯",
#endif
	"跳闸灯",
	"重合闸充电灯",

	"隔离刀闸灯",
	"接地刀闸灯",

#ifdef FUNC_DRIVE
	"开关传动灯",
#endif
};

// 开关模拟量名称
//！！！更改模拟量名称可能会对以下宏有影响，请注意
const struct mea_desc g_sw_ac_desc[SW_AC_NUM_ALL] =
{
#ifdef DISP_MEA_CN
	{"保护IA",UNIT_A5,UNIT_ANG},
	{"保护IB",UNIT_A5,UNIT_ANG},
	{"保护IC",UNIT_A5,UNIT_ANG},
	{"保护I0",UNIT_A5,UNIT_ANG},
#ifdef SW_AC_I0S_SAMPLE	
	{"保护I0s",UNIT_A5,UNIT_ANG},
#endif	
	{"测量IA",UNIT_A5,UNIT_ANG},
	{"测量IB",UNIT_A5,UNIT_ANG},
	{"测量IC",UNIT_A5,UNIT_ANG},	
	{"总有功",UNIT_W,UNIT_NULL},
	{"A相有功",UNIT_W,UNIT_NULL},
	{"B相有功",UNIT_W,UNIT_NULL},
	{"C相有功",UNIT_W,UNIT_NULL},
	{"总无功",UNIT_Var,UNIT_NULL},
	{"A相无功",UNIT_Var,UNIT_NULL},
	{"B相无功",UNIT_Var,UNIT_NULL},
	{"C相无功",UNIT_Var,UNIT_NULL},
	{"功率因素",UNIT_COS,UNIT_NULL},
#else
	{"BIA",UNIT_A5,UNIT_ANG},
	{"BIB",UNIT_A5,UNIT_ANG},
	{"BIC",UNIT_A5,UNIT_ANG},
	#ifdef GD_TEST_2021
		{"I0",UNIT_I0A,UNIT_ANG},
	#else
		{"I0",UNIT_A5,UNIT_ANG},
	#endif
#ifdef SW_AC_I0S_SAMPLE	
	{"I0s",UNIT_A5,UNIT_ANG},
#endif	
	{"CIA",UNIT_A5,UNIT_ANG},
	{"CIB",UNIT_A5,UNIT_ANG},
	{"CIC",UNIT_A5,UNIT_ANG},
	{"P",UNIT_W,UNIT_NULL},
	{"Pa",UNIT_W,UNIT_NULL},
	{"Pb",UNIT_W,UNIT_NULL},
	{"Pc",UNIT_W,UNIT_NULL},
	{"Q",UNIT_Var,UNIT_NULL},
	{"Qa",UNIT_Var,UNIT_NULL},
	{"Qb",UNIT_Var,UNIT_NULL},
	{"Qc",UNIT_Var,UNIT_NULL},
#ifdef FUN_YC_POWER_S	
	{"S",UNIT_Var,UNIT_NULL},
#endif
	{"COS",UNIT_COS,UNIT_NULL},
#endif
	
	{"BI_UNB",UNIT_Per,UNIT_NULL},
	{"CI_UNB",UNIT_Per,UNIT_NULL},
	{"脉冲计数1",UNIT_GE,UNIT_NULL},
	{"脉冲计数2",UNIT_GE,UNIT_NULL},
	{"速断电流定值",UNIT_NULL,UNIT_NULL}, 
	{"速断保护时间",UNIT_NULL,UNIT_NULL}, 
	{"过流电流定值",UNIT_NULL,UNIT_NULL}, 
	{"过流保护时间",UNIT_NULL,UNIT_NULL}, 
	{"零序电流定值",UNIT_NULL,UNIT_NULL}, 
	{"零序保护时间",UNIT_NULL,UNIT_NULL}, 
	{"零序保护模式",UNIT_NULL,UNIT_NULL}, 
	{"一次重合闸时间",UNIT_NULL,UNIT_NULL}, 
	{"二次重合闸时间",UNIT_NULL,UNIT_NULL}, 
	{"得电闭合时间",UNIT_NULL,UNIT_NULL}, 
	{"无压分闸闭锁时间",UNIT_NULL,UNIT_NULL}, 
	{"工作模式",UNIT_NULL,UNIT_NULL}, 	

#ifdef METERING_ENERGY
	{"计量UAB",UNIT_V220,UNIT_NULL},	// yc 17
	{"计量UBC",UNIT_V220,UNIT_NULL},
	{"计量UCA",UNIT_V220,UNIT_NULL},
	{"计量UA",UNIT_V220,UNIT_NULL},  
	{"计量UB",UNIT_V220,UNIT_NULL},
	{"计量UC",UNIT_V220,UNIT_NULL},	
	{"计量IA",UNIT_A5,UNIT_NULL},
	{"计量IB",UNIT_A5,UNIT_NULL},
	{"计量IC",UNIT_A5,UNIT_NULL},
	{"计量I0",UNIT_A5,UNIT_NULL},
	{"计量有功功率",UNIT_W,UNIT_NULL},
	{"计量A相有功功率",UNIT_W,UNIT_NULL},
	{"计量B相有功功率",UNIT_W,UNIT_NULL},
	{"计量C相有功功率",UNIT_W,UNIT_NULL},
	
	{"计量无功功率",UNIT_Var,UNIT_NULL},
	{"计量A相无功功率",UNIT_Var,UNIT_NULL},
	{"计量B相无功功率",UNIT_Var,UNIT_NULL},
	{"计量C相无功功率",UNIT_Var,UNIT_NULL},
	
	{"计量视在功率",UNIT_Var,UNIT_NULL},
	{"计量A相视在功率",UNIT_Var,UNIT_NULL},
	{"计量B相视在功率",UNIT_Var,UNIT_NULL},
	{"计量C相视在功率",UNIT_Var,UNIT_NULL},
	{"计量功率因数",UNIT_COS,UNIT_NULL},
	{"计量A相功率因数",UNIT_COS,UNIT_NULL},
	{"计量B相功率因数",UNIT_COS,UNIT_NULL},
	{"计量C相功率因数",UNIT_COS,UNIT_NULL},
	{"计量频率",UNIT_Hz,UNIT_NULL},
#else
	{"YC1",UNIT_NULL,UNIT_NULL},  // yc 17
	{"YC2",UNIT_NULL,UNIT_NULL},
	{"YC3",UNIT_NULL,UNIT_NULL},
	{"YC4",UNIT_NULL,UNIT_NULL},
	{"YC5",UNIT_NULL,UNIT_NULL},
	{"YC6",UNIT_NULL,UNIT_NULL},
	{"YC7",UNIT_NULL,UNIT_NULL},
	{"YC8",UNIT_NULL,UNIT_NULL},
	{"YC9",UNIT_NULL,UNIT_NULL},
	{"YC10",UNIT_NULL,UNIT_NULL},
	{"YC11",UNIT_NULL,UNIT_NULL},
	{"YC12",UNIT_NULL,UNIT_NULL}, 
#endif
};

// 计量模块电度值
const struct mea_desc g_dd_desc[SW_DD_NUM_ALL]=
{
	{"当前正向有功",		UNIT_kWh,UNIT_NULL},        //6401 
	{"当前正向无功",    		UNIT_kVarh,UNIT_NULL},      //6402 
	{"当前一象限无功", 		UNIT_kVarh,UNIT_NULL},      //6403 
	{"当前四象限无功",  	UNIT_kVarh,UNIT_NULL},      //6404 
	{"当前反向有功",   		UNIT_kWh,UNIT_NULL},        //6405 
	{"当前反向无功",   		UNIT_kVarh,UNIT_NULL},      //6406 
	{"当前二象限无功",  	UNIT_kVarh,UNIT_NULL},    	//6407 
	{"当前三象限无功",  	UNIT_kVarh,UNIT_NULL},      //6408 
	{"15分冻结正向有功", 	UNIT_kWh,UNIT_NULL},       	//6409 
	{"15分冻结正向无功",  	UNIT_kVarh,UNIT_NULL},     	//640A 
	{"15分冻结一象限无功", 	UNIT_kVarh,UNIT_NULL},     	//640B 
	{"15分冻结四象限无功", 	UNIT_kVarh,UNIT_NULL},     	//640C 
	{"15分冻结反向有功", 	UNIT_kWh,UNIT_NULL},        //640D 
	{"15分冻结反向无功",  	UNIT_kVarh,UNIT_NULL},     	//640E 
	{"15分冻结二象限无功",	UNIT_kVarh,UNIT_NULL},     	//640F 
	{"15分冻结三象限无功", 	UNIT_kVarh,UNIT_NULL},     	//6410 
	{"日冻结正向有功",   	UNIT_kWh,UNIT_NULL},        //6411 
	{"日冻结冻结正向无功",	UNIT_kVarh,UNIT_NULL},    	//6412 
	{"日冻结一象限无功", 	UNIT_kVarh,UNIT_NULL},      //6413 
	{"日冻结四象限无功",  	UNIT_kVarh,UNIT_NULL},      //6414 
	{"日冻结反向有功",  	UNIT_kWh,UNIT_NULL},        //6415 
	{"日冻结反向无功",    	UNIT_kVarh,UNIT_NULL},      //6416 
	{"日冻结二象限无功", 	UNIT_kVarh,UNIT_NULL},      //6417 
	{"日冻结三象限无功", 	UNIT_kVarh,UNIT_NULL},      //6418 
	{"潮变冻结正向有功", 	UNIT_kWh,UNIT_NULL},      	//6419 
	{"潮变冻结正向无功",  	UNIT_kVarh,UNIT_NULL}, 	 	//641A 
	{"潮变冻结一象限无功", 	UNIT_kVarh,UNIT_NULL},    	//641B 
	{"潮变冻结四象限无功", 	UNIT_kVarh,UNIT_NULL},    	//641C 
	{"潮变冻结反向有功",  	UNIT_kWh,UNIT_NULL},     	//641D 
	{"潮变冻结反向无功",   	UNIT_kVarh,UNIT_NULL},    	//641E 
	{"潮变冻结二象限无功", 	UNIT_kVarh,UNIT_NULL},    	//641F 
	{"潮变冻结三象限无功",	UNIT_kVarh,UNIT_NULL},    	//6420 

#ifdef METERING_ENERGY
	{"当前A相有功",				UNIT_kWh,	UNIT_NULL},
	{"当前B相有功",				UNIT_kWh,	UNIT_NULL},
	{"当前C相有功",				UNIT_kWh,	UNIT_NULL},
	{"当前A相正向有功",			UNIT_kWh,	UNIT_NULL},
	{"当前B相正向有功",			UNIT_kWh,	UNIT_NULL},
	{"当前C相正向有功",			UNIT_kWh,	UNIT_NULL},
	{"当前A相反向有功",			UNIT_kWh,	UNIT_NULL},
	{"当前B相反向有功",			UNIT_kWh,	UNIT_NULL},		
	{"当前C相反向有功",			UNIT_kWh,	UNIT_NULL},		
	{"当前总有功",				UNIT_kWh,	UNIT_NULL},
	{"当前总无功",				UNIT_kWh,	UNIT_NULL},
#endif
};

// 开关公共开入名称
const s8 *g_pub_di_name[PUB_DI_NUM] =
{
    "远方",
    "就地",
    "检修状态投入",
    "柜门打开",
    "复归信号",
    "交流失电",
    "电池活化状态",
    "电池欠压",
    "电源模块故障",
    "电容器动作",
    "直流电源欠压",
    "内阻异常",
    "FA解锁",
    "装置复位",
    "功能总压板",
    "信号复归+FA 解锁",
    "非电量1",
    "非电量2",
    "非电量3",
    "非电量4",
    "非电量5",
    "非电量6",
    "非电量7",
    "非电量8",
    "开入1",
    "开入2",
    "开入3",
    "开入4",
    "开入5",
    "开入6",
#ifdef YX_DI_ERROR
    "遥信自检",
#else
    "开入7",
#endif

#ifdef KZ_OUT_TT
    "控制出口压板",
#else
    "开入8",
#endif
};

// 开关公共开出名称
const s8 * g_pub_do_name[PUB_DO_NUM] =
{
	"电池活化",
	"活化退出",
	"开出03",
	"开出04",
	"开出05",
	"开出06",
	"开出07",
	"开出08",
	"开出09",

	"电压合格率清零",
	"预控开出",
	"解除闭锁",
	"远方重启",
	"远方复归",
#ifdef YK_FG_FAJS
	"远方复归&FA解锁",	// 远方复归+FA解锁
#endif
	"重合软压板合",
	"重合软压板分",
#if defined BHFA_YB_YK || defined BHFAGS_YB_YK
	//#ifdef GD_AREA_ECZD_2020
	#if defined GD_AREA_ECZD_2020 || defined GD_AREA_MAIN_2020
	"停用保护总软压板合",
	"停用保护总软压板分",
	#else
	"功能总投入软压板合",
	"功能总投入软压板分",
	#endif	
	"保护出口软压板合",
	"保护出口软压板分",
	#ifndef BH_FA_INONE_SW
	"常规保护软压板合",
	"常规保护软压板分",
	"馈线自动化软压板合",
	"馈线自动化软压板分",
		#ifdef BHFAGS_YB_YK
		"智能分布式软压板合",
		"智能分布式软压板分",
		#endif
	#endif
#else
    //#ifdef GD_AREA_ECZD_2020
    #if defined GD_AREA_ECZD_2020 || defined GD_AREA_MAIN_2020
	"停用保护总软压板合",
	"停用保护总软压板分",
	#else
	"自动功能软压板合",
	"自动功能软压板分",
	#endif
	"保护投入软压板合",
	"保护投入软压板分",
#endif
	"同期合闸软压板合",
	"同期合闸软压板分",
	"集中式软压板-合",
	"集中式软压板-分",

#ifdef YK_SOFT_YB
	"遥控软压板-合",
	"遥控软压板-分",
#endif

#ifdef YK_FA_ENBLE
	"FA遥控闭锁-合",
	"FA遥控闭锁-分",
#endif

#ifdef YK_FA_S_L_ENBLE
	"分段/联络-合",
	"分段/联络-分",
#endif	

	"自动解列软压板合",
	"自动解列软压板分",

#ifdef METERING_ENERGY
	"遥控电度清零",
	"遥控线损事件清零",
#endif

#ifdef FUNC_DRIVE
	"传动接收软压板合",
	"传动接收软压板分",
	"传动指令",
#endif

#ifdef FUNC_DRIVE_JY
	"不停电传动功能",
#endif

#ifdef FUNC_RESET_EQU
	"重启装置",
#endif
};

const s8 * g_pub_led_name[PUB_LED_NUM]=
{
	"电源灯",
	"运行灯",
	
	"通信灯",
	"通信状态灯",

	"电池灯",
	"异常灯",
//#ifdef GD_AREA_ECZD_2020	
#if defined GD_AREA_ECZD_2020 || defined GD_AREA_MAIN_2020
	"运行告警灯",
#endif
	"动作灯",
	"远方灯",
	"就地灯",
	"232T1",
	"232R1",
	"232T2",
	"232R2",
	"232T3",
	"232R3",
	"485T1",
	"485R1",
	"485T2",
	"485R2",
	"485T3",
	"485R3",
	"网口1",
	"网口2",
	"网口3",
#ifdef	KZ_OUT_TT
	"控制闭锁灯",
#endif
	"规约通信异常灯",
};

// 开关公共模拟量名称
const struct mea_desc g_pub_ac_desc[PUB_AC_NUM_ALL] =
{
#ifdef DISP_MEA_CN
	#ifdef GD_AREA_ZHUHAI_V2
		{"电缆UA1",UNIT_V100,UNIT_ANG},
		{"电缆UB1",UNIT_V100,UNIT_ANG},
		{"电缆UC1",UNIT_V100,UNIT_ANG},
		{"电缆UAB1",UNIT_V100,UNIT_ANG},
		{"电缆UBC1",UNIT_V100,UNIT_ANG},
		{"电缆UCA1",UNIT_V100,UNIT_ANG},
		{"母线U0 ",UNIT_V100,UNIT_ANG},
		{"电缆US1",UNIT_V220,UNIT_ANG},
		{"母线UA2",UNIT_V100,UNIT_ANG},
		{"母线UB2",UNIT_V100,UNIT_ANG},
		{"母线UC2",UNIT_V100,UNIT_ANG},
		{"母线UAB2",UNIT_V100,UNIT_ANG},
		{"母线UBC2",UNIT_V100,UNIT_ANG},
		{"母线UCA2",UNIT_V100,UNIT_ANG},
		{"电缆U0   ",UNIT_V100,UNIT_ANG},
		{"母线US2",UNIT_V220,UNIT_ANG},
	#else
		{"母线UA1",UNIT_V100,UNIT_ANG},
		{"母线UB1",UNIT_V100,UNIT_ANG},
		{"母线UC1",UNIT_V100,UNIT_ANG},
		{"母线UAB1",UNIT_V100,UNIT_ANG},
		{"母线UBC1",UNIT_V100,UNIT_ANG},
		{"母线UCA1",UNIT_V100,UNIT_ANG},
		{"母线U01",UNIT_V100,UNIT_ANG},
		#ifdef GD_AREA_HUIZHOU_HUIDONG
			{"母线AB3",UNIT_V220,UNIT_ANG},
		#else
			{"母线US1",UNIT_V220,UNIT_ANG},
		#endif
		{"线路UA2",UNIT_V100,UNIT_ANG},
		{"线路UB2",UNIT_V100,UNIT_ANG},
		{"线路UC2",UNIT_V100,UNIT_ANG},
		{"线路UAB2",UNIT_V100,UNIT_ANG},
		{"线路UBC2",UNIT_V100,UNIT_ANG},
		{"线路UCA2",UNIT_V100,UNIT_ANG},
		{"线路U02",UNIT_V100,UNIT_ANG},
		#ifdef GD_AREA_HUIZHOU_HUIDONG
			{"母线BC3",UNIT_V220,UNIT_ANG},
		#else
			{"线路US2",UNIT_V220,UNIT_ANG},
		#endif
	#endif
	
	{"V_UNB1",UNIT_Per,UNIT_NULL},
	{"V_UNB2",UNIT_Per,UNIT_NULL},
	{"工频1",UNIT_Hz,UNIT_NULL},
	{"工频2",UNIT_Hz,UNIT_NULL},
#else
	{"UA1",UNIT_V100,UNIT_ANG},
	{"UB1",UNIT_V100,UNIT_ANG},
	{"UC1",UNIT_V100,UNIT_ANG},
	{"UAB1",UNIT_V100,UNIT_ANG},
	{"UBC1",UNIT_V100,UNIT_ANG},
	{"UCA1",UNIT_V100,UNIT_ANG},
	{"U01",UNIT_V100,UNIT_ANG},
	{"US1",UNIT_V220,UNIT_ANG},
	{"UA2",UNIT_V100,UNIT_ANG},
	{"UB2",UNIT_V100,UNIT_ANG},
	{"UC2",UNIT_V100,UNIT_ANG},
	{"UAB2",UNIT_V100,UNIT_ANG},
	{"UBC2",UNIT_V100,UNIT_ANG},
	{"UCA2",UNIT_V100,UNIT_ANG},
	{"U02",UNIT_V100,UNIT_ANG},
	{"US2",UNIT_V220,UNIT_ANG},
	{"V_UNB1",UNIT_Per,UNIT_NULL},
	{"V_UNB2",UNIT_Per,UNIT_NULL},
	{"UF1",UNIT_Hz,UNIT_NULL},
	{"UF2",UNIT_Hz,UNIT_NULL},
#endif
	{"直流电压1",UNIT_V050,UNIT_NULL},
	{"直流电压2",UNIT_V050,UNIT_NULL},
#ifdef GD_AREA_YUNAN_LP		// 云南涞浦
	{"DltUab",UNIT_V100,UNIT_NULL},
	{"DltUbc",UNIT_V100,UNIT_NULL},
	{"DltUca",UNIT_V100,UNIT_NULL},
	{"ArgUab",UNIT_ANG,UNIT_NULL},
	{"ArgUbc",UNIT_ANG,UNIT_NULL},
	{"ArgUca",UNIT_ANG,UNIT_NULL},
#endif
	{"温度",UNIT_TEMP,UNIT_NULL},
#ifdef TMP_CHIP_AHT20
	{"湿度",UNIT_HUMI,UNIT_NULL},
#endif
	{"Ver",UNIT_NULL,UNIT_NULL},
#ifdef BATTERY_WITH_COMM
	{"活化放电时长",UINT_Hour,UNIT_NULL},
	{"当前放电时长",UINT_Hour,UNIT_NULL},
#endif
#ifdef DEV_GPS_ATGM332D
	#ifndef GPS_JWD_SPLIT
	{"经度",UNIT_ANG,UNIT_NULL},
	{"纬度",UNIT_ANG,UNIT_NULL},
	#else
	{"经度-度",UNIT_ANG,UNIT_NULL},
	{"纬度-分",UNIT_ANG,UNIT_NULL},
	{"经度-秒",UNIT_ANG,UNIT_NULL},
	{"纬度-度",UNIT_ANG,UNIT_NULL},
	{"纬度-分",UNIT_ANG,UNIT_NULL},
	{"纬度-秒",UNIT_ANG,UNIT_NULL},
	#endif
	{"卫星个数",UNIT_GE,UNIT_NULL},
#endif
	{"YC1",UNIT_NULL,UNIT_NULL},
	{"YC2",UNIT_NULL,UNIT_NULL},
	{"YC3",UNIT_NULL,UNIT_NULL},
	{"YC4",UNIT_NULL,UNIT_NULL},
	{"YC5",UNIT_NULL,UNIT_NULL},
	{"YC6",UNIT_NULL,UNIT_NULL},
	{"YC7",UNIT_NULL,UNIT_NULL},
	{"YC8",UNIT_NULL,UNIT_NULL},
	{"A相故障电流",UNIT_A5,UNIT_ANG},
	{"B相故障电流",UNIT_A5,UNIT_ANG},
	{"C相故障电流",UNIT_A5,UNIT_ANG},
	{"零序电流",UNIT_A5,UNIT_ANG},
#ifdef BATTERY_BP_L500
	{"电池内阻",UINT_mVperA,UNIT_NULL},
	{"电池温度",UNIT_TEMP,UNIT_NULL},
	{"电池实时电量",UNIT_Per,UNIT_NULL},
	{"电池放电电流",UINT_mA,UNIT_NULL},
	{"电池充电电流",UINT_mA,UNIT_NULL},
#endif
};


/*------------------------------ 函数声明 -------------------------------------
*/
int _sw_cal_mea(void);
void _sw_cal_average(int cal_num);
float _sw_ui_e_k(int index);
void _sw_auto_adjust_pq(void);
void _sw_get_dots(void);
void _sw_cal_fft(void);
void _sw_cal_effect(void);
void _sw_cal_angle(void);
void _sw_cal_ri_correct(void);
void _sw_min_max(int ui_index,u32 *p_min,u32*p_max);
void _fz_min_max(int ui_index1,int ui_index2,u32 *p_min,u32*p_max);
float _sw_base_angle(int ui_index);
int _sw_save_dc_factor(float dc1_H, float dc1_L,float dc2_H, float dc2_L);
void _sw_temp_factor(void);


/*------------------------------ 外部函数 -------------------------------------
外部函数供其它实体文件引用，必须仔细检查传入参数的合法性.
*/
/******************************************************************************
函数名称：	sw_init
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	线路开关初始化
参数说明：
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
int sw_init(void)
{
	int sw,i,type,ui;
	float f;

	// 初始化为固定默认值,只有上电初始化才运行一次
	if(g_sw_init == 0)
	{
		memset(&g_ui,0,sizeof(g_ui));
		memset(&g_sw_pub,0,sizeof(g_sw_pub));
		memset(&g_sw_pub.di,SW_DI_TYPE_OFF,sizeof(g_sw_pub.di));
		memset(&g_sw_pub.di_cfg_index,INDEX_INVALLID,sizeof(g_sw_pub.di_cfg_index));
		memset(&g_sw_pub.do_cfg_index,INDEX_INVALLID,sizeof(g_sw_pub.do_cfg_index));
		memset(&g_sw_pub.ac_cfg_index,INDEX_INVALLID,sizeof(g_sw_pub.ac_cfg_index));
		memset(&g_sw_pub.led_cfg_index,INDEX_INVALLID,sizeof(g_sw_pub.led_cfg_index));

		for(i=0; i< UI_NUM; i++)
		{
			g_ui[i].chn_index = CFG_ADC_CHANNEL_ZERO;
			g_ui[i].ui_base_make = -1;
			g_ui[i].e_factor0 = 1.0 ;
			
			// 使用理论默认值初始化m2_factor_k，防止初始化时使用此值的定值出错，
			// 导致保护逻辑出错(例如，跳位有流告警)
			if(i<PUB_AC_NUM)
			{
				g_ui[i].m2_factor_k = rt_round(factor_e_k(EQU_SCALE_PT_DEFAULT)*Q08_BASE);
			}
			else
			{
				g_ui[i].m2_factor_k = rt_round(factor_e_k(EQU_SCALE_CT_DEFAULT)*Q08_BASE);
			}

			g_ui[i].m2_factor_c = rt_round(1.0*Q16_BASE);
	 	}
		
		for(sw=0; sw<SWITCH_NUM_MAX; sw++)
		{
			memset(&g_sw[sw],0,sizeof(g_sw[i]));
			memset(&g_sw[sw].di,SW_DI_TYPE_OFF,sizeof(g_sw[sw].di));
			memset(&g_sw[sw].di_cfg_index,INDEX_INVALLID,sizeof(g_sw[sw].di_cfg_index));
			memset(&g_sw[sw].do_cfg_index,INDEX_INVALLID,sizeof(g_sw[sw].do_cfg_index));
			memset(&g_sw[sw].ac_cfg_index,INDEX_INVALLID,sizeof(g_sw[sw].ac_cfg_index));
			memset(&g_sw[sw].led_cfg_index,INDEX_INVALLID,sizeof(g_sw[sw].led_cfg_index));
		}
	}
	
	g_sw_init = 0;
	
	// 检查装置配置
	if(equ_config_null())
	{
		return -1;
	}

	// DI通道
	for(i=0; i< g_equ_config->di_num; i++)
	{
		if(g_equ_config_di[i].owner > SWITCH_NUM_MAX)
		{
			rt_printf("switch_init(own):i=%d,owner=%d,SWITCH_NUM_MAX=%d.\r\n",i, g_equ_config_di[i].owner,SWITCH_NUM_MAX);
			continue;
		}

		// 如果是其它类型(type == 0)，不处理
		type = g_equ_config_di[i].type;
		if(type == 0)
		{
			continue;
		}
		type--;
		
		if(g_equ_config_di[i].owner == 0)
		{
			if(type < PUB_DI_NUM)
			{
				g_sw_pub.di_cfg_index[type] = i;
			}
			else
			{
				rt_printf("switch_init(di):i=%d,type=%d,DI_NUM=%d.\r\n",i, type,PUB_DI_NUM);
			}
		}
		else
		{
			sw = g_equ_config_di[i].owner - 1;
			if(type < SW_DI_NUM)
			{
				g_sw[sw].di_cfg_index[type] = i;
			}
			else
			{
				rt_printf("switch_init(di):i=%d,type=%d,DI_NUM=%d,sw=%d.\r\n",i, type,SW_DI_NUM,sw);
			}
		}
	}

	// DO通道
	for(i=0; i< g_equ_config->do_num; i++)
	{
		if(g_equ_config_do[i].owner > SWITCH_NUM_MAX)
		{
			rt_printf("switch_init(own):i=%d,owner=%d,SWITCH_NUM_MAX=%d.\r\n",i, g_equ_config_do[i].owner,SWITCH_NUM_MAX);
			continue;
		}
		
		// 如果是其它类型(type == 0)，不处理
		type = g_equ_config_do[i].type;
		if(type == 0)
		{
			continue;
		}
		type--;
		
		if(g_equ_config_do[i].owner == 0)
		{
			if(type < PUB_DO_NUM)
			{
				g_sw_pub.do_cfg_index[type] = i;
			}
			else if(type < PUB_DO_NUM + PUB_LED_NUM)
			{
				s16 slot,index;
				
				g_sw_pub.led_cfg_index[type-PUB_DO_NUM] = i;

				slot  = g_equ_config_do[i].slot;
				index = g_equ_config_do[i].index;
				
				g_led_slot[slot].sn[index].sw = 0;
				g_led_slot[slot].sn[index].no = type-PUB_DO_NUM;

				index++;
				if(index > g_led_slot[slot].num)
				{
					g_led_slot[slot].num = index;
				}
			}
			else
			{
				rt_printf("switch_init(do):i=%d,type=%d,PUB_DO_NUM + PUB_LED_NUM=%d.\r\n",i, type,PUB_DO_NUM + PUB_LED_NUM);
			}
		}
		else
		{
			sw = g_equ_config_do[i].owner - 1;
			if(type < SW_DO_NUM)
			{
				g_sw[sw].do_cfg_index[type] = i;
			}
			else if(type < SW_DO_LED_NUM)
			{
				s16 slot,index;
				
				g_sw[sw].led_cfg_index[type-SW_DO_NUM] = i;
				
				slot  = g_equ_config_do[i].slot;
				index = g_equ_config_do[i].index;
				
				g_led_slot[slot].sn[index].sw = sw+1;
				g_led_slot[slot].sn[index].no = type-SW_DO_NUM;

				index++;
				if(index > g_led_slot[slot].num)
				{
					g_led_slot[slot].num = index;
				}
			}
			else
			{
				rt_printf("switch_init(do):i=%d,type=%d,SW_DO_LED_NUM=%d,sw=%d.\r\n",i, type,SW_DO_LED_NUM,sw);
			}
		}
	}

	// AC通道
	for(i=0; i< g_equ_config->ac_num; i++)
	{
		if(g_equ_config_ac[i].owner > SWITCH_NUM_MAX)
		{
			rt_printf("switch_init(own):i=%d,owner=%d,SWITCH_NUM_MAX=%d.\r\n",i, g_equ_config_ac[i].owner,SWITCH_NUM_MAX);
			continue;
		}
		
		// 如果是其它类型(type == 0)，不处理
		type = g_equ_config_ac[i].type;
		if(type == 0)
		{
			continue;
		}
		type--;
		
		if(g_equ_config_ac[i].owner == 0)
		{
			if(type < PUB_AC_NUM)
			{
				// 索引
				ui = type;
				g_sw_pub.ac_cfg_index[type] = i;

 			}
			else
			{
				rt_printf("switch_init(ac):i=%d,type=%d,AC_NUM=%d.\r\n",i, g_equ_config_ac[i].type,PUB_AC_NUM);
				continue;
			}
		}
		else
		{
			sw = g_equ_config_ac[i].owner - 1;
			if(type < SW_AC_NUM)
			{
				ui = UI_SW_INDEX(sw,type);
				
				// 索引
				g_sw[sw].ac_cfg_index[type] = i;
			}
			else
			{
				rt_printf("switch_init(ac):i=%d,type=%d,AC_NUM=%d,sw=%d.\r\n",i, type,SW_AC_NUM,sw);
				continue;
			}
		}

		// 通道索引
		g_ui[ui].chn_index = equ_get_ac_channel(g_equ_config_ac[i].slot,g_equ_config_ac[i].index);

		// 系数
		factor_e_c_get(g_equ_config_ac[i].slot,g_equ_config_ac[i].index,&f);
		g_ui[ui].e_factor0 = f /factor_e_k(g_equ_config_ac[i].scale);
		g_ui[ui].m2_factor_k = rt_round(factor_e_k(g_equ_config_ac[i].scale)*Q08_BASE);
	#ifdef PROTECT_AC_ADJUST
		factor_p_e_c_get(g_equ_config_ac[i].slot,g_equ_config_ac[i].index,&f); //保护校准系数
	#endif			
		g_ui[ui].m2_factor_c = rt_round(f*Q16_BASE);
		factor_p_c_get(g_equ_config_ac[i].slot,g_equ_config_ac[i].index,&f);
		g_ui[ui].p_factor = f;
		//一二变比
		g_ui[ui].e_ps = factor_e_ps(equ_get_ac_scale(g_equ_config_ac[i].slot, g_equ_config_ac[i].index));

		// 暂时屏蔽，看看不使用PQ校准的效果
		//factor_pq_get(g_equ_config_ac[i].slot,g_equ_config_ac[i].index,g_ui[ui].pq_factor);
	}


	// 计算角度时的基准通道
	if(g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO)
	{
		g_ui_angle0 = PUB_AC_UA1;
	}
	else if(g_ui[PUB_AC_UAB1].chn_index != CFG_ADC_CHANNEL_ZERO)
	{
		g_ui_angle0	= PUB_AC_UAB1;
	}
	else if(g_ui[PUB_AC_UAB2].chn_index != CFG_ADC_CHANNEL_ZERO)
	{
		g_ui_angle0	= PUB_AC_UAB2;
	}
	else
	{
		g_ui_angle0 = -1;
	}

	// 相电压合成线电压标志
	if(    g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UB1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UC1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UAB1].chn_index == CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UBC1].chn_index == CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UCA1].chn_index == CFG_ADC_CHANNEL_ZERO)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_LV1;

		memcpy(&g_ui[PUB_AC_UAB1],&g_ui[PUB_AC_UA1],sizeof(g_ui[0]));
		g_ui[PUB_AC_UAB1].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UAB1].ui_base_make = PUB_AC_UA1;
		g_ui[PUB_AC_UAB1].e_factor0 = (g_ui[PUB_AC_UA1].e_factor0 + g_ui[PUB_AC_UB1].e_factor0)/2;
		
		memcpy(&g_ui[PUB_AC_UBC1],&g_ui[PUB_AC_UA1],sizeof(g_ui[0]));
		g_ui[PUB_AC_UBC1].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UBC1].ui_base_make = PUB_AC_UA1;
		g_ui[PUB_AC_UBC1].e_factor0 = (g_ui[PUB_AC_UB1].e_factor0 + g_ui[PUB_AC_UC1].e_factor0)/2;
		
		memcpy(&g_ui[PUB_AC_UCA1],&g_ui[PUB_AC_UA1],sizeof(g_ui[0]));
		g_ui[PUB_AC_UCA1].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UCA1].ui_base_make = PUB_AC_UA1;
		g_ui[PUB_AC_UCA1].e_factor0 = (g_ui[PUB_AC_UC1].e_factor0 + g_ui[PUB_AC_UA1].e_factor0)/2;
	}	

	if(g_ui[PUB_AC_UA2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UB2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UC2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UAB2].chn_index == CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UBC2].chn_index == CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UCA2].chn_index == CFG_ADC_CHANNEL_ZERO)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_LV2;
		
		memcpy(&g_ui[PUB_AC_UAB2],&g_ui[PUB_AC_UA2],sizeof(g_ui[0]));
		g_ui[PUB_AC_UAB2].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UAB2].ui_base_make = PUB_AC_UA2;
		g_ui[PUB_AC_UAB2].e_factor0 = (g_ui[PUB_AC_UA2].e_factor0 + g_ui[PUB_AC_UB2].e_factor0)/2;
		
		memcpy(&g_ui[PUB_AC_UBC2],&g_ui[PUB_AC_UA2],sizeof(g_ui[0]));
		g_ui[PUB_AC_UBC2].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UBC2].ui_base_make = PUB_AC_UA2;
		g_ui[PUB_AC_UBC2].e_factor0 = (g_ui[PUB_AC_UB2].e_factor0 + g_ui[PUB_AC_UC2].e_factor0)/2;
		
		memcpy(&g_ui[PUB_AC_UCA2],&g_ui[PUB_AC_UA2],sizeof(g_ui[0]));
		g_ui[PUB_AC_UCA2].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UCA2].ui_base_make = PUB_AC_UA2;
		g_ui[PUB_AC_UCA2].e_factor0 = (g_ui[PUB_AC_UC2].e_factor0 + g_ui[PUB_AC_UA2].e_factor0)/2;
	}	

	// 合成UCA标志
	if(    g_ui[PUB_AC_UAB1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UBC1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UCA1].chn_index == CFG_ADC_CHANNEL_ZERO)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_UCA1;
		memcpy(&g_ui[PUB_AC_UCA1],&g_ui[PUB_AC_UAB1],sizeof(g_ui[0]));
		g_ui[PUB_AC_UCA1].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UCA1].ui_base_make = PUB_AC_UAB1;
		g_ui[PUB_AC_UCA1].e_factor0 = (g_ui[PUB_AC_UAB1].e_factor0 + g_ui[PUB_AC_UBC1].e_factor0)/2;
	}
	
	if(    g_ui[PUB_AC_UAB2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UBC2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UCA2].chn_index == CFG_ADC_CHANNEL_ZERO)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_UCA2;
		memcpy(&g_ui[PUB_AC_UCA2],&g_ui[PUB_AC_UAB2],sizeof(g_ui[0]));
		g_ui[PUB_AC_UCA2].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_UCA2].ui_base_make = PUB_AC_UAB2;
		g_ui[PUB_AC_UCA2].e_factor0 = (g_ui[PUB_AC_UAB2].e_factor0 + g_ui[PUB_AC_UBC2].e_factor0)/2;
	}	

	// U01 零序电压自产
	if(    g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UB1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UC1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_U01].chn_index == CFG_ADC_CHANNEL_ZERO
		&&pRunSet->bTT_U0ZC)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_U01;

		memcpy(&g_ui[PUB_AC_U01],&g_ui[PUB_AC_UA1],sizeof(g_ui[0]));
		g_ui[PUB_AC_U01].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_U01].ui_base_make = PUB_AC_UA1;
		g_ui[PUB_AC_U01].e_factor0 = (g_ui[PUB_AC_UA1].e_factor0 + g_ui[PUB_AC_UB1].e_factor0+g_ui[PUB_AC_UC1].e_factor0)/3;
	}	

	// U02 零序电压自产
	if(    g_ui[PUB_AC_UA2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UB2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UC2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_U02].chn_index == CFG_ADC_CHANNEL_ZERO
		&&pRunSet->bTT_U0ZC)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_U02;

		memcpy(&g_ui[PUB_AC_U02],&g_ui[PUB_AC_UA2],sizeof(g_ui[0]));
		g_ui[PUB_AC_U02].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_U02].ui_base_make = PUB_AC_UA2;
		g_ui[PUB_AC_U02].e_factor0 = (g_ui[PUB_AC_UA2].e_factor0 + g_ui[PUB_AC_UB2].e_factor0+g_ui[PUB_AC_UC2].e_factor0)/3;
	}		

	// 合成IB、I0标志
	for(sw=0; sw<SWITCH_NUM_MAX; sw++)
	{
		if(		g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			g_sw[sw].ui_flags |= UI_FLAGS_MAKE_IB;
			
			memcpy(&g_ui[UI_SW_INDEX(sw,SW_AC_IB)],&g_ui[UI_SW_INDEX(sw,SW_AC_IA)],sizeof(g_ui[0]));
			g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index = CFG_ADC_CHANNEL_ZERO;
			g_ui[UI_SW_INDEX(sw,SW_AC_IB)].ui_base_make = UI_SW_INDEX(sw,SW_AC_IA);
			g_ui[UI_SW_INDEX(sw,SW_AC_IB)].e_factor0 = (g_ui[UI_SW_INDEX(sw,SW_AC_IA)].e_factor0 + g_ui[UI_SW_INDEX(sw,SW_AC_IC)].e_factor0)/2;
		}

		if(		g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_CIC)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_CIB)].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			g_sw[sw].ui_flags |= UI_FLAGS_MAKE_CIB;
			
			memcpy(&g_ui[UI_SW_INDEX(sw,SW_AC_CIB)],&g_ui[UI_SW_INDEX(sw,SW_AC_CIA)],sizeof(g_ui[0]));
			g_ui[UI_SW_INDEX(sw,SW_AC_CIB)].chn_index = CFG_ADC_CHANNEL_ZERO;
			g_ui[UI_SW_INDEX(sw,SW_AC_CIB)].ui_base_make = UI_SW_INDEX(sw,SW_AC_CIA);
			g_ui[UI_SW_INDEX(sw,SW_AC_CIB)].e_factor0 = (g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].e_factor0 + g_ui[UI_SW_INDEX(sw,SW_AC_CIC)].e_factor0)/2;
		}
	
		if(		g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index != CFG_ADC_CHANNEL_ZERO
			&& 	g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			g_sw[sw].ui_flags |= UI_FLAGS_MAKE_I0;
			
			memcpy(&g_ui[UI_SW_INDEX(sw,SW_AC_I0)],&g_ui[UI_SW_INDEX(sw,SW_AC_IA)],sizeof(g_ui[0]));
			g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index = CFG_ADC_CHANNEL_ZERO;
			g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ui_base_make = UI_SW_INDEX(sw,SW_AC_IA);
			g_ui[UI_SW_INDEX(sw,SW_AC_I0)].e_factor0 =   (g_ui[UI_SW_INDEX(sw,SW_AC_IA)].e_factor0 
														+ g_ui[UI_SW_INDEX(sw,SW_AC_IB)].e_factor0
														+ g_ui[UI_SW_INDEX(sw,SW_AC_IC)].e_factor0)/3;
			
		}
	}

#if 0 // 支持功率电压选择，计算方法等计算时再确定
	// 确认是3表法还是2表法
	for(sw=0; sw<SWITCH_NUM_MAX; sw++)
	{
		if(g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO
			&& g_ui[PUB_AC_UB1].chn_index != CFG_ADC_CHANNEL_ZERO
			&& g_ui[PUB_AC_UC1].chn_index != CFG_ADC_CHANNEL_ZERO)
		{

			if(	   g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index != CFG_ADC_CHANNEL_ZERO
				&& g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index != CFG_ADC_CHANNEL_ZERO
				&& g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index != CFG_ADC_CHANNEL_ZERO)
			{
				g_sw[sw].ui_flags |= UI_FLAGS_3M;
			}
		}
	}
#endif

	//通道名称
	for(i=0; i< UI_NUM; i++)
	{
		if(i< PUB_AC_NUM)
		{
			if(strlen(g_pub_ac_desc[i].name) < CFG_NAME_LEN)
				strcpy(g_ui[i].name, g_pub_ac_desc[i].name);
			else
				strncpy(g_ui[i].name, g_pub_ac_desc[i].name,CFG_NAME_LEN);
		}
		else
		{
			sw = (i-PUB_AC_NUM)/SW_AC_NUM;
			sprintf(g_ui[i].name,"%02d%s",sw+1,g_sw_ac_desc[(i-PUB_AC_NUM)%SW_AC_NUM].name);
		}

	}

	// 复位统计数据
	sw_stat_reset();

 	g_sw_init = 1;

	return 0;
}

 int sw_ext_init(void)
 {
	// U01 零序电压自产
	if(    g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UB1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UC1].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_U01].chn_index == CFG_ADC_CHANNEL_ZERO
		&&pRunSet->bTT_U0ZC)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_U01;
		memcpy(&g_ui[PUB_AC_U01],&g_ui[PUB_AC_UA1],sizeof(g_ui[0]));
		g_ui[PUB_AC_U01].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_U01].ui_base_make = PUB_AC_UA1;
		g_ui[PUB_AC_U01].e_factor0 = (g_ui[PUB_AC_UA1].e_factor0 + g_ui[PUB_AC_UB1].e_factor0+g_ui[PUB_AC_UC1].e_factor0)/3;

	}
	// U02 零序电压自产
	if(    g_ui[PUB_AC_UA2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UB2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_UC2].chn_index != CFG_ADC_CHANNEL_ZERO
		&& g_ui[PUB_AC_U02].chn_index == CFG_ADC_CHANNEL_ZERO
		&&pRunSet->bTT_U0ZC)
	{
		g_sw_pub.ui_flags |= UI_FLAGS_MAKE_U02;
		memcpy(&g_ui[PUB_AC_U02],&g_ui[PUB_AC_UA2],sizeof(g_ui[0]));
		g_ui[PUB_AC_U02].chn_index = CFG_ADC_CHANNEL_ZERO;
		g_ui[PUB_AC_U02].ui_base_make = PUB_AC_UA2;
		g_ui[PUB_AC_U02].e_factor0 = (g_ui[PUB_AC_UA2].e_factor0 + g_ui[PUB_AC_UB2].e_factor0+g_ui[PUB_AC_UC2].e_factor0)/3;
	}		
	return 0;

 }

/******************************************************************************
函数名称：	sw_exit
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	线路开关退出
参数说明：
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
int sw_exit(void)
{

	return 0;
}

int sw_di_get(u32 sw,u32 no)
{
	u8  v;
	if(no == 0)
	{
		return -1;
	}
	no--;

	if(sw == 0)
	{
		v=g_sw_pub.di[no] ;
	}
	else
	{
		sw--;
		v=g_sw[sw].di[no] ;	
	}

	return v;
}


int sw_di_set(u32 sw,u32 no,u8 v)
{
	if(no == 0)
	{
		return -1;
	}
	no--;

	if(sw == 0)
	{
		g_sw_pub.di[no] = v;
	}
	else
	{
		sw--;
		g_sw[sw].di[no] = v;	
	}

	return 0;
}

/******************************************************************************
函数名称：	sw_do
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	针对线路开关执行开出动作
参数说明：
	sw		开关序号
	index	开出索引
	type	开出类型
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
static int _sw_do(u32 slot,u32 index,int type)
{
	int ret,do_num;
	
	do_num = equ_get_do_num(slot);
	if(do_num == 0)
	{
		return -1;
	}

	// 将辅助板的4个开出(64~67)映射到(0~3),
	// 解决32位宽度不够的问题，这样LED灯不允许配置成开出。
	// 其它板不存在这个问题，例如开出板只有16个开出可配
	if((g_board_info[slot].type == BOARD_TYPE_AUX) || (g_board_info[slot].type == BOARD_TYPE_ZT))
	{
		index = index%32; 
	}
	
	ret = 0;
	switch(type)
	{
	case SW_DO_TYPE_OFF:
	case SW_DO_TYPE_ON:
		ret = dido_do(slot,(1<<index),type);
		break;
		
	case SW_DO_TYPE_SELECT_ON:
		if(dido_do_have_select(slot,index))
		{
			ret = dido_do(slot,(1<<do_num),1);
		}
		break;
		
	case SW_DO_TYPE_SELECT_OFF:
		if(dido_do_have_select(slot,index))
		{
			ret = dido_do(slot,(1<<do_num),0);
		}
		break;
		
	default:
		ret = -3;
		break;
	}

	return ret;
}

int sw_do(u32 sw,u32 index,int type)
{
	int ret;
	u32 slot;
	TRELAY_T *pR=&g_tRelay[sw];

	if((index == SW_DO_HZ || index == SW_DO_YKH || index == SW_DO_BHH) && (type == SW_DO_TYPE_ON))
	{
		if(pR->run_stu.sw==1)
		{
			pR->uRmtSW.bHz_Doing = 1;
		#ifdef FUNC_DRIVE
			gb_drive.bHz_Doing = 1;
		#endif
		}
		pR->uRmtSW.bTz_Doing = 0;
	#ifdef FUNC_DRIVE
		gb_drive.bTz_Doing = 0;
	#endif
	}
	if((index == SW_DO_FZ || index == SW_DO_YKT || index == SW_DO_BHT) && (type == SW_DO_TYPE_ON))
	{
		if(pR->run_stu.sw==2)
		{
			pR->uRmtSW.bTz_Doing = 1;
		#ifdef FUNC_DRIVE
			gb_drive.bTz_Doing = 1;
		#endif
		}
		pR->uRmtSW.bHz_Doing = 0;
	#ifdef FUNC_DRIVE
		gb_drive.bHz_Doing = 0;
	#endif
	}
	if(sw >= SWITCH_NUM_MAX || index >=SW_DO_NUM)
	{
		return -1;
	}

	// 气压低闭锁分合闸
	if(pRunSet->tSwSet[sw].bTT_QYD_BS 
		&& (g_sw[sw].di[SW_DI_QYD_BS] == SW_DI_TYPE_ON)
		&& (index == SW_DO_HZ || index == SW_DO_FZ||index == SW_DO_YKH||index == SW_DO_YKT||index ==SW_DO_BHH||index ==SW_DO_BHT))
	{
		return -2;
	}

	// 需要通道有配置
	index  = g_sw[sw].do_cfg_index[index];
	if(index == INDEX_INVALLID || index >= g_equ_config->do_num)
	{
		return -3;
	}

	slot = g_equ_config_do[index].slot;
	index = g_equ_config_do[index].index;

	ret = _sw_do(slot,index,type);
	
	return ret;
}


/******************************************************************************
函数名称：	sw_do_pub
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	针对线路开关公共部门执行开出动作
参数说明：
	index	开出索引
	type	开出类型
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
int sw_do_pub(u32 index,int type)
{
	int ret;
	u32 slot;
	
	if(index >=PUB_DO_NUM)
	{
		return -1;
	}

	index  = g_sw_pub.do_cfg_index[index];
	if(index == INDEX_INVALLID || index >= g_equ_config->do_num)
	{
		return -2;
	}

	slot = g_equ_config_do[index].slot;
	index = g_equ_config_do[index].index;

	ret = _sw_do(slot,index,type);

	return ret;
}


/******************************************************************************
函数名称：	sw_do_yk
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	预控继电器开出
参数说明：
	index	开出索引
	type	开出类型
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
int sw_do_yuk(int type)
{
	int ret;
	u32 slot;
	int index;	

	index  = g_sw_pub.do_cfg_index[PUB_DO_YK];
	if(index == INDEX_INVALLID || index >= g_equ_config->do_num)
	{
		return -2;
	}

	slot = g_equ_config_do[index].slot;
	index = g_equ_config_do[index].index;

	ret = _sw_do(slot,index,type);

	return ret;
}




/******************************************************************************
函数名称：	sw_v_m2_factor_k
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	得到一个保护定值计算用的理论转化系数。目前假设所有电压的系数都是一样，
			从第一组电压中取出一个。
参数说明：
返回值：	
修改记录：	
*/
float sw_v_m2_factor_k(int id)
{

	if(id < PUB_AC_NUM)
	{
		if(id == PUB_AC_US1)
		{
			if((short)g_sw_pub.ac_cfg_index[PUB_AC_US1] == INDEX_INVALLID)
			{
				return g_ui[PUB_AC_UAB1].m2_factor_k;
			}
			else
			{
				if(g_ui[id].chn_index != CFG_ADC_CHANNEL_ZERO)
				{
					return g_ui[id].m2_factor_k;
				}
			}
		}
		else if(id == PUB_AC_US2)
		{
			if((short)g_sw_pub.ac_cfg_index[PUB_AC_US2] == INDEX_INVALLID)
			{
				return g_ui[PUB_AC_UBC2].m2_factor_k;
			}
			else
			{
				if(g_ui[id].chn_index != CFG_ADC_CHANNEL_ZERO)
				{
					return g_ui[id].m2_factor_k;
				}
			}
		}
		else if(id == PUB_AC_U01)
		{
			if(g_ui[id].chn_index == CFG_ADC_CHANNEL_ZERO)
				
			{
				return g_ui[PUB_AC_UA1].m2_factor_k;
			}
			else
			{
				if(g_ui[id].chn_index != CFG_ADC_CHANNEL_ZERO)
				{
					return g_ui[id].m2_factor_k;
				}
			}
		}
		else if(id == PUB_AC_U02)
		{
			if(g_ui[id].chn_index == CFG_ADC_CHANNEL_ZERO)
			{
				return g_ui[PUB_AC_UA2].m2_factor_k;
			}
			else
			{
				if(g_ui[id].chn_index != CFG_ADC_CHANNEL_ZERO)
				{
					return g_ui[id].m2_factor_k;
				}
			}
		}
		else
		{
			//if(g_ui[id].chn_index != CFG_ADC_CHANNEL_ZERO)
			//{
				return g_ui[id].m2_factor_k;
			//}
		}
		
	}

	return 1.0;
}

#ifdef FUNC_DRIVE_JY
static void drive_ui_proc(void)
{
	int i=0,sw=0;
	TSETSW *pSet = &pRunSet->tSwSet[sw];

	if(!gb_drive.b_drive_on)
	{
		return;
	}
	
	for(i=0;i<1;i++)//保护遥测值
	{
		if(!gb_drive.tDriveUa1Time.boolTrip)
		{
			g_ui[PUB_AC_UA1].m2[i] = GetSetSQR(pSet->dU_drive_ua1,(pRunSet->dKU[PUB_AC_UA1]/256.0));
			g_ui[PUB_AC_UB1].m2[i] = GetSetSQR(pSet->dU_drive_ua1,(pRunSet->dKU[PUB_AC_UB1]/256.0));
			g_ui[PUB_AC_UC1].m2[i] = GetSetSQR(pSet->dU_drive_ua1,(pRunSet->dKU[PUB_AC_UC1]/256.0));
			g_ui[PUB_AC_UAB1].m2[i] = GetSetSQR(pSet->dU_drive_ua1,(pRunSet->dKU[PUB_AC_UAB1]/256.0));
			g_ui[PUB_AC_UBC1].m2[i] = GetSetSQR(pSet->dU_drive_ua1,(pRunSet->dKU[PUB_AC_UBC1]/256.0));
			g_ui[PUB_AC_UCA1].m2[i] = GetSetSQR(pSet->dU_drive_ua1,(pRunSet->dKU[PUB_AC_UCA1]/256.0));
		}

		if(!gb_drive.tDriveUa2Time.boolTrip)
		{
			g_ui[PUB_AC_UA2].m2[i] = GetSetSQR(pSet->dU_drive_ua2,(pRunSet->dKU[PUB_AC_UA2]/256.0));
			g_ui[PUB_AC_UB2].m2[i] = GetSetSQR(pSet->dU_drive_ua2,(pRunSet->dKU[PUB_AC_UB2]/256.0));
			g_ui[PUB_AC_UC2].m2[i] = GetSetSQR(pSet->dU_drive_ua2,(pRunSet->dKU[PUB_AC_UC2]/256.0));
			g_ui[PUB_AC_UAB2].m2[i] = GetSetSQR(pSet->dU_drive_ua2,(pRunSet->dKU[PUB_AC_UAB2]/256.0));
			g_ui[PUB_AC_UBC2].m2[i] = GetSetSQR(pSet->dU_drive_ua2,(pRunSet->dKU[PUB_AC_UBC2]/256.0));
			g_ui[PUB_AC_UCA2].m2[i] = GetSetSQR(pSet->dU_drive_ua2,(pRunSet->dKU[PUB_AC_UCA2]/256.0));
		}

		if(!gb_drive.tDriveU0Time.boolTrip)
		{
			g_ui[PUB_AC_U01].m2[i] = GetSetSQR(pSet->dU_drive_u0,(pRunSet->dKU[PUB_AC_U01]/256.0));
		}

		if(!gb_drive.tDriveITime.boolTrip)
		{
			g_ui[UI_SW_INDEX_BEGIN(sw)+SW_AC_IA].m2[i] = GetSetSQR(pSet->dU_drive_i,(g_ui[UI_SW_INDEX_BEGIN(sw)+SW_AC_IA].m2_factor_k/256.0));
		}
		
		if(!gb_drive.tDriveI0Time.boolTrip)
		{
			g_ui[UI_SW_INDEX_BEGIN(sw)+SW_AC_I0].m2[i] = GetSetSQR(pSet->dU_drive_i0,(g_ui[UI_SW_INDEX_BEGIN(sw)+SW_AC_I0].m2_factor_k/256.0));
		}
	}

	#if 0
	//测量显示遥测值
	g_sw_pub.ac_in[PUB_AC_UA1] =(pSet->dU_drive_ua1*Q16_BASE);
	g_sw_pub.ac_in[PUB_AC_UAB1] =(pSet->dU_drive_ua1*Q16_BASE);
	
	g_sw_pub.ac_in[PUB_AC_UA2] =(pSet->dU_drive_ua2*Q16_BASE);
	g_sw_pub.ac_in[PUB_AC_UAB2] =(pSet->dU_drive_ua2*Q16_BASE);
	
	g_sw_pub.ac_in[PUB_AC_U01] =  (qs16)(pSet->dU_drive_u0*Q16_BASE);

	g_sw[sw].ac_in[SW_AC_IA] =  (qs16)(pSet->dU_drive_i*Q16_BASE);
	g_sw[sw].ac_in[SW_AC_I0] =  (qs16)(pSet->dU_drive_i0*Q16_BASE);
	#endif
}
#endif

/******************************************************************************
函数名称：	sw_cal_protect
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	在保护5ms中断中计算基波的值。
参数说明：
返回值：	
修改记录：	
*/
void sw_cal_protect(void)
{
	int sw,i,index ;
	short *psam;
	
	qs08 angle;
	qs16 lncos,lnsin;

	struct ri_s16 ri16;
	struct ri_s16 ri16_2;
	struct ri_s32 ri;
	struct ri_s32 ri_2[2];

	// 更新保护计算时采样点的索引
	g_prot_index=g_adc_dots_index;
	extern DWORD dTcounterrem;
	dTcounterrem=dTCounter;
	
	// 计算模值平方
	for(i=0; i<UI_NUM; i++)
	{
		// 如果索引通道不存在，不需计算
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			continue;
		}

		// 检查硬件通道是否正常，如果不正常，ri清零；否则计算出ri。
		if(equ_ac_channel_is_ok(g_ui[i].chn_index) == 0)
		{
			ri16.r = 0;
			ri16.i = 0;
			ri16_2.r = 0;
			ri16_2.i = 0;			
		}
		else
		{
			psam = adc_fourier_address(g_ui[i].chn_index,g_prot_index);    
			
			// 基波FFT
			fourier32(psam, &ri16, FOURIER_HARMONIC_1);
			
			// 二次谐波FFT
			if (i >= PUB_AC_NUM)
			{
				fourier32(psam, &ri16_2, FOURIER_HARMONIC_2);
			}
		}
		
		//基波计算
		ri.r = _MulFac_S(ri16.r,g_ui[i].m2_factor_c);	//	电压电流实部
		ri.i = _MulFac_S(ri16.i,g_ui[i].m2_factor_c);	//	电压电流虚部

	  	angle = rt_round((g_ui[i].p_factor + factor_p_k(g_ui[i].chn_index))*256);
      	lncos = mCos(angle);
    	lnsin = mSin(angle);
	
      	g_ui[i].ri.r = _MulFac_S(ri.r,lncos) - _MulFac_S(ri.i,lnsin);
    	g_ui[i].ri.i = _MulFac_S(ri.r,lnsin) + _MulFac_S(ri.i,lncos);
		
		g_ui[i].m2[0] = SQR(g_ui[i].ri.r,g_ui[i].ri.i);		//	电压电流平方和
		rt_stat_in(&g_ui[i].m2_stat,g_ui[i].m2[0]);

		//二次谐波计算
		if (i >= PUB_AC_NUM)
		{
			ri_2[0].r = _MulFac_S(ri16_2.r,g_ui[i].m2_factor_c);	//	电压电流实部
			ri_2[0].i = _MulFac_S(ri16_2.i,g_ui[i].m2_factor_c);	//	电压电流虚部
#if 0
		  	angle = rt_round(g_ui[i].p_factor*256);
	      	lncos = mCos(angle);
	    	lnsin = mSin(angle);
#endif		
	      	ri_2[1].r = _MulFac_S(ri_2[0].r,lncos) - _MulFac_S(ri_2[0].i,lnsin);
	    	ri_2[1].i = _MulFac_S(ri_2[0].r,lnsin) + _MulFac_S(ri_2[0].i,lncos);
			
			g_ui[i].m2[1] = SQR(ri_2[1].r,ri_2[1].i);		//	电压电流平方和
		}
	}
	#ifdef GD_AREA_ECZD_2020
	//计算正序和负序电压	
	//US1
	if((g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO)&&(g_ui[PUB_AC_UB1].chn_index != CFG_ADC_CHANNEL_ZERO)&&(g_ui[PUB_AC_UC1].chn_index != CFG_ADC_CHANNEL_ZERO))
	{			
		_sw_cal_Xfl120(PUB_AC_UA1, &Us1_120);
	}
	else
	{
		Us2_120.vect1=0;
		Us2_120.vect2=0;
	}
	//US2
	if((g_ui[PUB_AC_UA2].chn_index != CFG_ADC_CHANNEL_ZERO)&&(g_ui[PUB_AC_UB2].chn_index != CFG_ADC_CHANNEL_ZERO)&&(g_ui[PUB_AC_UC2].chn_index != CFG_ADC_CHANNEL_ZERO))
	{			
		_sw_cal_Xfl120(PUB_AC_UA2, &Us2_120);
	}
	else
	{
		Us2_120.vect1=0;
		Us2_120.vect2=0;
	}
	#endif
	// 合成线电压1
	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_LV1)
	{
		g_ui[PUB_AC_UAB1].ri.r = g_ui[PUB_AC_UA1].ri.r - g_ui[PUB_AC_UB1].ri.r;
		g_ui[PUB_AC_UAB1].ri.i = g_ui[PUB_AC_UA1].ri.i - g_ui[PUB_AC_UB1].ri.i;
		g_ui[PUB_AC_UAB1].m2[0] = SQR(g_ui[PUB_AC_UAB1].ri.r,g_ui[PUB_AC_UAB1].ri.i);	
		rt_stat_in(&g_ui[PUB_AC_UAB1].m2_stat,g_ui[PUB_AC_UAB1].m2[0]);
		
		g_ui[PUB_AC_UBC1].ri.r = g_ui[PUB_AC_UB1].ri.r - g_ui[PUB_AC_UC1].ri.r;
		g_ui[PUB_AC_UBC1].ri.i = g_ui[PUB_AC_UB1].ri.i - g_ui[PUB_AC_UC1].ri.i;
		g_ui[PUB_AC_UBC1].m2[0] = SQR(g_ui[PUB_AC_UBC1].ri.r,g_ui[PUB_AC_UBC1].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UBC1].m2_stat,g_ui[PUB_AC_UBC1].m2[0]);
		
		g_ui[PUB_AC_UCA1].ri.r = g_ui[PUB_AC_UC1].ri.r - g_ui[PUB_AC_UA1].ri.r;
		g_ui[PUB_AC_UCA1].ri.i = g_ui[PUB_AC_UC1].ri.i - g_ui[PUB_AC_UA1].ri.i;
		g_ui[PUB_AC_UCA1].m2[0] = SQR(g_ui[PUB_AC_UCA1].ri.r,g_ui[PUB_AC_UCA1].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UCA1].m2_stat,g_ui[PUB_AC_UCA1].m2[0]);
	}	

	// 合成线电压2
	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_LV2)
	{
		g_ui[PUB_AC_UAB2].ri.r = g_ui[PUB_AC_UA2].ri.r - g_ui[PUB_AC_UB2].ri.r;
		g_ui[PUB_AC_UAB2].ri.i = g_ui[PUB_AC_UA2].ri.i - g_ui[PUB_AC_UB2].ri.i;
		g_ui[PUB_AC_UAB2].m2[0] = SQR(g_ui[PUB_AC_UAB2].ri.r,g_ui[PUB_AC_UAB2].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UAB2].m2_stat,g_ui[PUB_AC_UAB2].m2[0]);
		
		g_ui[PUB_AC_UBC2].ri.r = g_ui[PUB_AC_UB2].ri.r - g_ui[PUB_AC_UC2].ri.r;
		g_ui[PUB_AC_UBC2].ri.i = g_ui[PUB_AC_UB2].ri.i - g_ui[PUB_AC_UC2].ri.i;
		g_ui[PUB_AC_UBC2].m2[0] = SQR(g_ui[PUB_AC_UBC2].ri.r,g_ui[PUB_AC_UBC2].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UBC2].m2_stat,g_ui[PUB_AC_UBC2].m2[0]);
		
		g_ui[PUB_AC_UCA2].ri.r = g_ui[PUB_AC_UC2].ri.r - g_ui[PUB_AC_UA2].ri.r;
		g_ui[PUB_AC_UCA2].ri.i = g_ui[PUB_AC_UC2].ri.i - g_ui[PUB_AC_UA2].ri.i;
		g_ui[PUB_AC_UCA2].m2[0] = SQR(g_ui[PUB_AC_UCA2].ri.r,g_ui[PUB_AC_UCA2].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UCA2].m2_stat,g_ui[PUB_AC_UCA2].m2[0]);
	}	

	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_UCA1)  // 合成线电压UCA1
	{
		g_ui[PUB_AC_UCA1].ri.r =- g_ui[PUB_AC_UAB1].ri.r - g_ui[PUB_AC_UBC1].ri.r;
		g_ui[PUB_AC_UCA1].ri.i =- g_ui[PUB_AC_UAB1].ri.i - g_ui[PUB_AC_UBC1].ri.i;
		g_ui[PUB_AC_UCA1].m2[0] = SQR(g_ui[PUB_AC_UCA1].ri.r,g_ui[PUB_AC_UCA1].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UCA1].m2_stat,g_ui[PUB_AC_UCA1].m2[0]);
 	}	

	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_UCA2)  // 合成线电压UCA1
	{
		g_ui[PUB_AC_UCA2].ri.r =- g_ui[PUB_AC_UAB2].ri.r - g_ui[PUB_AC_UBC2].ri.r;
		g_ui[PUB_AC_UCA2].ri.i =- g_ui[PUB_AC_UAB2].ri.i - g_ui[PUB_AC_UBC2].ri.i;
		g_ui[PUB_AC_UCA2].m2[0] = SQR(g_ui[PUB_AC_UCA2].ri.r,g_ui[PUB_AC_UCA2].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_UCA1].m2_stat,g_ui[PUB_AC_UCA2].m2[0]);
 	}	

	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_U01)
	{
		g_ui[PUB_AC_U01].ri.r = g_ui[PUB_AC_UA1].ri.r + g_ui[PUB_AC_UB1].ri.r+ g_ui[PUB_AC_UC1].ri.r;
		g_ui[PUB_AC_U01].ri.i = g_ui[PUB_AC_UA1].ri.i + g_ui[PUB_AC_UB1].ri.i+ g_ui[PUB_AC_UC1].ri.i;
		g_ui[PUB_AC_U01].m2[0] = SQR(g_ui[PUB_AC_U01].ri.r,g_ui[PUB_AC_U01].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_U01].m2_stat,g_ui[PUB_AC_U01].m2[0]);
 	}	

 	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_U02)
	{
		g_ui[PUB_AC_U02].ri.r = g_ui[PUB_AC_UA2].ri.r + g_ui[PUB_AC_UB2].ri.r+ g_ui[PUB_AC_UC2].ri.r;
		g_ui[PUB_AC_U02].ri.i = g_ui[PUB_AC_UA2].ri.i + g_ui[PUB_AC_UB2].ri.i+ g_ui[PUB_AC_UC2].ri.i;
		g_ui[PUB_AC_U02].m2[0] = SQR(g_ui[PUB_AC_U02].ri.r,g_ui[PUB_AC_U02].ri.i);		
		rt_stat_in(&g_ui[PUB_AC_U02].m2_stat,g_ui[PUB_AC_U02].m2[0]);
 	}	

	// 合成电流
	for(sw=0; sw<g_sw_num; sw++)
	{
		// IB
		if(g_sw[sw].ui_flags&UI_FLAGS_MAKE_IB)
		{
			index = UI_SW_INDEX(sw,SW_AC_IB);
			g_ui[index].ri.r = -g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.r - g_ui[UI_SW_INDEX(sw,SW_AC_IC)].ri.r;
			g_ui[index].ri.i = -g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.i - g_ui[UI_SW_INDEX(sw,SW_AC_IC)].ri.i;
			g_ui[index].m2[0] = SQR(g_ui[index].ri.r,g_ui[index].ri.i);		
			rt_stat_in(&g_ui[index].m2_stat,g_ui[index].m2[0]);
		}

		// I0
		if(g_sw[sw].ui_flags&UI_FLAGS_MAKE_I0)
		{
			index = UI_SW_INDEX(sw,SW_AC_I0);
			g_ui[index].ri.r = g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.r  + g_ui[UI_SW_INDEX(sw,SW_AC_IB)].ri.r + g_ui[UI_SW_INDEX(sw,SW_AC_IC)].ri.r;
			g_ui[index].ri.i = g_ui[UI_SW_INDEX(sw,SW_AC_IA)].ri.i  + g_ui[UI_SW_INDEX(sw,SW_AC_IB)].ri.i + g_ui[UI_SW_INDEX(sw,SW_AC_IC)].ri.i;
			g_ui[index].m2[0] = SQR(g_ui[index].ri.r,g_ui[index].ri.i);		
			rt_stat_in(&g_ui[index].m2_stat,g_ui[index].m2[0]);
		}

	#ifdef FUN_JDXX
		//计算零序有功无功
		if(pRunSet->tSwSet[sw].bTT_Power_v2 == 0)
		{
			if(g_ui[PUB_AC_U01].chn_index != CFG_ADC_CHANNEL_ZERO)
			{
				if(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index != CFG_ADC_CHANNEL_ZERO)
				{			
					g_ui_p0[sw].p= _sw_p2(g_ui[PUB_AC_U01].ri.r,g_ui[PUB_AC_U01].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.i,g_ui[PUB_AC_U01].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].e_factor);
					g_ui_p0[sw].q= _sw_q2(g_ui[PUB_AC_U01].ri.r,g_ui[PUB_AC_U01].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.i,g_ui[PUB_AC_U01].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].e_factor);
				}	
				if(g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].chn_index != CFG_ADC_CHANNEL_ZERO)
				{			
					g_ui_p0[sw].ps= _sw_p2(g_ui[PUB_AC_U01].ri.r,g_ui[PUB_AC_U01].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.i,g_ui[PUB_AC_U01].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].e_factor);
					g_ui_p0[sw].qs= _sw_q2(g_ui[PUB_AC_U01].ri.r,g_ui[PUB_AC_U01].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.i,g_ui[PUB_AC_U01].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].e_factor);
				}	
			}
			else
			{
				g_ui_p0[sw].p=0;g_ui_p0[sw].q=0;
				g_ui_p0[sw].ps=0;g_ui_p0[sw].qs=0;
			}
		}
		else
		{
			if(g_ui[PUB_AC_U02].chn_index != CFG_ADC_CHANNEL_ZERO)
			{
				if(g_ui[UI_SW_INDEX(sw,SW_AC_I0)].chn_index != CFG_ADC_CHANNEL_ZERO)
				{			
					g_ui_p0[sw].p= _sw_p2(g_ui[PUB_AC_U02].ri.r,g_ui[PUB_AC_U02].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.i,g_ui[PUB_AC_U02].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].e_factor);
					g_ui_p0[sw].q= _sw_q2(g_ui[PUB_AC_U02].ri.r,g_ui[PUB_AC_U02].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].ri.i,g_ui[PUB_AC_U02].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0)].e_factor);
				}	
				if(g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].chn_index != CFG_ADC_CHANNEL_ZERO)
				{			
					g_ui_p0[sw].ps= _sw_p2(g_ui[PUB_AC_U02].ri.r,g_ui[PUB_AC_U02].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.i,g_ui[PUB_AC_U02].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].e_factor);
					g_ui_p0[sw].qs= _sw_q2(g_ui[PUB_AC_U02].ri.r,g_ui[PUB_AC_U02].ri.i,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.r,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].ri.i,g_ui[PUB_AC_U02].e_factor,g_ui[UI_SW_INDEX(sw,SW_AC_I0s)].e_factor);
				}	
			}
			else
			{
				g_ui_p0[sw].p=0;g_ui_p0[sw].q=0;
				g_ui_p0[sw].ps=0;g_ui_p0[sw].qs=0;
			}
		}
	#endif
	}

	// 仅线电压需计算幅值
	for(i=PUB_AC_UA1; i<PUB_AC_NUM; i++)
	{
		g_ui[i].fz = _AmXY(g_ui[i].ri.r,g_ui[i].ri.i);
	}

#ifdef FUNC_DRIVE_JY
	drive_ui_proc();
#endif

	// 计算最大最小值
	_sw_min_max(PUB_AC_UA1,&g_sw_pub.m2_min[0],&g_sw_pub.m2_max[0]);
	_sw_min_max(PUB_AC_UAB1,&g_sw_pub.m2_min[2],&g_sw_pub.m2_max[2]);
	_sw_min_max(PUB_AC_UAB2,&g_sw_pub.m2_min[3],&g_sw_pub.m2_max[3]);
	
	_fz_min_max(PUB_AC_UAB1,PUB_AC_UCA1,&g_sw_pub.fz_min[0],&g_sw_pub.fz_max[0]);
	_fz_min_max(PUB_AC_UAB2,PUB_AC_UCA2,&g_sw_pub.fz_min[1],&g_sw_pub.fz_max[1]);

	for(sw=0; sw<g_sw_num; sw++)
	{
		for(i=UI_SW_INDEX(sw,SW_AC_IA); i<=UI_SW_INDEX(sw,SW_AC_IC); i++)
		{
			g_ui[i].fz = _AmXY(g_ui[i].ri.r,g_ui[i].ri.i);
		}	
		_sw_min_max(UI_SW_INDEX_BEGIN(sw),&g_sw[sw].m2_min,&g_sw[sw].m2_max);
		_fz_min_max(UI_SW_INDEX(sw,SW_AC_IA),UI_SW_INDEX(sw,SW_AC_IC),&g_sw[sw].fz_min,&g_sw[sw].fz_max);
	}
	return;
}


/******************************************************************************
函数名称：	sw_cal_app
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	在测量线程中计算测量值
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_zl(void);
int sw_cal_app(void )
{
	_sw_temp_factor();
	if(_sw_cal_mea() != 0)
	{
		return 0;
	}

	// 如果没有达到累计次数，直接返回。
	g_mea_cnt++;
	if(g_mea_cnt < MEA_CAL_NUMBER)  
	{
		return 0;
	}
	g_mea_cnt = 0;

	_sw_cal_average(MEA_CAL_NUMBER);

	return 0;
}
void sw_factor_cp(void)  //保存校正的系数，根据第一路电流的配置，是按CT默认100A校正还是51欧校正
{
	bool b100A=false;
	bool b50A=false;
	bool b20A=false;
	bool b10A=false;	
	int i;
	for(i=0; i< g_equ_config->ac_num; i++)
	{
		if(g_equ_config_ac[i].owner ==1&&g_equ_config_ac[i].type==(SW_AC_IA+1))  // 根据开关1 IA的配置，保存相关的参数
		{
	
			if(g_equ_config_ac[i].scale==EQU_SCALE_CT_DEFAULT)
			{
				b100A=true;
			}
			if(g_equ_config_ac[i].scale==EQU_SCALE_CT_10A_51)
			{
				b50A=true;
			}

			if(g_equ_config_ac[i].scale==EQU_SCALE_CT_10A_249)
			{
				b20A=true;
			}
			if(g_equ_config_ac[i].scale==EQU_SCALE_CT_10A_120)
			{
				b10A=true;
			}
			
			if(b100A)
			{
				rt_file_cp("/app/data/acfactor.bin","/app/data/acfactor_100A.bin");
			}
			if(b50A)
			{
				rt_file_cp("/app/data/acfactor.bin","/app/data/acfactor_50A.bin");
			}

			if(b20A)
			{
				rt_file_cp("/app/data/acfactor.bin","/app/data/acfactor_20A.bin");
			}
			if(b10A)
			{
				rt_file_cp("/app/data/acfactor.bin","/app/data/acfactor_10A.bin");
			}
			
			return;
		}
	}
	
}


/******************************************************************************
函数名称：	sw_auto_adjust
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	自动校准程序
			U 100V,I 5A,
参数说明：
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
struct pq_factor
{
	int cfg_index;
	float pq[2];
};
struct pq_factor g_pq_factor[SWITCH_NUM_MAX][3];
int sw_auto_adjust(int ui_angle0)
{
	float baseAng;  

	int ret,i,j,sw;
	int cfg_index;
	float factor;
	float fv;
	float minfv,maxfv;
	float baseValue ;  
	u16 base_v=0,base_i=0;
#ifdef PROTECT_AC_ADJUST
	float fv_p;
#endif

	g_mea_cnt= 0;

	// 如果是单板测试，可能需要使用PUB_AC_UA2作为角度0参考
	if(ui_angle0 != -1)
	{
		g_ui_angle0 = ui_angle0;
	}
	
	// 测量值复位
	g_factor_version = ACFACTOR_FILE_VERSION;
	for(i=0; i<UI_NUM; i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			continue;
		}
		g_ui[i].e_acc = 0;
		g_ui[i].e = 0;
		g_ui[i].p_acc = 0;
		g_ui[i].p = 0;
		g_ui[i].p_mark = 0;
		g_ui[i].e_factor = 1.0/_sw_ui_e_k(i);
			g_ui[i].p_factor = 0;
		
	}
	
	for(sw=0; sw<g_sw_num; sw++)
	{
		for(j=0; j<3; j++)
		{
			g_pq_factor[sw][j].cfg_index = -1;
			g_pq_factor[sw][j].pq[0] = 0;
			g_pq_factor[sw][j].pq[1] = 0;
		}
	}

	sw_stat_reset();
	
	// 测量AUTO_ADJUST_NUM次
	for(i=0;i<AUTO_ADJUST_NUM;i++)  // 计算多次幅值
	{
		watchdog_feed_mainloop();
		
		// 得到采样点
		_sw_get_dots();

		// fft
		_sw_cal_fft();
		
		_sw_cal_ri_correct();
		
		// 计算有效值
		_sw_cal_effect();

		// 计算角度
		_sw_cal_angle();
	
		// 延时20ms，并喂狗
	#ifdef CPU_FUXI
		msleep(30);
	#else		
		ustimer_delay(20*USTIMER_MS);
	#endif
		watchdog_feed_mainloop();  
 	}

 	_sw_cal_average(AUTO_ADJUST_NUM);

#if 0 //def PROTECT_AC_ADJUST
	factor_restore_default();
	ustimer_delay(20*USTIMER_MS); 
#endif

	for(i=0; i<UI_NUM; i++)
	{
		// 如果索引通道不存在，不需计算
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			continue;
		}

		fv = (float)g_ui[i].e/Q16_BASE;
	#ifdef PROTECT_AC_ADJUST			
		fv_p = (float)_Mul_Div_U(sqrt_32fix(g_ui[i].m2[0]), 256, g_ui[i].m2_factor_k)/(float)Q16_BASE;		
	#endif
		// 确定通道配置索引和基本值
		if(i<PUB_AC_NUM)
		{
			cfg_index = g_sw_pub.ac_cfg_index[i];
			
			//if(g_equ_config_ac[cfg_index].scale == EQU_SCALE_EVT_3V25_100V)
			//{
				// 电子式相电压
			//	baseValue = 57.735;
			//}
			/*
			else if(g_equ_config_ac[cfg_index].scale == EQU_SCALE_EVT_6V50_100V)
			{
				// 电子式零序电压，为了校验方便，使用C相电压，换算零序为此值。
				baseValue = 28.86751346;
			}
			*/
			
			// 自适应电压校准
			if(fv > 200)		// 220
			{
				// 220V额定电压
				baseValue = 220; 	// 
			}
			else if (fv > (120.0*1.732))		// 207.84
			{
				// 130V相电压合成线电压校准
				// 因为罩式控制器在用100V校准时，PT切换不断的响，
				// 130V相电压可得到225V电源，可避免PT切换的异响
				baseValue = 130*1.732; 	// 225.16
			}
			else if(fv > 90*1.732)		// 155.88
			{
				// 100V相电压合成线电压校准
				baseValue = 100*1.732; 	// 173.2
			}
			else if (fv > 120.0)		// 120
			{
				// 130V 相电压校准
				baseValue = 130;		// 130
			}
			else if(fv > 90.0)
			{
				// 100V 相电压校准
				baseValue = 100;		// 100
				
			}
			else if(fv > 50.0)
			{
				// 100V 相电压校准
				baseValue = 57.735;		// 57.735
				
			}
			else if(fv > 16.0)
			{
				// 100V 相电压校准
				baseValue = 20;		// 20
			}
			
			else if(fv > 8.0)
			{
				// 10V 相电压校准
				baseValue = 10;		// 10
			}
			else if(fv > 6.0)
			{
				baseValue =6.5;
			}
			else if(fv > 2.0)
			{
				// 10V 相电压校准
				baseValue = 3;		// 10
			}
			else if(fv > 1.5)
			{
				baseValue = 1.8763875;
			}
			else
			{
				// 57.735V 相电压校准
				baseValue = 57.735;		// 57.735
			}
			
		}
		else
		{
			sw = (i - PUB_AC_NUM)/SW_AC_NUM;
			j =  (i - PUB_AC_NUM)%SW_AC_NUM;
			cfg_index = g_sw[sw].ac_cfg_index[j];

			// 电子式互感器I0使用5A校准
//			if(g_equ_config_ac[cfg_index].scale == EQU_SCALE_ECT_1V_1A
//				|| g_equ_config_ac[cfg_index].scale == EQU_SCALE_ECT_0V2_1A)
			if(g_equ_config_ac[cfg_index].scale == EQU_SCALE_ECT_1V_1A)
			{
				// 电子式CT使用1A。
				baseValue = 1;
			}
			else if(g_equ_config_ac[cfg_index].scale == EQU_SCALE_CT_10A_249)
			{
				// 高精度零序电流互感器，小信号校正值
				baseValue = 0.5;
			}
			else if(fv > 4)
			{
				baseValue=5;
			}
			else if(fv > 2)
			{
				// 大容量校准时，例如16回路，标准源可能带不动5A负载。
				baseValue=3;
			}
			else
			{
				baseValue=1;
			}
		}
		minfv=baseValue*0.9;
		maxfv=baseValue*1.1;
		
		// 检查幅值是否超范围
		if(fv<minfv)
		{
			rt_printf("sw_auto_adjust(invalid):i=%d,fv=%f,minfv=%f\r\n",i,fv ,minfv);
			continue;
		}
		else if(fv>maxfv)
		{
			rt_printf("sw_auto_adjust(err):i=%d,fv=%f,maxfv=%f\r\n",i,fv ,maxfv);
			return -1;
		}

		// 得到并检查校正系数
		factor=baseValue/fv;
		if(CheckFloatSet(&factor,MAX_FACTOR,MIN_FACTOR)>0)
		{
			rt_printf("sw_auto_adjust(err):i=%d,fv=%f,factor=%f.\r\n",i,fv ,factor);
			return -2;
		}

		// 保存校正系数
		factor_e_c_set(g_equ_config_ac[cfg_index].slot,g_equ_config_ac[cfg_index].index,factor);
	#ifdef PROTECT_AC_ADJUST
		factor=baseValue/fv_p;
		rt_printf("fv_p=%f,baseValue=%f,factor=%f\r\n",fv_p, baseValue, factor);
		if(CheckFloatSet(&factor,MAX_FACTOR,MIN_FACTOR)>0)
		{
			rt_printf("sw_auto_adjust(err) protect ac:i=%d,fv=%f,factor_p=%f.\r\n",i,fv ,factor);
			return -2;
		}
		// 保存校正系数
		factor_p_e_c_set(g_equ_config_ac[cfg_index].slot,g_equ_config_ac[cfg_index].index,factor);	
	#endif
		// 保存校正成功配置通道值
		if(i >= PUB_AC_NUM)
		{
			g_pq_factor[sw][j].cfg_index = cfg_index;
		}

		// 角度校准
		baseAng =_sw_base_angle(i);
		fv = (float)g_ui[i].p/Q16_BASE;
		if(baseAng == 360.0)
		{
			factor = 0;
		}
		else
		{
			factor = baseAng - fv;
		}

		// 确保角度在正负180内。
		if(factor > 180.0)
		{
			factor -= 360.0;
		}
		if(factor < -180.0)
		{
			factor += 360.0;
		}
		
		rt_printf("sw_auto_adjust(ang):i=%d,fv=%f,factor=%f.\r\n",i,fv ,factor);
		if(factor<MIN_PHASE)  
		{
			return -3;
		}
		else if(factor>MAX_PHASE)
		{
			return -4;
		}
		if(CheckFloatSet(&factor,MAX_PHASE,MIN_PHASE)>0)
		{
			return -5;
		}

		// 如果是基准通道，就不更新角度校准值。
		if(i != g_ui_angle0)
		{
			factor_p_c_set(g_equ_config_ac[cfg_index].slot,g_equ_config_ac[cfg_index].index,factor);
		}

#if defined TMP_CHIP_AHT20
		// 保存校正温度和基准值
		factor_temp_set(g_equ_config_ac[cfg_index].slot,
					#if defined TMP_CHIP_AHT20
							aht20_get_temp()
					#endif						
						);
#endif

		if(i < PUB_AC_NUM)
		{
			base_v = baseValue;
		}
		else
		{
			base_i = baseValue;
		}
	}

	// 重新初始化
	sw_init();

	//保存校正系数
	ret = factor_write_all(base_v,base_i);
	if(ret != 0)
	{
		return -6;
	}
	
	sw_factor_cp();
	soe_record_opt(EV_CHNZJS, 0);	
	
	return 0;
}


float g_dc_factor[2][2]=
{
	{1.0,1.0},
	{1.0,1.0},
};


int sw_adjust_dc_0(void)
{
	int i;
	float dc;
	
	for(i=0;i<pRunSet->dDc_num;i++)
	{
		dc = dc_get(i);
		if(dc < 0.5*dc_adjust[0])
		{
			return -1;
		}

		if(dc > 1.5*dc_adjust[0])
		{
			return -2;
		}
		
		g_dc_factor[i][0] = dc;
	}
	
	return 0;
}

int sw_adjust_dc_1(void)
{
	int i;
	float dc;

	for(i=0;i<pRunSet->dDc_num;i++)
	{
		dc = dc_get(i);
		if(dc < 0.5*dc_adjust[1])
		{
			return -1;
		}

		if(dc > 1.5*dc_adjust[1])
		{
			return -2;
		}
		
		g_dc_factor[i][1] = dc;
	}
	
	_sw_save_dc_factor(g_dc_factor[0][1], g_dc_factor[0][0], g_dc_factor[1][1], g_dc_factor[1][0]);

	return 0;
}

/*------------------------------ 内部函数 -------------------------------------
内部函数以下划线‘_’开头，不需要检查参数的合法性.
*/
/******************************************************************************
函数名称：	_sw_get_dots
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	获取采样点，供测量计算用
参数说明：
返回值：	
修改记录：	
*/
void xdl_smooth3 ( short in[], short out[], int N );
void xdl_smooth5 ( short in[], short out[], int N );

int  _sw_check_tb_dots(unsigned long dot_index)
{
	int i,j;
	if(pRunSet->dSmoothZero==0)return 0;

	for(i=0;i<CFG_ADC_CHANNEL;i++)
	{
		short   pnSam[3] = {0};
		long    laaa;
		DWORD   daaa;
		 int 	caulp;
		if(!g_equ_adc_config[i]) // 通道无配置
		{
			continue;
		}
		for(j=0;j<CFG_ADC_DOTS_PER_PERIOD;j++)
		{
		  	caulp = (dot_index+j)&CFG_ADC_DOTS_MASK;
			// 取出连续三周波的同一对应点
			pnSam[0] = g_adc_dots[i][(caulp - 1) & SAMLENGTH];    
			pnSam[1] = g_adc_dots[i][(caulp - SAMFREQ -1) & SAMLENGTH];    
			pnSam[2] = g_adc_dots[i][(caulp - 2*SAMFREQ -1) & SAMLENGTH];    

		        // 计算突变量并取绝对值，i(k)-2*i(k-N)+i(K-2N)
		        laaa = ( pnSam[0] - pnSam[1]*2 + pnSam[2]);
		        if(laaa < 0)
		        {
		            daaa = -laaa;//
		        }
		        else
		        {
		            daaa = laaa;        
		        }
		        // 检查是否超过突变量门槛，且需满足3次，即对应相电流突变量满足要求
		        if(daaa > pRunSet->dSmoothZero)       
		        {  
		        	rt_printf("\r\n chnel=%d zero=%d set=%d",i,daaa,pRunSet->dSmoothZero);
		        	return -1;
		   	 }
		   }
	}
	return 0;
}



void _sw_get_dots(void)
{
	unsigned long i,loop,dots_index ,dots_count_old;
	int cnt;
	int ret=0;
	loop =0;
	do
	{
		// 获取采样点的位置，如果最后一个周波跨界，调整采样点的位置。
#ifdef CPU_FUXI
		dots_count_old = g_adc_dots_index - CFG_ADC_DOTS_PER_PERIOD;      //jack.liu 20200921 获取最后一个周波的采样点   
#else		
		dots_count_old = g_adc_dots_count - CFG_ADC_DOTS_PER_PERIOD;	// 最后一个周波的采样点
#endif
		cnt = (dots_count_old&CFG_ADC_DOTS_MASK) - (CFG_ADC_DOTS_PER_CHANNEL - CFG_ADC_DOTS_PER_PERIOD);
		if(cnt > 0)
		{
			dots_count_old -= cnt;
		}
		
		dots_index = dots_count_old&CFG_ADC_DOTS_MASK;

		ret=_sw_check_tb_dots(dots_index);
		if(ret<0)return;  // 波形判断有突变，不处理采样
		for(i=0;i<CFG_ADC_CHANNEL;i++)
		{
#if 0
			if(g_equ_adc_config[i])
			{
				xdl_smooth3(&g_adc_dots[i][dots_index],&g_adc_dots[i][CFG_ADC_DOTS_PER_CHANNEL],CFG_ADC_DOTS_PER_PERIOD);
			}
#else			
			memcpy(&g_adc_dots[i][CFG_ADC_DOTS_PER_CHANNEL],&g_adc_dots[i][dots_index],CFG_ADC_DOTS_PER_PERIOD*2);
#endif			
		}
		
		loop++;
		if(loop > 5)
		{
			rt_printf("sw_get_dots:i=%d\r\n",loop);
		}
	}
#ifdef CPU_FUXI
	while((g_adc_dots_index - dots_count_old)  > CFG_ADC_DOTS_PER_CHANNEL);
#else	
	while((g_adc_dots_count - dots_count_old)  > CFG_ADC_DOTS_PER_CHANNEL);
#endif	
}


/******************************************************************************
函数名称：	_sw_fft
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	计算FFT，一次计算两个通道
参数说明：
	ch0	通道0索引
	ch1 通道1索引
	p0	通道0结果，所有谐波的复数表示。	
	p1	通道1结果，所有谐波的复数表示。	
返回值：	
修改记录：	
*/
void _sw_fft(int ch0,int ch1,complex * p0,complex * p1)
{
	static complex k[CFG_ADC_DOTS_PER_PERIOD];		
	int i;

	// 初始化点
	for(i=0; i<CFG_ADC_DOTS_PER_PERIOD; i++)
	{
		k[i].r = g_adc_dots[ch0][CFG_ADC_DOTS_PER_CHANNEL + i];
		k[i].i = g_adc_dots[ch1][CFG_ADC_DOTS_PER_CHANNEL + i];
	}
	
	// 计算
	fft(CFG_ADC_DOTS_PER_PERIOD, &k[0]);

	// 整理
	for (i=1;i<=g_harmonic_num;i++)    
	{
		if(p0)
		{
			p0[i].r = (k[i].r+k[CFG_ADC_DOTS_PER_PERIOD-i].r)/CFG_ADC_DOTS_PER_PERIOD;
			p0[i].i = (k[i].i-k[CFG_ADC_DOTS_PER_PERIOD-i].i)/CFG_ADC_DOTS_PER_PERIOD;
		}
		if(p1)
		{
			p1[i].r = (k[i].i+k[CFG_ADC_DOTS_PER_PERIOD-i].i)/CFG_ADC_DOTS_PER_PERIOD;
			p1[i].i = (k[CFG_ADC_DOTS_PER_PERIOD-i].r-k[i].r)/CFG_ADC_DOTS_PER_PERIOD;
		}
	}

}


/******************************************************************************
函数名称：	_sw_cal_fft
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	计算所有通道的FFT
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_fft(void)
{
	s32 i,index0;	

	// fft
	index0  =  UI_NUM;
	for(i=0;i<UI_NUM;i++)
	{
		// 如果索引通道不存在，不需计算
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			continue;
		}

		// 检查硬件通道是否正常，如果不正常，ri清零；否则计算出ri。
		if(equ_ac_channel_is_ok(g_ui[i].chn_index) == 0)
		{
			memset(&g_ui[i].h,0,sizeof(g_ui[i].h));
			continue;
		}


		if(index0 == UI_NUM)
		{
			index0 = i;
		}
		else
		{
			_sw_fft(g_ui[index0].chn_index,g_ui[i].chn_index,g_ui[index0].h,g_ui[i].h);
			index0  =  UI_NUM;
		}
	}
	if(index0 != UI_NUM)
	{
		_sw_fft(g_ui[index0].chn_index,g_ui[index0].chn_index,g_ui[index0].h,NULL);
	}

	return;
}


/******************************************************************************
函数名称：	_sw_cal_h_sub
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	2个谐波向量减
参数说明：
	r	结果
	a	向量a的g_ui索引
	b	向量b的g_ui索引
返回值：	
修改记录：	
*/
void _sw_cal_h_sub(int r,int a,int b)
{
	int i;

	for(i=1;i<=g_harmonic_num;i++)
	{
		g_ui[r].h[i].r = g_ui[a].h[i].r - g_ui[b].h[i].r;
		g_ui[r].h[i].i = g_ui[a].h[i].i - g_ui[b].h[i].i;
	}

	return;
}

/******************************************************************************
函数名称：	_sw_cal_h_sub2
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	谐波向量减，求Ib
参数说明：
	r	结果
	o	向量o的g_ui索引
	a	向量a的g_ui索引
	b	向量b的g_ui索引
返回值：	
修改记录：	
*/
void _sw_cal_h_sub2(int r,int o,int a,int b)
{
	int i;
	float factor_i0_ia=1.0;
	if((g_ui[o].m2_factor_k!=0)&&(g_ui[o].m2_factor_k!=g_ui[a].m2_factor_k))
	{
		factor_i0_ia=(float)g_ui[a].m2_factor_k/g_ui[o].m2_factor_k;
	}
	for(i=1;i<=g_harmonic_num;i++)
	{
		g_ui[r].h[i].r = g_ui[o].h[i].r*factor_i0_ia - g_ui[a].h[i].r - g_ui[b].h[i].r;
		g_ui[r].h[i].i = g_ui[o].h[i].i *factor_i0_ia- g_ui[a].h[i].i - g_ui[b].h[i].i;
	}

	return;
}


/******************************************************************************
函数名称：	_sw_cal_h_add
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	3个谐波向量加
参数说明：
	r	结果
	a	向量a的g_ui索引
	b	向量b的g_ui索引
	c	向量c的g_ui索引
返回值：	
修改记录：	
*/
void _sw_cal_h_add(int r,int a,int b,int c)
{
	int i;

	for(i=1;i<=g_harmonic_num;i++)
	{
		g_ui[r].h[i].r = g_ui[a].h[i].r + g_ui[b].h[i].r + g_ui[c].h[i].r;
		g_ui[r].h[i].i = g_ui[a].h[i].i + g_ui[b].h[i].i + g_ui[c].h[i].i;
	}

	return;
}


/******************************************************************************
函数名称：	_sw_cal_ri_correct
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	根据角度误差校正向量值
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_ri_correct(void)
{
	s32 i,j;
	qs08 angle;
	qs16 lncos,lnsin,v;
	
	struct ri_s32 ri;	

	for(i=0;i<UI_NUM;i++)
	{
		// 如果索引通道不存在，不需计算
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			continue;
		}

		// 根据频率修正角度校正值，提高频率变化时的功率精度。
  		angle = rt_round((g_ui[i].p_factor + factor_p_k(g_ui[i].chn_index))*256);
    	
    	for(j=1;j<=g_harmonic_num;j++)
		{
	    	lncos = mCos(angle*j);
  		  	lnsin = mSin(angle*j);

			ri.r = rt_round(g_ui[i].h[j].r * Q16_BASE);
	    	ri.i = rt_round(g_ui[i].h[j].i * Q16_BASE);
	    	
	      	v = _MulFac_S(ri.r,lncos) - _MulFac_S(ri.i,lnsin);
	      	g_ui[i].h[j].r = (float)v/Q16_BASE;
	    	v = _MulFac_S(ri.r,lnsin) + _MulFac_S(ri.i,lncos);
	    	g_ui[i].h[j].i = (float)v/Q16_BASE;
    	}
	}
}

/******************************************************************************
函数名称：	_sw_cal_unbalance
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	不平衡度计算
参数说明：
返回值：	
修改记录：	
*/
#ifdef asdfadasdfa
void CalcuIx120( struct UI *pI, struct UI120 *pII )
{

    long  labc,lbc;
    	
    labc = pI->lIaR - (( pI->lIbR + pI->lIcR )>>1);
    lbc  = pI->lIbI - pI->lIcI;
    lbc  =_MulFac_S(lbc, 56756);//(1.732/2)*2^16=56756
    pII->l1Cos = labc - lbc;
    pII->l2Cos = labc + lbc;

    labc = pI->lIaI - ( (pI->lIbI + pI->lIcI )>>1);
    lbc  = pI->lIbR - pI->lIcR;
    lbc  =_MulFac_S(lbc,56756);//(1.732/2)*2^16=56756
    pII->l1Sin = labc + lbc;
    pII->l2Sin = labc - lbc;

    pII->l0Cos = pI->lIaR + pI->lIbR + pI->lIcR;
    pII->l0Sin = pI->lIaI + pI->lIbI + pI->lIcI;

    pII->d1Modu = SQR( pII->l1Cos, pII->l1Sin );
    pII->d2Modu = SQR( pII->l2Cos, pII->l2Sin );
    pII->d0Modu = SQR( pII->l0Cos, pII->l0Sin );
 
}
#endif

float _sw_cal_unbalance(int ui_index)
{
	
    float abc,bc;
    float r1,r2,i1,i2;
    	
	abc = g_ui[ui_index].h[1].r - (g_ui[ui_index+1].h[1].r + g_ui[ui_index+2].h[1].r)/2;
	bc  = g_ui[ui_index+1].h[1].i - g_ui[ui_index+2].h[1].i;
	bc  = bc * (1.7320508/2); 
	r1  = abc - bc;
	r2  = abc + bc;

	abc = g_ui[ui_index].h[1].i - (g_ui[ui_index+1].h[1].i + g_ui[ui_index+2].h[1].i)/2;
	bc  = g_ui[ui_index+1].h[1].r - g_ui[ui_index+2].h[1].r;
	bc  = bc * (1.7320508/2); 
	i1  = abc + bc;
	i2  = abc - bc;

	abc = sqrtf(r1*r1 + i1*i1);
	bc  = sqrtf(r2*r2 + i2*i2);
	
	//rt_printf("%s\tabc=%f,\tbc=%f.\r\n",g_ui[ui_index].name,abc*g_ui[ui_index].e_factor,bc*g_ui[ui_index].e_factor);
	
    if(abc == 0.0)
	{
		return 100;
	}

    return bc/abc*100;
}

/******************************************************************************
函数名称：	_sw_cal_unbalance
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	正负序计算
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_Xfl120( int ui_index, struct ui120 *pII )
{
	float abc,bc;
    float r1,r2,i1,i2;
    	
	abc = g_ui[ui_index].ri.r - (g_ui[ui_index+1].ri.r + g_ui[ui_index+2].ri.r)/2;
	bc  = g_ui[ui_index+1].ri.i - g_ui[ui_index+2].ri.i;
	bc  = bc * (1.7320508/2); 
	r1  = abc - bc;
	r2  = abc + bc;

	abc = g_ui[ui_index].ri.i - (g_ui[ui_index+1].ri.i + g_ui[ui_index+2].ri.i)/2;
	bc  = g_ui[ui_index+1].ri.r - g_ui[ui_index+2].ri.r;
	bc  = bc * (1.7320508/2); 
	i1  = abc + bc;
	i2  = abc - bc;

	pII->vect1 = (r1*r1 + i1*i1)/9;
	pII->vect2 = (r2*r2 + i2*i2)/9;
}

/******************************************************************************
函数名称：	_sw_cal_make
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量合成通道向量值
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_make(void)
{
	int sw ; 	
	
	// 合成电压
	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_LV1)
	{
		_sw_cal_h_sub(PUB_AC_UAB1,PUB_AC_UA1,PUB_AC_UB1);
		_sw_cal_h_sub(PUB_AC_UBC1,PUB_AC_UB1,PUB_AC_UC1);
		_sw_cal_h_sub(PUB_AC_UCA1,PUB_AC_UC1,PUB_AC_UA1);
 	}	

	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_LV2)
	{
		_sw_cal_h_sub(PUB_AC_UAB2,PUB_AC_UA2,PUB_AC_UB2);
		_sw_cal_h_sub(PUB_AC_UBC2,PUB_AC_UB2,PUB_AC_UC2);
		_sw_cal_h_sub(PUB_AC_UCA2,PUB_AC_UC2,PUB_AC_UA2);
	}	

	// 合成UCA
	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_UCA1)
	{
		{
			int i;
			for(i=1;i<=g_harmonic_num;i++)
			{
				g_ui[PUB_AC_UCA1].h[i].r = -g_ui[PUB_AC_UAB1].h[i].r - g_ui[PUB_AC_UBC1].h[i].r;
				g_ui[PUB_AC_UCA1].h[i].i = -g_ui[PUB_AC_UAB1].h[i].i - g_ui[PUB_AC_UBC1].h[i].i;
			}
		}
 	}	

	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_UCA2)
	{
		{
			int i;
			for(i=1;i<=g_harmonic_num;i++)
			{
				g_ui[PUB_AC_UCA2].h[i].r = -g_ui[PUB_AC_UAB2].h[i].r - g_ui[PUB_AC_UBC2].h[i].r;
				g_ui[PUB_AC_UCA2].h[i].i = -g_ui[PUB_AC_UAB2].h[i].i - g_ui[PUB_AC_UBC2].h[i].i;
			}
		}
 	}	
	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_U01)
	{
		{
			int i;
			for(i=1;i<=g_harmonic_num;i++)
			{
				g_ui[PUB_AC_U01].h[i].r = g_ui[PUB_AC_UA1].h[i].r + g_ui[PUB_AC_UB1].h[i].r+ g_ui[PUB_AC_UC1].h[i].r;
				g_ui[PUB_AC_U01].h[i].i = g_ui[PUB_AC_UA1].h[i].i + g_ui[PUB_AC_UB1].h[i].i+ g_ui[PUB_AC_UC1].h[i].i;
			}
		}
 	}	

 	if(g_sw_pub.ui_flags&UI_FLAGS_MAKE_U02)
	{
		{
			int i;
			for(i=1;i<=g_harmonic_num;i++)
			{
				g_ui[PUB_AC_U02].h[i].r = g_ui[PUB_AC_UA2].h[i].r + g_ui[PUB_AC_UB2].h[i].r+ g_ui[PUB_AC_UC2].h[i].r;
				g_ui[PUB_AC_U02].h[i].i = g_ui[PUB_AC_UA2].h[i].i + g_ui[PUB_AC_UB2].h[i].i+ g_ui[PUB_AC_UC2].h[i].i;
			}
		}
 	}	
	

	// 电压不平衡计算
	g_sw_pub.ac_in_acc[PUB_AC_IN_V_UNBALANCE1] += _sw_cal_unbalance(PUB_AC_UA1);
	g_sw_pub.ac_in_acc[PUB_AC_IN_V_UNBALANCE2] += _sw_cal_unbalance(PUB_AC_UA2);

	// 开关电流
	for(sw=0; sw<g_sw_num; sw++)
	{
		// 合成电流IB
		if(g_sw[sw].ui_flags&UI_FLAGS_MAKE_IB)
		{
			_sw_cal_h_sub2(UI_SW_INDEX(sw,SW_AC_IB),UI_SW_INDEX(sw,SW_AC_I0),UI_SW_INDEX(sw,SW_AC_IA),UI_SW_INDEX(sw,SW_AC_IC));
		}

		// 合成电流IB
		if(g_sw[sw].ui_flags&UI_FLAGS_MAKE_CIB)
		{
			_sw_cal_h_sub2(UI_SW_INDEX(sw,SW_AC_CIB),UI_SW_INDEX(sw,SW_AC_I0),UI_SW_INDEX(sw,SW_AC_CIA),UI_SW_INDEX(sw,SW_AC_CIC));
		}

		// 合成电流I0
		if(g_sw[sw].ui_flags&UI_FLAGS_MAKE_I0)
		{
			_sw_cal_h_add(UI_SW_INDEX(sw,SW_AC_I0),UI_SW_INDEX(sw,SW_AC_IA),UI_SW_INDEX(sw,SW_AC_IB),UI_SW_INDEX(sw,SW_AC_IC));
		}

		// 电流不平衡计算
		g_sw[sw].ac_in_acc[SW_AC_IN_BI_UNBALANCE] += _sw_cal_unbalance(UI_SW_INDEX(sw,SW_AC_IA));
		// 电流不平衡计算
		g_sw[sw].ac_in_acc[SW_AC_IN_CI_UNBALANCE] += _sw_cal_unbalance(UI_SW_INDEX(sw,SW_AC_CIA));
	}
}


/******************************************************************************
函数名称：	_sw_cal_effect
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量计算有效值，累加结果。
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_effect(void)
{
	int  i,j;
	float f,re,im,sum;

	for(i=0;i<UI_NUM;i++)
	{
		// 如果索引通道不存在，不需计算
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[i].ui_base_make == -1)
		{
			continue;
		}

		sum = 0.0;
		for(j=1;j<=g_harmonic_num;j++)
		{
			re = g_ui[i].h[j].r;
			im = g_ui[i].h[j].i;
			f = sqrtf(re*re+im*im); 
			f *= g_harmonic_factor[j]; // 谐波系数修正
			sum += f*f;
			
#if 0
			if(i>=UI_SW_INDEX(1,SW_AC_IA) && i<=UI_SW_INDEX(1,SW_AC_I0))
			{
				rt_printf("%s[%02d]:e=%f,p=%f.\r\n",g_ui[i].name,j,f*g_ui[i].e_factor,_sw_cal_angle0(re,im));
			}
#endif
		
		}
		f = sqrtf(sum);
		g_ui[i].e_acc += f*g_ui[i].e_factor ;

	}

	return ;
}


/******************************************************************************
函数名称：	_sw_cal_angle0
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	计算向量角度
参数说明：
	re	向量实部
	im	向量虚部
返回值：	
修改记录：	
*/

#if 1
float _sw_cal_angle0(float re, float im)
{
	float p;
	p = atan2f(im,re);
	p = p*180/pi;

	return p;
}
#else
const int Angle_const[7] =
{
	0,267,577,1000,1732,3732,57400
};
float _sw_cal_angle0(float re, float im)
{
	float angle_arttg;
	float angle = 0;
	uint8 quad;

	if (re >=0)
	{
		if (im >=0)
			quad = 1;
		else
		{
			quad = 4;
			im = im*(-1);
		}
	}
	else
	{
		re = re*(-1);
		if (im >= 0)
			quad = 2;
		else 
		{	
			im = im*(-1);
			quad = 3;
		}
    }

    if (re <=2)
    {
		switch (quad)
		{
			case 1:angle = 90;break;
			case 2:angle = 90;break;
			case 3:angle = 270;break;
			case 4:angle = 270;break;
		}
    }
    else
    {   
		angle_arttg = (im*1000)/re;
		
		if (angle_arttg <= Angle_const[1])
		{
			angle = 0 + (angle_arttg-Angle_const[0])*57/(1000+Angle_const[0]*angle_arttg/1000);
		}
		else if (angle_arttg <= Angle_const[2])
		{
			angle = 15 + (angle_arttg-Angle_const[1])*57/(1000+Angle_const[1]*angle_arttg/1000);
		}
		else if (angle_arttg <= Angle_const[3])
		{
			angle = 30 + (angle_arttg-Angle_const[2])*57/(1000+Angle_const[2]*angle_arttg/1000);
		}
		else if (angle_arttg <= Angle_const[4])
		{
			angle = 45 + (angle_arttg-Angle_const[3])*57/(1000+Angle_const[3]*angle_arttg/1000);
		}
		else if (angle_arttg <= Angle_const[5])
		{
			angle = 60 + (angle_arttg-Angle_const[4])*57/(1000+Angle_const[4]*angle_arttg/1000);
		}
		else if (angle_arttg <= Angle_const[6])
		{
			angle = 75 + (angle_arttg-Angle_const[5])*57/(1000+Angle_const[5]*angle_arttg/1000);
		}
		else
		{
			angle = 90;
		}
        
		switch (quad)
		{
			case 1: angle = angle;break;
			case 2: angle = 180 - angle;break;
			case 3: angle = 180 + angle;break;
			case 4: angle = 360 - angle;break;
		}
	}
    
	if((re < 5) && (im < 5)) angle = 0;
	return(angle);
}
#endif

/******************************************************************************
函数名称：	_sw_cal_angle_correct
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量计算角度时对角度进行校正，保证累加时不会出现计算错误。
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_angle_correct(qs16 *angle,int *mark)
{
	if(*angle > ANGF180)
	{
		*angle -= ANG360;
	}
	if(*angle < ANGN180)
	{
		*angle += ANG360;
	}

	if(*mark == 0)
	{
		if(abs(*angle)< 90*Q16_BASE)
		{
			*mark = 1;
		}
		else
		{
			*mark = -1;
		}
	}
	if(*mark == -1)
	{
		if(*angle >= 0)
		{
			*angle = 180*Q16_BASE - *angle;
		}
		else
		{
			*angle = (-180)*Q16_BASE - *angle;
		}
	}
}


/******************************************************************************
函数名称：	_sw_cal_angle
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量计算角度，每次调用累加计算值。
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_angle(void)
{
	int  i;
	qs16  qs;
	float angle,angle0;

	// 检查是否有基准通道
	if(g_ui_angle0 == -1)
	{
		return;
	}

	// 计算基准通道的角度
	angle0 = _sw_cal_angle0(g_ui[g_ui_angle0].h[1].r,g_ui[g_ui_angle0].h[1].i);
//	angle0 += g_ui[g_ui_angle0].p_factor;

	// 计算相对角度
	for(i=0;i<UI_NUM;i++)
	{
		// 如果索引通道不存在，不需计算
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[i].ui_base_make == -1)
		{
			continue;
		}
		
		angle  = _sw_cal_angle0(g_ui[i].h[1].r,g_ui[i].h[1].i);
//		angle += g_ui[i].p_factor;
		angle -= angle0;
		qs = rt_round(angle*Q16_BASE);
		_sw_cal_angle_correct(&qs,&g_ui[i].p_mark);

		g_ui[i].p_acc += qs;
	}

	return ;

}


/******************************************************************************
函数名称：	_sw_p2
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	根据电压电流向量计算p值
参数说明：
	ur	电压实部
	ui	电压虚部
	ir	电流实部
	ii	电流虚部
	k1	电压系数
	k2	电流系数
返回值：	p值
修改记录：	
*/
float  _sw_p2( float Ur, float Ui,float Ir, float Ii, float k1, float k2)
{  
	float p ; 
	p =  Ur*Ir + Ui*Ii;
   	p = p * k1 *k2; 

     return p;
} 


/******************************************************************************
函数名称：	_sw_q2
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	根据电压电流向量计算q值
参数说明：
	ur	电压实部
	ui	电压虚部
	ir	电流实部
	ii	电流虚部
	k1	电压系数
	k2	电流系数
返回值：	q值
修改记录：	
*/
float _sw_q2( float Ur,  float Ui,float Ir,float Ii,float k1, float k2)
{   
	float q ; 
	q =Ui*Ir - Ur*Ii;
	q = q * k1* k2; 
	return q;
}


/******************************************************************************
函数名称：	_sw_cal_pq_3m
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	3表法计算一个开关的pq，每次调用累加计算值。
参数说明：
	sw	开关序号
返回值：	
修改记录：	
*/
void _sw_cal_pq_3m(u32 sw)
{
	u32 i,j,U,I,baseI;
	float p,q,pz,qz;	
	if(g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].chn_index != CFG_ADC_CHANNEL_ZERO)baseI=SW_AC_CIA;
	else baseI=0;	
	U = pRunSet->tSwSet[sw].bTT_Power_v2 ? PUB_AC_UA2 : PUB_AC_UA1;
	for(j=0; j<3; j++)
	{
		I = UI_SW_INDEX(sw,j+baseI);
		p = 0;
		q = 0;
		pz=0;
		qz=0;
		
		for(i=1; i<=g_harmonic_num;i++)
		{
			p += _sw_p2(g_ui[U].h[i].r,g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
			q += _sw_q2(g_ui[U].h[i].r,g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
		}
		pz=p*(1 + g_ui[I].pq_factor[0]) - q*g_ui[I].pq_factor[1];
		qz=q*(1 + g_ui[I].pq_factor[0]) + p*g_ui[I].pq_factor[1];
		
		g_sw[sw].ac_in_acc[SW_AC_IN_P] += pz;
		g_sw[sw].ac_in_acc[SW_AC_IN_Q] += qz;

		if(j==0)
		{
			g_sw[sw].ac_in_acc[SW_AC_IN_Pa] += pz;		
			g_sw[sw].ac_in_acc[SW_AC_IN_Qa] += qz;		
		}
		else if(j==1)
		{
			g_sw[sw].ac_in_acc[SW_AC_IN_Pb] += pz;		
			g_sw[sw].ac_in_acc[SW_AC_IN_Qb] += qz;		
		}
		else if(j==2)
		{
			g_sw[sw].ac_in_acc[SW_AC_IN_Pc] += pz;		
			g_sw[sw].ac_in_acc[SW_AC_IN_Qc] += qz;		
		}		
		U++;
	}

	return;
}


/******************************************************************************
函数名称：	_sw_cal_pq_2m
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	2表法计算一个开关的pq，每次调用累加计算值。
参数说明：
	sw	开关序号
返回值：	
修改记录：	
*/
void _sw_cal_pq_2m(u32 sw)
{
	u32 i,U,I,baseI;
	float p,q,pz,qz;
	
	// IA
	U = PUB_AC_UAB1;
	if(g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].chn_index != CFG_ADC_CHANNEL_ZERO)baseI=SW_AC_CIA;
	else baseI=0;
	if(pRunSet->tSwSet[sw].bTT_Power_v2)
	{
		U = PUB_AC_UAB2;
	}
	else if ((g_ui[PUB_AC_UAB1].chn_index == CFG_ADC_CHANNEL_ZERO)
		&& (g_ui[PUB_AC_UAB2].chn_index != CFG_ADC_CHANNEL_ZERO))
	{
		U = PUB_AC_UAB2;
	}
	I = UI_SW_INDEX(sw,baseI);
	p = 0;
	q = 0;
	
	for(i=1; i<=g_harmonic_num;i++)
	{
		p += _sw_p2(g_ui[U].h[i].r,g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
		q += _sw_q2(g_ui[U].h[i].r,g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
	}

	pz=p*(1 + g_ui[I].pq_factor[0]) - q*g_ui[I].pq_factor[1];
	qz=q*(1 + g_ui[I].pq_factor[0]) + p*g_ui[I].pq_factor[1];;
	g_sw[sw].ac_in_acc[SW_AC_IN_P] += pz;
	g_sw[sw].ac_in_acc[SW_AC_IN_Q] += qz;
	
	g_sw[sw].ac_in_acc[SW_AC_IN_Pa] += pz;		
	g_sw[sw].ac_in_acc[SW_AC_IN_Qa] += qz;		


	// IC
	U = PUB_AC_UBC1;
	if(pRunSet->tSwSet[sw].bTT_Power_v2)
	{
		U = PUB_AC_UBC2;
	}
	else if ((g_ui[PUB_AC_UBC1].chn_index == CFG_ADC_CHANNEL_ZERO)
		&& (g_ui[PUB_AC_UBC2].chn_index != CFG_ADC_CHANNEL_ZERO))
	{
		U = PUB_AC_UBC2;
	}
	I = UI_SW_INDEX(sw,2+baseI);
	p = 0;
	q = 0;
	
	for(i=1; i<=g_harmonic_num;i++)
	{
		p += _sw_p2(-g_ui[U].h[i].r,-g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
		q += _sw_q2(-g_ui[U].h[i].r,-g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
	}

	pz=p*(1 + g_ui[I].pq_factor[0]) - q*g_ui[I].pq_factor[1];
	qz=q*(1 + g_ui[I].pq_factor[0]) + p*g_ui[I].pq_factor[1];;
	g_sw[sw].ac_in_acc[SW_AC_IN_P] += pz;
	g_sw[sw].ac_in_acc[SW_AC_IN_Q] += qz;
	
	g_sw[sw].ac_in_acc[SW_AC_IN_Pc] += pz;		
	g_sw[sw].ac_in_acc[SW_AC_IN_Qc] += qz;		

	g_sw[sw].ac_in_acc[SW_AC_IN_Pb] = 0;		
	g_sw[sw].ac_in_acc[SW_AC_IN_Qb] = 0;		

	return;
}


/******************************************************************************
函数名称：	_sw_cal_pq
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量计算pq，区分3表法和2表法，每次调用累加计算值。
参数说明：
返回值：	
修改记录：	
*/
void _sw_cal_pq(void)
{
	u32 sw,U;
	for(sw=0; sw<g_sw_num; sw++)
	{
		bool b3U,b3I=false;
		U = pRunSet->tSwSet[sw].bTT_Power_v2 ? PUB_AC_UA2 : PUB_AC_UA1;
		b3U= (g_ui[U+0].chn_index != CFG_ADC_CHANNEL_ZERO
				&& g_ui[U+1].chn_index != CFG_ADC_CHANNEL_ZERO
				&& g_ui[U+2].chn_index != CFG_ADC_CHANNEL_ZERO);
			b3I|= (g_ui[UI_SW_INDEX(sw,SW_AC_IA)].chn_index != CFG_ADC_CHANNEL_ZERO
					&& g_ui[UI_SW_INDEX(sw,SW_AC_IB)].chn_index != CFG_ADC_CHANNEL_ZERO
					&& g_ui[UI_SW_INDEX(sw,SW_AC_IC)].chn_index != CFG_ADC_CHANNEL_ZERO
					&&g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].chn_index == CFG_ADC_CHANNEL_ZERO); //测量电流未配置

			b3I|= (g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].chn_index != CFG_ADC_CHANNEL_ZERO
					&& g_ui[UI_SW_INDEX(sw,SW_AC_CIB)].chn_index != CFG_ADC_CHANNEL_ZERO
					&& g_ui[UI_SW_INDEX(sw,SW_AC_CIC)].chn_index != CFG_ADC_CHANNEL_ZERO);



		if(b3U&&b3I) //有三相电压，且有三相测量电流或无AC 测量电流有三相保护电流，用三表法
		{
			_sw_cal_pq_3m(sw);
		}
		else
		{
			_sw_cal_pq_2m(sw);
		}
	}
}


/******************************************************************************
函数名称：	_sw_cal_mea
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量计算，每次调用累加计算值
参数说明：
返回值：	
修改记录：	
*/
int _sw_cal_mea(void)
{
	static int g_cal_step = 0;
  	uint64_t us0;

	us0 = bsp_ustimer_get_origin();

	if(g_cal_step == 0)
	{
		// 得到采样点
		_sw_get_dots();

		// fft
		_sw_cal_fft();

		_sw_cal_ri_correct();
		
		g_cal_step = 1;
		
		rt_stat_other_in(3,bsp_ustimer_get_duration(us0)/USTIMER_US);
	}
	else
	{
		
		// 得到合成通道的向量值
		_sw_cal_make();
		
		// 计算有效值
		_sw_cal_effect();

		// 计算角度
		_sw_cal_angle();

		// 计算PQ
		_sw_cal_pq();
		
		g_cal_step = 0;
		
		rt_stat_other_in(4,bsp_ustimer_get_duration(us0)/USTIMER_US);
	}
	

	return g_cal_step;
}

#ifdef FUN_JDXX
/*********************************************************
函数名称:isTakeIsVal
函数版本:v1.0	
作   者: Xzy	
日   期：2021.10.30
函数说明:是否取Is通道的值
参数说明:sw：开关号
		I_chn：常规通道号
		Is_chn：小值范围通道号
返 回 值:true：取Is的值 false：不取Is的值		
**********************************************************/
static bool isTakeIsVal(int sw,int I_chn,int Is_chn)
{
	float I_val,Is_val,err_val;

	if(g_ui[UI_SW_INDEX(sw,I_chn)].chn_index == CFG_ADC_CHANNEL_ZERO || g_ui[UI_SW_INDEX(sw,Is_chn)].chn_index == CFG_ADC_CHANNEL_ZERO){
		return false;
	}

	I_val = (float)g_sw[sw].ac_in[I_chn]/65536;
	Is_val = (float)g_sw[sw].ac_in[Is_chn]/65536;

	if(Is_val == 0)
		err_val = 1;
	else	
		err_val = ((float)abs(I_val*1000-Is_val*1000))/(Is_val*1000);
	
	if(Is_val > 0.5 || err_val >= 0.05)
		return false;

	return true;
}
#endif

/******************************************************************************
函数名称：	_sw_cal_average
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	测量计算平均值
参数说明：
	cal_num	平均的次数
返回值：	
修改记录：	
*/
void _sw_cal_average(int cal_num)
{
	s32  i,sw;			
	s32 temp;

	// 平均幅值和角度
	for(i=0;i<UI_NUM;i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[i].ui_base_make == -1)
		{
			continue;
		}

		// 幅值
		g_ui[i].e = rt_round(g_ui[i].e_acc/cal_num*Q16_BASE);  	
		rt_stat_in(&g_ui[i].e_stat,g_ui[i].e);
		if(i<PUB_AC_NUM)
		{
			g_sw_pub.ac_in[i] = g_ui[i].e;
		}
		else
		{
			g_sw[(i-PUB_AC_NUM)/SW_AC_NUM].ac_in[(i-PUB_AC_NUM)%SW_AC_NUM] = g_ui[i].e;
		}

		// 角度
		temp = (g_ui[i].p_acc + (cal_num/2))/cal_num;	
		if(g_ui[i].p_mark == -1)
		{
		 	if(temp >= 0)
		 	{
		 		temp = 180*Q16_BASE - temp;
		 	}
		 	else
		 	{
		 		temp = (-180)*Q16_BASE - temp;
		 	}
		}
		
		g_ui[i].p = temp;
		rt_stat_in(&g_ui[i].p_stat,g_ui[i].p);
		
		g_ui[i].e_acc = 0;
		g_ui[i].p_acc = 0;
		g_ui[i].p_mark = 0;

 	}

#ifdef FUN_JDXX
	// 电流值小于0.5A，取Is的，因为在这个范围I0s准确度高
	for(sw=0;sw<g_sw_num;sw++){
		if(isTakeIsVal(sw,SW_AC_I0,SW_AC_I0s)){
			g_sw[sw].ac_in[SW_AC_I0] = g_sw[sw].ac_in[SW_AC_I0s];
		}
	}
#endif

	// 角度清除
 	for(i=0;i<UI_NUM;i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[i].ui_base_make == -1)
		{
			continue;
		}
#ifdef MIN_SIGNAL_SAMPLE
		if(g_ui_angle0 == -1 || g_ui[g_ui_angle0].e < 0.1*Q16_BASE)
#else
		if(g_ui_angle0 == -1 || g_ui[g_ui_angle0].e < 10*Q16_BASE)
#endif

		{
			g_ui[i].p = ANGEL_INVALID;
		}
 	}

	// 平均开关内部测量值:P,Q,COS,电流不平衡度
	for(sw=0;sw<g_sw_num;sw++)
	{
	#ifdef FUN_YC_POWER_S	
		float p,q;
		p = g_sw[sw].ac_in_acc[SW_AC_IN_P]/cal_num;
		q = g_sw[sw].ac_in_acc[SW_AC_IN_Q]/cal_num;
		g_sw[sw].ac_in[SW_AC_IN_S] = sqrtf(p*p+q*q)*Q16_BASE;
	#endif	
		g_sw[sw].ac_in[SW_AC_IN_P] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_P]/cal_num*Q16_BASE);
		g_sw[sw].ac_in[SW_AC_IN_Q] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Q]/cal_num*Q16_BASE);

		g_sw[sw].ac_in[SW_AC_IN_Pa] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Pa]/cal_num*Q16_BASE);
		g_sw[sw].ac_in[SW_AC_IN_Pb] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Pb]/cal_num*Q16_BASE);
		g_sw[sw].ac_in[SW_AC_IN_Pc] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Pc]/cal_num*Q16_BASE);
		g_sw[sw].ac_in[SW_AC_IN_Qa] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Qa]/cal_num*Q16_BASE);
		g_sw[sw].ac_in[SW_AC_IN_Qb] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Qb]/cal_num*Q16_BASE);
		g_sw[sw].ac_in[SW_AC_IN_Qc] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_Qc]/cal_num*Q16_BASE);
		

		// 如果电流反向，功率反向
		if(pRunSet->tSwSet[sw].bTT_Current_Inv)
		{
			g_sw[sw].ac_in[SW_AC_IN_P]	= -g_sw[sw].ac_in[SW_AC_IN_P];
			g_sw[sw].ac_in[SW_AC_IN_Q]	= -g_sw[sw].ac_in[SW_AC_IN_Q];
			g_sw[sw].ac_in[SW_AC_IN_Pa]	= -g_sw[sw].ac_in[SW_AC_IN_Pa];
			g_sw[sw].ac_in[SW_AC_IN_Pb]	= -g_sw[sw].ac_in[SW_AC_IN_Pb];
			g_sw[sw].ac_in[SW_AC_IN_Pc]	= -g_sw[sw].ac_in[SW_AC_IN_Pc];			
			g_sw[sw].ac_in[SW_AC_IN_Qa]	= -g_sw[sw].ac_in[SW_AC_IN_Qa];
			g_sw[sw].ac_in[SW_AC_IN_Qb]	= -g_sw[sw].ac_in[SW_AC_IN_Qb];
			g_sw[sw].ac_in[SW_AC_IN_Qc]	= -g_sw[sw].ac_in[SW_AC_IN_Qc];

			
		}
		
		if(		g_ui[UI_SW_INDEX(sw,SW_AC_IA)].e > g_unit[g_sw_ac_desc[SW_AC_IA].unit].zero
			|| 	g_ui[UI_SW_INDEX(sw,SW_AC_IB)].e > g_unit[g_sw_ac_desc[SW_AC_IB].unit].zero
			|| 	g_ui[UI_SW_INDEX(sw,SW_AC_IC)].e > g_unit[g_sw_ac_desc[SW_AC_IC].unit].zero)
		{
			g_sw[sw].ac_in[SW_AC_IN_BI_UNBALANCE] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_BI_UNBALANCE]/cal_num*Q16_BASE);
		}
		else
		{
			g_sw[sw].ac_in[SW_AC_IN_BI_UNBALANCE] = 0;
		}

		if(		g_ui[UI_SW_INDEX(sw,SW_AC_CIA)].e > g_unit[g_sw_ac_desc[SW_AC_CIA].unit].zero
			|| 	g_ui[UI_SW_INDEX(sw,SW_AC_CIB)].e > g_unit[g_sw_ac_desc[SW_AC_CIB].unit].zero
			|| 	g_ui[UI_SW_INDEX(sw,SW_AC_CIC)].e > g_unit[g_sw_ac_desc[SW_AC_CIC].unit].zero)
		{
			g_sw[sw].ac_in[SW_AC_IN_CI_UNBALANCE] = rt_round(g_sw[sw].ac_in_acc[SW_AC_IN_CI_UNBALANCE]/cal_num*Q16_BASE);
		}
		else
		{
			g_sw[sw].ac_in[SW_AC_IN_CI_UNBALANCE] = 0;
		}

		// TODO:
		// 功率因数，I1/I*COSφ1=COSφ ，I1基波电流有效值，I总电流有效值，COSφ1基波功率因数，COSφ含谐波电网的实际功率因数
		if(_AbsL(g_sw[sw].ac_in[SW_AC_IN_Q]) > g_unit[g_sw_ac_desc[SW_AC_IN_Q].unit].zero)
		{
			g_sw[sw].ac_in[SW_AC_IN_COS] =_CosPQ((g_sw[sw].ac_in[SW_AC_IN_P]>>14),(g_sw[sw].ac_in[SW_AC_IN_Q]>>14));
		}
		else if(g_sw[sw].ac_in[SW_AC_IN_P]>=Q16_BASE)
		{
			g_sw[sw].ac_in[SW_AC_IN_COS]=Q16_BASE;
		}
		else if(g_sw[sw].ac_in[SW_AC_IN_P]<=-Q16_BASE)
		{
			g_sw[sw].ac_in[SW_AC_IN_COS]=-Q16_BASE;
		}
		else 
		{
			g_sw[sw].ac_in[SW_AC_IN_COS]=0;
		}
		
		g_sw[sw].ac_in_acc[SW_AC_IN_P] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Q] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Pa] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Pb] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Pc] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Qa] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Qb] = 0;
		g_sw[sw].ac_in_acc[SW_AC_IN_Qc] = 0;
		
		g_sw[sw].ac_in_acc[SW_AC_IN_BI_UNBALANCE] = 0;


		

#if 0
		//电子电流互感器小信号电压值
		for(i=0;i<4;i++)
		{
			s16 cfg,scale;
			cfg = g_sw[sw].ac_cfg_index[SW_AC_IA+i];
			if(cfg != INDEX_INVALLID)
			{
				scale = equ_get_ac_scale(g_equ_config_ac[cfg].slot,g_equ_config_ac[cfg].index);
				if(scale == EQU_SCALE_ECT_1V_1A || scale == EQU_SCALE_ECT_0V2_1A)
				{
					g_sw[sw].ac_in[SW_AC_IN_IA_ECT+i] = g_ui[UI_SW_INDEX(sw,SW_AC_IA+i)].e*g_e_k_ECVT[scale];
				}
			}
		}
#endif
	}

 	// 其它测量值
	// 频率
	g_sw_pub.ac_in[PUB_AC_IN_F1] = (qs16)(freq_get(0)*Q16_BASE);  //第1路频率
	g_sw_pub.ac_in[PUB_AC_IN_F2] = (qs16)(freq_get(1)*Q16_BASE);  //第2路频率

	// 直流、温度
	{
		float factor,t,f0,f1;
	#ifdef TMP_CHIP_AHT20
		float h=0.0;
	#endif
#if defined TMP_CHIP_AHT20
		t = aht20_get_temp();
		h = aht20_get_humi();
#endif

		#ifdef DC_TEST_ONE
		f0 = (dc_get(0)-g_dcfactor[0].f_dcL)*g_dcfactor[0].f_dc+dc_adjust[0];
		f1 = 0;	
		#else		
		f0 = (dc_get(0)-g_dcfactor[0].f_dcL)*g_dcfactor[0].f_dc+dc_adjust[0];
		f1 = (dc_get(1)-g_dcfactor[1].f_dcL)*g_dcfactor[1].f_dc+dc_adjust[0];
		#endif
		factor = 1.0;
		if(t > -80.0 &&  t < 125.0)
		{
			factor += (t - g_dc_temp)* pRunSet->f_temp_factor_dc/1000000;
		}
		f0 /= factor;
		f1 /= factor;
        if (pRunSet->dDc_num == 1)
            f1 = 0; // 只有一个通道，将第二个直流通道强制=0
#ifdef CPU_FUXI
		if(f0 < tRunPara.wDC_ZERO)
		{
			f0 = 0.0;
		}
		if(f1 < tRunPara.wDC_ZERO)
		{
			f1 = 0.0;
		}
#endif
	#ifdef TMP_CHIP_AHT20
		g_sw_pub.ac_in[PUB_AC_IN_HUMI] = (qs16)(h*Q16_BASE);
	#endif
		g_sw_pub.ac_in[PUB_AC_IN_TEMP] = (qs16)(t*Q16_BASE);
		g_sw_pub.ac_in[PUB_AC_IN_UZ1] = (qs16)(f0*Q16_BASE);
		g_sw_pub.ac_in[PUB_AC_IN_UZ2] = (qs16)(f1*Q16_BASE);
		if(g_sw_pub.ac_in[PUB_AC_IN_UZ1]<0)
			g_sw_pub.ac_in[PUB_AC_IN_UZ1]=0;
		if(g_sw_pub.ac_in[PUB_AC_IN_UZ2]<0)
			g_sw_pub.ac_in[PUB_AC_IN_UZ2]=0;
	}

	// 电压不平衡度
	if(		g_ui[PUB_AC_UA1].e > g_unit[g_pub_ac_desc[PUB_AC_UA1].unit].zero
		|| 	g_ui[PUB_AC_UB1].e > g_unit[g_pub_ac_desc[PUB_AC_UB1].unit].zero
		|| 	g_ui[PUB_AC_UC1].e > g_unit[g_pub_ac_desc[PUB_AC_UC1].unit].zero)
	{
		g_sw_pub.ac_in[PUB_AC_IN_V_UNBALANCE1] = rt_round(g_sw_pub.ac_in_acc[PUB_AC_IN_V_UNBALANCE1]/cal_num*Q16_BASE);
	}
	else
	{
		g_sw_pub.ac_in[PUB_AC_IN_V_UNBALANCE1] = 0;
	}
	if(		g_ui[PUB_AC_UA2].e > g_unit[g_pub_ac_desc[PUB_AC_UA2].unit].zero
		|| 	g_ui[PUB_AC_UB2].e > g_unit[g_pub_ac_desc[PUB_AC_UB2].unit].zero
		|| 	g_ui[PUB_AC_UC2].e > g_unit[g_pub_ac_desc[PUB_AC_UC2].unit].zero)
	{
		g_sw_pub.ac_in[PUB_AC_IN_V_UNBALANCE2] = rt_round(g_sw_pub.ac_in_acc[PUB_AC_IN_V_UNBALANCE2]/cal_num*Q16_BASE);
	}
	else
	{
		g_sw_pub.ac_in[PUB_AC_IN_V_UNBALANCE2] = 0;
	}
	g_sw_pub.ac_in_acc[PUB_AC_IN_V_UNBALANCE1] = 0;
	g_sw_pub.ac_in_acc[PUB_AC_IN_V_UNBALANCE2] = 0;

#ifdef GD_AREA_YUNAN_LP		// 云南涞浦
	g_sw_pub.ac_in[PUB_AC_IN_DLTUAB] =_AbsL(g_ui[PUB_AC_UAB1].e -g_ui[PUB_AC_UAB2].e);
	g_sw_pub.ac_in[PUB_AC_IN_DLTUBC] =_AbsL(g_ui[PUB_AC_UBC1].e -g_ui[PUB_AC_UBC2].e);
	g_sw_pub.ac_in[PUB_AC_IN_DLTUCA] =_AbsL(g_ui[PUB_AC_UCA1].e -g_ui[PUB_AC_UCA2].e);

	if(g_ui[PUB_AC_UAB1].e>10*Q16_BASE&&g_ui[PUB_AC_UAB2].e>10*Q16_BASE)
	{
		g_sw_pub.ac_in[PUB_AC_IN_ARGUAB] =_AbsL(CalcAngSub(g_ui[PUB_AC_UAB1].ri.r,g_ui[PUB_AC_UAB1].ri.i,g_ui[PUB_AC_UAB2].ri.r,g_ui[PUB_AC_UAB2].ri.i));
	}
	else
	{
		g_sw_pub.ac_in[PUB_AC_IN_ARGUAB]=0;
	}

	if(g_ui[PUB_AC_UBC1].e>10*Q16_BASE&&g_ui[PUB_AC_UBC2].e>10*Q16_BASE)
	{
		g_sw_pub.ac_in[PUB_AC_IN_ARGUBC] =_AbsL(CalcAngSub(g_ui[PUB_AC_UBC1].ri.r,g_ui[PUB_AC_UBC1].ri.i,g_ui[PUB_AC_UBC2].ri.r,g_ui[PUB_AC_UBC2].ri.i));
	}
	else
	{
		g_sw_pub.ac_in[PUB_AC_IN_ARGUBC]=0;
	}
	if(g_ui[PUB_AC_UCA1].e>10*Q16_BASE&&g_ui[PUB_AC_UCA2].e>10*Q16_BASE)
	{
		g_sw_pub.ac_in[PUB_AC_IN_ARGUCA] =_AbsL(CalcAngSub(g_ui[PUB_AC_UCA1].ri.r,g_ui[PUB_AC_UCA1].ri.i,g_ui[PUB_AC_UCA2].ri.r,g_ui[PUB_AC_UCA2].ri.i));
	}
	else
	{
		g_sw_pub.ac_in[PUB_AC_IN_ARGUCA]=0;
	}
#endif
	//版本号0x00010104
	{
		g_sw_pub.ac_in[PUB_AC_IN_VER] =((BYTE)((VER_NUM>>0)&0x0f)
										+((BYTE)(VER_NUM>>4)&0x0f)*10
										+((BYTE)(VER_NUM>>8)&0x0f)*100
										+((BYTE)(VER_NUM>>12)&0x0f)*1000
										+((BYTE)(VER_NUM>>16)&0x0f)*10000)*Q16_BASE;
										
	}

#if 0
	//电子电压互感器小信号电压值
	for(i=0;i<8;i++)
	{
		u8 evt[8]={PUB_AC_UA1,PUB_AC_UB1,PUB_AC_UC1,PUB_AC_U01,PUB_AC_UA2,PUB_AC_UB2,PUB_AC_UC2,PUB_AC_U02};
		s16 cfg,scale;
		cfg = g_sw_pub.ac_cfg_index[evt[i]];
		if(cfg != INDEX_INVALLID)
		{
			scale = equ_get_ac_scale(g_equ_config_ac[cfg].slot,g_equ_config_ac[cfg].index);
			if(scale == EQU_SCALE_EVT_3V25_100V || scale == EQU_SCALE_EVT_6V50_100V)
			{
				g_sw_pub.ac_in[PUB_AC_IN_UA1_EVT+i] = g_ui[evt[i]].e*g_e_k_ECVT[scale];
			}
		}
	}
#endif	
}


void _sw_cal_zl(void)
{
	// 直流、温度
	{
		float factor,t,f0,f1;

#if defined TMP_CHIP_AHT20
		t = aht20_get_temp();
#endif
		f0 = (dc_get(0)-g_dcfactor[0].f_dcL)*g_dcfactor[0].f_dc+dc_adjust[0];
		f1 = (dc_get(1)-g_dcfactor[1].f_dcL)*g_dcfactor[1].f_dc+dc_adjust[0];
		factor = 1.0;
		if(t > -80.0 &&  t < 125.0)
		{
			factor += (t - g_dc_temp)* pRunSet->f_temp_factor_dc/1000000;
		}
		f0 /= factor;
		f1 /= factor;		
		g_sw_pub.ac_in[PUB_AC_IN_TEMP] = (qs16)(t*Q16_BASE);
		g_sw_pub.ac_in[PUB_AC_IN_UZ1] = (qs16)(f0*Q16_BASE);
		g_sw_pub.ac_in[PUB_AC_IN_UZ2] = (qs16)(f1*Q16_BASE);
	}

}

/******************************************************************************
函数名称：	_sw_auto_adjust_pq
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	自动校正PQ，累加校正系数
参数说明：
返回值：	
修改记录：	
*/
void _sw_auto_adjust_pq(void)
{
	float RateP; 
	float RateQ;
	u32 sw,i,j,U,I;
	float pp[3],qq[3];

	RateP = (float)100*5*0.5;	//U*I*COS60
	RateQ = (float)100*5*0.866;	//U*I*SIN60
	
	for(sw=0; sw<g_sw_num; sw++)
	{
		for(j=0; j<3; j++)
		{
			U = PUB_AC_UA1+j;
			I = UI_SW_INDEX(sw,j);

			pp[j] = 0;
			qq[j] = 0;
			
			for(i=1; i<=g_harmonic_num;i++)
			{
				pp[j] += _sw_p2(g_ui[U].h[i].r,g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
				qq[j] += _sw_q2(g_ui[U].h[i].r,g_ui[U].h[i].i,g_ui[I].h[i].r,g_ui[I].h[i].i,g_ui[U].e_factor,g_ui[I].e_factor) ;
			}
			
			g_pq_factor[sw][j].pq[0]	+= (RateQ*qq[j] + RateP*pp[j])/(pp[j]*pp[j] + qq[j]*qq[j]) - 1;
			g_pq_factor[sw][j].pq[1] 	+= (RateQ*pp[j] - RateP*qq[j])/(pp[j]*pp[j] + qq[j]*qq[j]);
		}
	}
 
	return;
}


/******************************************************************************
函数名称：	_sw_ui_e_k
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	通过g_ui的索引得到对应通道的理论比例系数。
参数说明：
	ui_index	通道在g_ui中的索引值
返回值：	对应通道的理论比例系数。
修改记录：	
*/
float _sw_ui_e_k(int ui_index)
{
	int sw,i;
	
	if(ui_index < PUB_AC_NUM)
	{
		i = g_sw_pub.ac_cfg_index[ui_index];
	}
	else
	{
		sw = (ui_index - PUB_AC_NUM)/SW_AC_NUM;
		i =  (ui_index - PUB_AC_NUM)%SW_AC_NUM;
		i =  g_sw[sw].ac_cfg_index[i];
	}

	return factor_e_k(g_equ_config_ac[i].scale);
}


/******************************************************************************
函数名称：	_sw_min_max
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	计算g_ui中连续三个通道中的m2的最小值，最大值，供保护算法使用
参数说明：
	ui_index	通道在g_ui中的索引值
	p_min		返回的最小值
	p_max		返回的最大值
返回值：	
修改记录：	
*/
void _sw_min_max(int ui_index,u32 *p_min,u32*p_max)
{
	u32 min,max,m2;
	int i;
	
	min = -1;
	max = 0;
	for(i=0;i<3;i++)
	{
		if(g_ui[ui_index].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[ui_index].ui_base_make == -1)
		{
			ui_index++;
			continue;
		}
		
		m2 = g_ui[ui_index].m2[0];
		if(m2 < min)
		{
			min = m2;
		}

		if(m2 > max)
		{
			max = m2;
		}

		ui_index++;
	}

	*p_min = min;
	*p_max = max;

	return;
}

/******************************************************************************
函数名称：	_fz_min_max
函数版本：	01.01
创建作者：	xxxxxx
创建日期：	2013-08-07
函数说明：	计算g_ui中连续通道中的幅值的最小值，最大值，供保护算法使用
参数说明：
	ui_index1	起始通道在g_ui中的索引值
	ui_index2	结束通道在g_ui中的索引值
	p_min		返回的最小值
	p_max		返回的最大值
返回值：	
修改记录：	
*/
void _fz_min_max(int ui_index1,int ui_index2,u32 *p_min,u32*p_max)
{
	u32 min,max,m2;
	int i;
	
	min = -1;
	max = 0;
	for(i=ui_index1;i<ui_index2+1;i++)
	{
		if(g_ui[ui_index1].chn_index == CFG_ADC_CHANNEL_ZERO && g_ui[ui_index1].ui_base_make == -1)
		{
			ui_index1++;
			continue;
		}
		
		m2 = g_ui[ui_index1].fz;
		if(m2 < min)
		{
			min = m2;
		}

		if(m2 > max)
		{
			max = m2;
		}

		ui_index1++;
	}

	*p_min = min;
	*p_max = max;
	
	return;
}

/******************************************************************************
函数名称：	_sw_base_angle
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	自动校准时，通道的基本参考角度
参数说明：
	ui_index	通道在g_ui中的索引值
返回值：	参考的角度
修改记录：	
*/
float _sw_base_angle(int ui_index)
{
	static float angle_v[8] = {0,-120,120,0,-120,120,120,120};	// U0、US使用UC角度

#ifdef SW_AC_I0S_SAMPLE
	static float angle_a [SW_AC_NUM] = {0,-120,120,-120,-120,0,-120,120}; 		// I0使用IB值
#else
	static float angle_a [SW_AC_NUM] = {0,-120,120,-120,0,-120,120}; 		// I0使用IB值
#endif

	float angle;

	if(ui_index < PUB_AC_NUM)
	{
		// 电压
		// 将第2组电压映射到第一组上面
		ui_index = ui_index%(PUB_AC_NUM/2);
	
		// 得到基准电压
		angle = angle_v[ui_index];

		// 如果配置不是相电压，U01、US1减30度。
		if((g_ui[PUB_AC_UA1].chn_index == CFG_ADC_CHANNEL_ZERO)
		&& (ui_index == PUB_AC_U01 || ui_index == PUB_AC_US1))
		{
			angle -= 30;
		}
	}
	else
	{
		// 电流
		ui_index = (ui_index - PUB_AC_NUM)%SW_AC_NUM;
		angle = angle_a[ui_index];

		// 如果配置不是相电压，电流减30度。
		if(g_ui[PUB_AC_UA1].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
			angle -= 30;
		}
	}
	
	return angle;
}


/******************************************************************************
函数名称：	_sw_save_dc_factor
函数版本：	01.01
创建作者:	sunxi
创建日期：	2013-08-07
函数说明：	将直流量校正系数保存到内部定值
参数说明：
	dc1	直流量1的校正系数
	dc2 只流量2的校正系数
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
int _sw_save_dc_factor(float dc1_H, float dc1_L,float dc2_H, float dc2_L)
{
	struct dc_factor_save factor[2];
	u8 id[8];
	if(dc1_H != 0.0)
	{
		factor[0].dc_h = dc1_H;
		factor[0].adjust_set = DC_ADJUST;
	}

	if(dc1_L!= 0.0)
	{
		factor[0].dc_l= dc1_L;
		factor[0].adjust_set = DC_ADJUST;
	}

	if(dc2_H != 0.0)
	{
		factor[1].dc_h = dc2_H;
		factor[1].adjust_set = DC_ADJUST;
	}

	if(dc2_L!= 0.0)
	{
		factor[1].dc_l = dc2_L;
		factor[1].adjust_set = DC_ADJUST;
	}
	
	memcpy(id, g_auth_id, 8);
	
	if(dcfactor_createfile(&id[0], (u8*)&factor) != 0)
	{
		rt_printf("直流系数文件保存失败\r\n");
		return -1;
	}
	
	return 0;
}


float g_temp_factor[EQU_SLOT_AC_NUM];

void _sw_temp_factor(void)
{
	int i;
	float t;

#if defined TMP_CHIP_AHT20
	t = aht20_get_temp();
#endif

	if(t < -80.0 ||  t > 125.0)
	{
		// 温度超范围，可能温度传感器坏，使用默认值
		for(i=0; i<EQU_SLOT_AC_NUM; i++)
		{
			g_temp_factor[i] = 1.0;
		}
	}
	else
	{
		//在正常范围内，使用温度校正
		for(i=0; i<EQU_SLOT_AC_NUM; i++)
		{
			factor_temp_get(equ_ac_index_to_slot(i),&g_temp_factor[i]);
			g_temp_factor[i] = t -  g_temp_factor[i];
			g_temp_factor[i] *= pRunSet->f_temp_factor_ac/1000000;
			g_temp_factor[i] += 1.0;
		}
	}

	
	for(i=0;i<UI_NUM;i++)
	{
		if(g_ui[i].chn_index != CFG_ADC_CHANNEL_ZERO)
		{
			g_ui[i].e_factor = g_ui[i].e_factor0*g_temp_factor[g_ui[i].chn_index/16];
		}
		else if(g_ui[i].ui_base_make != -1)
		{
			g_ui[i].e_factor = g_ui[i].e_factor0*g_temp_factor[g_ui[g_ui[i].ui_base_make].chn_index/16];
		}
	}

	return;
}


int sw_get_chnl_ps(int index,bool prim)
{
	int owner,type;
	owner=g_equ_config_ac[index].owner;
	type=g_equ_config_ac[index].type;

	if(owner==0)
	{
		type-=1;
		if(type==PUB_AC_U01||type==PUB_AC_U02)  //零序 PT变比为默认10000/100
		{
			if(prim)	return 10000;
			else return 100;
		}
		else if(PUB_AC_UA2||PUB_AC_UB2||PUB_AC_UC2||PUB_AC_UAB2||PUB_AC_UBC2||PUB_AC_UCA2)
		{	//采用PT2变比 dlj 2019-6-5
			if(prim)return 10000;	
			else return pRunSet->pt2_two;
		}
		else if(type<PUB_AC_NUM)
		{
			if(prim)return 10000;
			else return pRunSet->pt1_two;
		}
	}
	else
	{
		owner-=1;
		type-=1;
		if(type==SW_AC_I0)  //零序 CT变比
		{
			if(prim)	return pRunSet->ct0_one;
			else return pRunSet->ct0_two;
		}
		else if(type==SW_AC_IA||type==SW_AC_IB||type==SW_AC_IC)  
		{
			if(prim)	return pRunSet->ct_one;
			else return pRunSet->ct_two;
		}
	}
	return 1;
}
/*------------------------------ 测试函数 -------------------------------------
一个实体文件必须带一个本模块的测试函数来进行单元测试，如果的确不方便在本模块中
进行单元测试，必须在此注明实际的测试位置（例如在哪个实体文件中使用哪个测试函数）.
*/
int sw_stat_reset(void)
{
	int  i;
	
	for(i=0; i< UI_NUM; i++)
	{
		rt_stat_init(&g_ui[i].m2_stat,g_ui[i].name);
		rt_stat_init(&g_ui[i].e_stat,g_ui[i].name);
		rt_stat_init(&g_ui[i].p_stat,g_ui[i].name);

	}
	
	return 0;
}

int sw_pub_printf(void)
{
	return 0;
}
int sw_pub_printf_v(void)
{
	int i;

//	rt_printf("PUB AC通道模值:\r\n");
//	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\r\n");

	rt_printf("PUB AC通道有效值:\r\n");
	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\r\n");
	for(i=0; i<PUB_AC_NUM; i++)
	{
		rt_stat_printf_q16(&g_ui[i].e_stat);
	}
#if 1
	rt_printf("PUB AC通道角度:\r\n");
	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\r\n");
	for(i=0; i<PUB_AC_NUM; i++)
	{
		rt_stat_printf_q16(&g_ui[i].p_stat);
	}
#endif

	return 0;

}

int sw_printf(void)
{

	return 0;
}


int sw_printf_v(void)
{
	int i,sw;

	rt_printf("SW AC通道有效值:\r\n");
	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\r\n");
	for(sw=0; sw<SWITCH_NUM_MAX; sw++)
	{
		rt_printf("sw%02d\r\n",sw);
		for(i=0; i<SW_AC_NUM; i++)
		{
			rt_stat_printf_q16(&g_ui[PUB_AC_NUM + sw*SW_AC_NUM + i].e_stat);
		}
		for(i=SW_AC_NUM; i<SW_AC_NUM_ALL; i++)
		{
				rt_printf("%s:%s.\r\n",g_sw_ac_desc[i].name,q16_to_str((long)g_sw[sw].ac_in[i]));
		}
	}
	
#if 0
	rt_printf("SW AC通道角度:\r\n");
	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\r\n");
	for(sw=0; sw<SWITCH_NUM_MAX; sw++)
	{
		for(i=0; i<SW_AC_NUM; i++)
		{
			rt_stat_printf_q16(&g_sw[sw].I.i_stat_p[i]);
		}
	}
#endif

	return 0;
}


int sw_ui_printf(void)
{
	int i;

	rt_printf("谐波次数:%d\r\n",g_harmonic_num);
	rt_printf("UI通道:\r\n");
	rt_printf("\t\tm2_factor_k\tm2_factor_c\te_factor\tp_factor\te_ps\r\n");
	
	for(i=0; i<UI_NUM; i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
//			continue;
		}


		rt_printf("%s(%02d,%02d):\t%f\t%f\t%f\t%f\t%f\r\n",
			g_ui[i].name,
			g_ui[i].chn_index ,
			g_ui[i].ui_base_make ,
			(float)g_ui[i].m2_factor_k/Q08_BASE,
			(float)g_ui[i].m2_factor_c/Q16_BASE,
			g_ui[i].e_factor ,
			g_ui[i].p_factor ,
			g_ui[i].e_ps);
	}
	
	return 0;
}

#if 1
void rt_stat_printf_m2(int i,struct rt_stat *stat)
{
	uint32_t avg = 0;
	qs16 qs;
	
	if(stat->cnt)
	{
		avg = stat->sum/stat->cnt;
	}

	rt_printf("%-24s",stat->name);
	qs = _Mul_Div_U(sqrt_32fix(stat->min), 256, g_ui[i].m2_factor_k);
	rt_printf("%f\t", (float)qs/Q16_BASE);
	qs = _Mul_Div_U(sqrt_32fix(stat->max), 256, g_ui[i].m2_factor_k);
	rt_printf("%f\t", (float)qs/Q16_BASE);
	qs = _Mul_Div_U(sqrt_32fix(avg), 256, g_ui[i].m2_factor_k);
	rt_printf("%f\t", (float)qs/Q16_BASE);
	rt_printf("%-016d%d\r\n",stat->sum,stat->cnt);

	return;
}

#else

void rt_stat_printf_m2(int i,struct rt_stat *stat)
{
	uint32_t avg = 0;
	float k;
	
	if(stat->cnt)
	{
		avg = stat->sum/stat->cnt;
	}

	k = _sw_ui_e_k(i);
	rt_printf("%-24s",stat->name);
	rt_printf("%f\t", sqrtf((float)stat->min)/k);
	rt_printf("%f\t", sqrtf((float)stat->max)/k);
	rt_printf("%f\t", sqrtf((float)avg)/k);
	rt_printf("%-016d%d\r\n",stat->sum,stat->cnt);

	return;
}
#endif

int sw_ui_printf_e(void)
{
	int i;

	rt_printf("UI通道:\r\n");
	rt_printf("name\t\t\tmin\t\tmax\t\tavg\t\tsum\t\tcnt\r\n");
	
	for(i=0; i<UI_NUM; i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
	//		continue;
		}

//		rt_stat_printf_m2(i,&g_ui[i].m2_stat);	
		rt_stat_printf_q16(&g_ui[i].e_stat);	
//		rt_stat_printf_q16(&g_ui[i].p_stat);	
	}
	
	return 0;
}

int sw_ui_printf_m(void)
{
	int i;

	rt_printf("UI通道:\r\n");
	rt_printf("name\t\t\tmin\t\tmax\t\tavg\t\tsum\t\tcnt\r\n");
	
	for(i=0; i<UI_NUM; i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
	//		continue;
		}

		rt_stat_printf_m2(i,&g_ui[i].m2_stat);	
	}
	
	return 0;
}


int sw_ui_printf_p(void)
{
	int i;

	rt_printf("UI通道:\r\n");
	rt_printf("name\t\t\tmin\t\tmax\t\tavg\t\tsum\t\tcnt\r\n");
	
	for(i=0; i<UI_NUM; i++)
	{
		if(g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO)
		{
	//		continue;
		}

		rt_stat_printf_q16(&g_ui[i].p_stat);	
	}
	
	return 0;
}

int sw_ui_temp(void)
{
	int i;
	float t;

#if defined TMP_CHIP_AHT20
	rt_printf("温度校正系数[当前温度:%f]:\r\n",
#if defined TMP_CHIP_AHT20
		aht20_get_temp()
#endif		
		);
#endif	
	
	for(i=0; i<EQU_SLOT_AC_NUM;i++)
	{
		factor_temp_get(equ_ac_index_to_slot(i),&t);
		rt_printf("%d[slot=%02d,temp=%f]:%f.\r\n",i,equ_ac_index_to_slot(i),t,g_temp_factor[i]);
	}
	
	rt_printf("谐波校正系数[次数=%d]:\r\n",g_harmonic_num);
	for(i=0; i<CFG_ADC_DOTS_PER_PERIOD/2;i++)
	{
		rt_printf("%02d\t%f.\r\n",i,g_harmonic_factor[i]);
	}
	
	return 0;
}


/*------------------------------ 文件结束 -------------------------------------
*/

