📄 emeter_3ph_foreground.c
字号:
//**************************************************************************
//*
//* This is the main routine for 3_ph emeter.
// Foreground process includes:
// -Using timer tick to wait
// -Calculating the power per channel
// -Displaying the power using SPI to communicate with external F413
// -Determine if current channel needs scaling.
// -Determine if needs to be in low power modes.
// -Compensate reference from Temperature sensor
//
// Vincent Chan
// Texas Instruments Hong Kong Ltd
// Date Comments
// =====================
// 01/09/19 Code Starts
// 01/10/23 Calibration for CT and reference meter algorithm done
// Added in power factor features
// Display now does, power factor, phase shift, active and reactive
// power.
// 01/10/24 CT correction has been tested. Found bug in sampling rate
// it was incorrectly set to 2.8Ksps, adjusted TIMER_B to
// make in 3.2ksps.
// Calibrated result is now store in Flash.
// 01/11/27 Calibration working and storing in flash.
// Calibration done using "high gain" range.
// "low gain" range calibration is worked out internally.
// 01/12/3 Found and corrected bug in the line ADC12MCTL1&=~SREF_7
// should be ADC12MCTL1&=~(SREF_7) otherwise the mask's lsnibble is 0
// not 0xf;
//
// To Do List
// -Do reference temperature calibration
//**************************************************************************
#include "emeter_3phase.h"
#include "math.h"
long chan1_long_params[12];
long chan2_long_params[12];
long chan3_long_params[12];
//#defines are done in emeter_3phase.h
//#define V_accum 0 //accumulates voltage samples
//#define logged_V_accum 1 //stores accumulator after a number of cycles
//#define I_accum 2 //accumulates current samples
//#define logged_I_accum 3 //stores accumulator after a number of cycles
//#define P_accum 4 //accumulates power samples
//#define logged_P_accum 5 //stores accumulator after a number of cycles
//#define E_accum 6
//#define E_accum_threshold 7
//#define E_accum_count 8
//#define PS_P_accum 9 //accumulates phase shifted power samples
//#define logged_PS_P_accum 10 //stores phase shifted accumulator after a number of cycles
//#define POWER_SCALE_FACTOR 11
int chan1_int_params[22];
int chan2_int_params[22];
int chan3_int_params[22];
//#defines are done in emeter_3phase.h
//#define V_cycle_counter 0 // contains number of voltage cycles
//#define I_cycle_counter 1 // contains number of current cycles
//#define P_cycle_counter 2 // contains number of power cycles
//define V_count 3 // contains number of voltage samples accumulated
//define logged_V_count 4 // stores number of sampples after a number of cycles
//define I_count 5 // contains number of current samples accumulated
//define logged_I_count 6 // stores number of sampples after a number of cycles
//define P_count 7 // contains number of power samples accumulated
//define logged_P_count 8 // stores number of sampples after a number of cycles
//define V_bias 9 // contains uptodate voltage dc_bias level
//define I_bias 10 // contians uptodate current dc_bias level
//define channel_status 11 // contains status use for detecting a threshold
//define V_POS 0x1 // these are flags defined for channel_status
//define I_POS 0x2
//define NEW_V_LOG 0x4
//define NEW_I_LOG 0x8
//define NEW_P_LOG 0x10
//define E_TICK 0x20
//define PS_P_count 12 // contains number of phase shifted power samples accumulated
//define logged_PS_P_count 13 // stores number of phase shifted samples after a number of cycles
//define FIR_POINTER 14 // points to the FIR entrance in the table
//define FIR_TAP 15
//define FIR_BETA 16
//define FIR_GAIN 17
//define I_above_threshold_counter 18
//define logged_I_above_threshold_counter 19
int FIR_current_chan1[3]; //these are the CT compesation FIR parameters
int FIR_current_chan2[3]; //these are the CT compesation FIR parameters
int FIR_current_chan3[3]; //these are the CT compesation FIR parameters
int samples_write_index; //voltage and current samples are stored in a buffered
//accessed by these pointers
int samples_read_index;
int voltage_buffer_chan1[64]; //64 samples are stored for current and voltage
int current_buffer_chan1[64]; //this is equivalent to 1 cycle
int voltage_buffer_chan2[64]; //64 samples are stored for current and voltage
int current_buffer_chan2[64]; //this is equivalent to 1 cycle
int voltage_buffer_chan3[64]; //64 samples are stored for current and voltage
int current_buffer_chan3[64]; //this is equivalent to 1 cycle
int sinne_1,sinne_2; //simulation for current and voltage
int power_led_length_count;
int global_counter;
long logged_shifted_p_accum,shifted_p_accum;
int logged_shifted_p_count,shifted_p_count,shifted_samples_read_index;
double chan1_ratio;
double chan2_ratio;
double chan3_ratio;
int chan1_power;
int chan2_power;
int chan3_power;
long chan1_total_power,chan1_shifted_total_power;
long chan2_total_power,chan2_shifted_total_power;
long chan3_total_power,chan3_shifted_total_power;
long chan1_low_gain_threshold;
long chan1_high_gain_threshold;
long chan2_low_gain_threshold;
long chan2_high_gain_threshold;
long chan3_low_gain_threshold;
long chan3_high_gain_threshold;
int chan1_energy_period,chan1_last_TAR_reading;
int chan2_energy_period,chan2_last_TAR_reading;
int chan3_energy_period,chan3_last_TAR_reading;
int instant_temperature,instant_VeREF_PLUS,instant_VeREF_MINUS;
int average_VeREF_range,average_temperature;
int average_HALF_VCC,instant_HALF_VCC;
int master_stability_counter;
int display_stage,display_phase;
int ticker,seconds,minutes,hours,days;
extern const int FIR_COEFF[254];
extern unsigned int CH1_FLASH_INFO_FIR_PTR;
extern unsigned int CH2_FLASH_INFO_FIR_PTR;
extern unsigned int CH3_FLASH_INFO_FIR_PTR;
extern long CH1_FLASH_INFO_E_accum_threshold;
extern long CH2_FLASH_INFO_E_accum_threshold;
extern long CH3_FLASH_INFO_E_accum_threshold;
extern long CH1_FLASH_INFO_POWER_SCALE_FACTOR;
extern long CH2_FLASH_INFO_POWER_SCALE_FACTOR;
extern long CH3_FLASH_INFO_POWER_SCALE_FACTOR;
extern int FLASH_INFO_average_temperature;
extern int FLASH_INFO_average_VeREF_range;
//--------------------------------------------------------------------------
void main(void); // Initialization of System/Control Registers
//--------------------------------------------------------------------------
#define CALIBRATE 0
#define STORE_INFO 0
#define STORE_TEMP_COEFF 0
#define SINGLE_PHASE 1
void display_readings(int power, double ratio);
int __low_level_init(void)
{
/* Insert your low-level initializations here */
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
FLL_CTL0 = XCAP0PF;
/*==================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit seg_init */
/* 1 to run seg_init */
/*==================================*/
return (1);
}
void main(void)
{
int i;
int j,k,l;
float power_gain;
int* i_ptr;
long* l_ptr;
float* f_ptr;
int toggle=0;
system_setup();
DISPLAY(12345,0); //to show lcd is o.k.
_EINT();
sinne_1=sinne_2=0; //use simulated CT shift here
sinne_2+=0x6d; //add 0.6 degree phase lead to simulate CT shift
// = 0.6/360 * 65536
#if !SIMULATED_INPUT
#if CALIBRATE
//Needs some more work to add the other two channels
//for(j=1;j<4;j++)
#if SINGLE_PHASE
for(j=1;j<2;j++)
#else
for(j=1;j<4;j++)
#endif
{
if(j==1)
{
i_ptr = chan1_int_params;
l_ptr = chan1_long_params;
}
else if(j==2)
{
i_ptr = chan2_int_params;
l_ptr = chan2_long_params;
}
else
{
i_ptr = chan3_int_params;
l_ptr = chan3_long_params;
}
do
{
DISPLAY_1DIGIT(j,6);
i=calibrate_CT(i_ptr,l_ptr);
//this will return the phase delay divided
//by the minimum CT compensation step
//FIR takes care of max 63/64 of 5.6 degree
//if >64 then needs to adjust current read
//pointer
i_ptr[FIR_POINTER]-=i*2; //each step has two integar constants
//update the FIR parameters accordingly
i_ptr[FIR_BETA]=FIR_COEFF[i_ptr[FIR_POINTER]];
i_ptr[FIR_GAIN]=FIR_COEFF[i_ptr[FIR_POINTER]+1];
//display the integer steps here
if(i<0)
{
DISPLAY_1DIGIT(D_MINUS,5);
i=-i;
}
else DISPLAY_1DIGIT(D_CLEAR,5); //clear sign bit
DISPLAY(i,0);
}while(i!=0); //do calibration until phase shift is zero.
// power_gain = (float) chan1_low_gain_threshold;
// power_gain=power_gain*4096;
// power_gain = power_gain/ (float) FLASH_INFO_average_VeREF_range;
// power_gain = power_gain/ (float) average_VeREF_range;
// chan1_long_params[E_accum_threshold]= (long)power_gain;
// ADC12CTL0 &=~ ENC; //temp stop ADC
// ADC12MCTL1&=~SREF_1; //set value to higher gain
// ADC12MCTL1|=SREF_6; //by using the lower voltage external reference
// ADC12CTL0 |= ENC; //start ADC again
//sync_with_reference();
//l_ptr[E_accum] = 0;
calibrate_starts(i_ptr, l_ptr);
calibrate_starts(i_ptr, l_ptr);
}//EOF for (j=1;j<4;j++)
sync_with_reference();
chan1_long_params[E_accum] = 0;
chan2_long_params[E_accum] = 0;
chan3_long_params[E_accum] = 0;
#endif
#if STORE_INFO
#if SINGLE_PHASE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -