⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emeter_3ph_background.c

📁 TI三相电能表源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//**************************************************************************
//*   信号采样
//*   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 + -