📄 emeter_3ph_background.c
字号:
//**************************************************************************
//* 信号采样
//* This is the master background process. The interrupt is set at 3276.8Hz
//
// The background process deals with the input samples.
// These are first stored into buffers.
// The buffered samples are processed as follows:
// -Voltage and Current signals are converted to zero DC AC signals
// -The Current Signal is phase compensated
// -Voltage and Current are signed multiplied to give power.
// -Power samples are acummulated. The accumulated power samples are averaged (in foreground.c)
// afte a number of voltage cycles has been detected (in dcbias.c).
//
//
// Vincent Chan
// Texas Instruments Hong Kong Ltd
// Date Comments
// =====================
// 01/09/19 Code Starts
// 01/10/07 First cut testing done using simulated sinne inputs.
// 01/10/11 Connected to real power, found that Current is inverted
// 01/10/23 Optimised the code so that buffer stores A.C. phase compensated signals
// Also added extra power calculation for phase shifted power.
// 01/11/28 The pulse is now issued as negative rather than positive.
//
//Note to users: This code is given in an as is basis and we do not guarantee
// it would work 100% without faults. Texas Instrements does not
// take responsibility on the maintainance of this code.
//**************************************************************************
#include "emeter_3phase.h"
#define ADCMEM ((int*) 0x0140) // ADC12MEMx definition
extern int voltage_buffer_chan1[64];
extern int current_buffer_chan1[64];
extern int voltage_buffer_chan2[64];
extern int current_buffer_chan2[64];
extern int voltage_buffer_chan3[64];
extern int current_buffer_chan3[64];
extern int chan1_int_params[22];
extern long chan1_long_params[12];
extern int chan2_int_params[22];
extern long chan2_long_params[12];
extern int chan3_int_params[22];
extern long chan3_long_params[12];
extern int samples_write_index;
extern int samples_read_index;
extern int sinne_1,sinne_2;
extern int power_led_length_count;
extern int instant_temperature,instant_VeREF_PLUS,instant_VeREF_MINUS,instant_HALF_VCC;
int simulated_voltage,simulated_current;
//Simulated Input
//--------------------------------------------------------------------------
// This the main interrupt routine where all the signal processing is done
//--------------------------------------------------------------------------
interrupt [TIMERB0_VECTOR] void Timer_B0(void)
{
int V_sample, I_sample,i,TAR_reading;
long power_sample;
//--------------------------------------------------------------------------
// CHANNEL ONE
//--------------------------------------------------------------------------
#if SIMULATED_INPUT
//****************************************************
//generate signal for use in testing, assume 50Hz and sampling freq of 3276.8
// 65.536 samples/cycle
//****************************************************
//sinne_gen returns +/- 1024 pk-pk
//= 1.25V pk-pk
V_sample=sinne_gen(&sinne_1, 1000)+2500;
//simulate max current and voltage
//=(2V/2.5V)*32768
I_sample=sinne_gen(&sinne_2, 1000);
//simulate max current and voltage
//=(2V/2.5V)*32768
//I_sample=FRACTIONAL_SIGNED_MUL(I_sample,0x6666);
I_sample+=1900; //add different DC bias
simulated_current=I_sample;
simulated_voltage=V_sample;
#else
//****************************************************
// Read ADC results for Channel 1 voltage and current
//****************************************************
//read current value
I_sample=ADC12MEM[1];
//voltage is sampled twice both before and after current
//so need to average to find out the value in the middle
V_sample=(ADC12MEM[0]+ADC12MEM[2])>>1;
#endif
//*****************
// Time Stampe
//P1OUT|=BIT0;
//*****************
//****************************************************
// Take DC bias away from voltage and current samples
// Take CT lag away from current sample
// Store in Chan1 buffer
//****************************************************
//get rid of the bias and calculate overall bias
extract_dc_bias(&chan1_long_params[0],&chan1_int_params[0],&V_sample,&I_sample);
//get rid of CT delay for the current
I_sample=FIR(chan1_int_params,I_sample);
//store into buffers
current_buffer_chan1[samples_write_index]=I_sample;
voltage_buffer_chan1[samples_write_index]=V_sample;
//if(samples_write_index>=SAMPLE_BUFFER_SIZE)
// samples_write_index=0;
//****************************************************
// Now comes the reading part, both current and voltage is
// out and the power is calculated and put is power_sample.
// Power_sample is accumulated and averaged to work out the average power
// It also accumulated and used to generate the energy count.
//****************************************************
V_sample=voltage_buffer_chan1[samples_read_index];
I_sample=current_buffer_chan1[samples_read_index];
power_sample=SIGNED_MUL(V_sample,I_sample);
chan1_long_params[P_accum]+=power_sample;
++chan1_int_params[P_count];
power_sample>>=4; //need scaling down
//power_sample>>=7;
chan1_long_params[E_accum]+=power_sample;
if(chan1_long_params[E_accum]>=chan1_long_params[E_accum_threshold])
{
TAR_reading=TAR;
chan1_int_params[ENERGY_PERIOD]=TAR_reading;
chan1_int_params[ENERGY_PERIOD]-=chan1_int_params[LAST_TAR];
chan1_int_params[LAST_TAR]=TAR_reading;
chan1_long_params[E_accum]-=chan1_long_params[E_accum_threshold];
++chan1_long_params[E_accum_count];
chan1_int_params[channel_status]|=E_TICK;
P3OUT&=~CHAN1_PULSE;
power_led_length_count=0;
}
//******************************************************
// A second power is calculated based on the current sample
// phase lagged by 60.4 degrees or 11 samples
// each sample = (50/3276.8)*360 = 5.4931640625 degree
// delay by 11 samples or 60.4 degree
// This phase lagged sample is multiplied by the none phase shifted
// voltage sample, the result power sample is used to calculate
// the relative phase shift between the incoming current and voltage
// signal. It is also used to self compensate for the CT lag
// The resultant power is stored in a separate buffer and then averaged
//*******************************************************
i=samples_read_index;
i-=11;
i&=0x3f; //circular buffer adjust, buffer size must be
//64!!!!
I_sample=current_buffer_chan1[i];
chan1_long_params[PS_P_accum]+=SIGNED_MUL(V_sample,I_sample);
++chan1_int_params[PS_P_count];
//--------------------------------------------------------------------------
// CHANNEL TWO
//--------------------------------------------------------------------------
#if SIMULATED_INPUT
//****************************************************
//generate signal for use in testing, assume 50Hz and sampling freq of 3276.8
// 65.536 samples/cycle
//****************************************************
//use previously simulated results
I_sample=simulated_current;
V_sample=simulated_voltage;
#else
//****************************************************
// Read ADC results for Channel 1 voltage and current
//****************************************************
//read current value
I_sample=ADC12MEM[4];
//voltage is sampled twice both before and after current
//so need to average to find out the value in the middle
V_sample=(ADC12MEM[3]+ADC12MEM[5])>>1;
#endif
//****************************************************
// Take DC bias away from voltage and current samples
// Take CT lag away from current sample
// Store in Chan1 buffer
//****************************************************
//get rid of the bias and calculate overall bias
extract_dc_bias(&chan2_long_params[0],&chan2_int_params[0],&V_sample,&I_sample);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -