交流电压信号处理以及RMS计算

定时器中断中对ADC数据进行采集并累加平方和,在本场景下是因为输入输出电压相位相同,输入电压是半波,主要为了确定周期(为适配不同电网情况50-60Hz),输出电压是全波,每次20ms采集并运算输出。

存在几个可能的疑问点:

1.20ms运算可能太慢了,要考虑一下是不是符合需求。

2.我为什么做20ms,是因为硬件不是我负责,这个半波由于添加了二极管(0.1V的压降),实测相比于正常的波形是有整体下移的,也就是说零点不是那么准。我只能选择从零点到零点这样的方法才能正确确定周期。

3.Vout_Zero是上电时确定的零点位置,实际上最好对零点在循环中实时确定。后续应该会做修改,电流上的410也是。但是目前整体实测是准的

4.滤波函数Filter就是个普通的滑动滤波

后续更新:

增加零点的实时确定。

void main(void)
{
   if(Read20msEnd_flag==1)//采200个点后结束标志位,进行rms计算
	{
		Read20msEnd_flag=0;
		v_out =(float)sqrtf(SUM_VOCPY / v20msCpy_count)*2.429f;//输出电压均方根
		v_AI =(float)sqrtf(SUM_IOCPY / v20msCpy_count)*0.85f;//输出电流均方根
		v_in =(float)sqrtf(SUM_VICPY / (v20msCpy_count/2))*0.8243f;//输入电压均方根
	}
}
void TIM2_IRQHandler(void) //50us=20k频率
{
	static uint16_t  con_20ms,con_100us,con_otherms;
	static uint16_t  con_500ms, TEMP;

	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{		
		static uint8_t freq_flag=0;
		static uint8_t count_high=0;	
		TEMP=(float) ADC_ConvertedValue[2]/5;//输入电压,半波
		if(TEMP<=1) //负半周
		{
            
		}
		else if(TEMP>=3) //正半周
		{
			if(count_high++==8)//确定为负半轴零点
			{
				freq_flag=1;
			}
		}
		// if(freq_flag==1)
		// {
		// 	freq_flag=0;
		// 	freqCpy_positive=freq_positive;
		// 	freq_positive=0;
		// }
		// freq_positive++;
	//---------------------------------	
		if(freq_flag==1)//周期到了,结束平方和运算,置标志位
		{
			freq_flag=0;
			Read20msEnd_flag = 1;
			v20msCpy_count=v20ms_count;
			SUM_VOCPY=SUM_VO;
			SUM_IOCPY=SUM_IO;
			SUM_VICPY=SUM_VI;
			SUM_VO=0;
			SUM_IO=0;
			SUM_VI=0;
			v20ms_count=0;
		}		
		con_100us++;
		if(con_100us>=2)//每100us进行一次RMS累加运算
		{
			LED_3=~LED_3;
			con_100us=0;
			flag_100us=1;
			v20ms_count++;
			uint16_t raw_vi=ADC_ConvertedValue[2]/5;//输入电压
			uint16_t raw_VoltageO = ADC_ConvertedValue[1]/5;//输出电压
			uint16_t raw_Current= ADC_ConvertedValue[0]/5;//输出电流

			uint16_t fliter_ii=Raw_Filter_II(raw_Current);
			uint16_t fliter_vi=Raw_Filter_VI(raw_vi);
			uint16_t fliter_vo=Raw_Filter_VO(raw_VoltageO);
			
			Ins_VoltageO=fliter_vo-(Vout_Zero/5);
			SUM_VO+=(uint32_t)Ins_VoltageO*Ins_VoltageO;

			Ins_Current = fliter_ii-410;
			SUM_IO+=(uint32_t)Ins_Current*Ins_Current;

			if(fliter_vi<1)	fliter_vi=0;
			else Ins_VoltageI=(int32_t)fliter_vi;
			SUM_VI+=(uint32_t)(Ins_VoltageI*Ins_VoltageI);
			LED_3=~LED_3;
		}			 
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值