📄 emeter.c
字号:
//**************************************************************************
//
// ESP430CE1 Application Program Example
//
// This file shows exemplarily the usage of the ESP430CE1 module for
// a single-phase emeter with one current sensors (either shunt or
// current transformer).
//
// Modified Stefan Schauer
// date 06/14/2004
// Changes:
// - added Temp. calibration Parameters
// - fixed bouncing of Idle Key
// - added flag for Neg. Energy Measurement at LED
// - Impoved Idle Mode Current (switch of TimerA and LED)
// - Impoved Debouncing if Keys
// - added defSET_ADAPTI1 to ts_paramters
// - splitted ESP_Init_Parameter to ESP_Init and ESP_init_parameters
// - added read_paramter function
// - moved Request handling for Temp. Measurement to main.c
// - added _DINT _EINT to set_parameter and read_parameter functions
//
// Version 1.0 first release for Application Report
// 06/14/04
// Version 1.1
// 08/19/04 Fixed wrong initalisation of INCH (Wrong register used)
// (no error produced as no wrong bit was set)
// Added POFFSETx to Parameter struct
// Added Mailbox interrupt enable to start_calibration
// Version 1.2
// 01/17/05 Enhanced and fixed negative Energy detection
// 01/17/05 read_parameter - stored Parameter in temp variable to avoid
// overwritting
// 01/17/05 Added Temp. Compensation function for PhaseShift
// 03/01/05 added disabling of Temp. Measurement
// 03/07/05 Moved checkkeys function into main routine
// Removed Averaging function
// 04/22/05 Removed _EINT form set_parameter
// Added _EINT to start_measurement and start_calibration
// Switched of Calibration mode if done in ESP430_ISR
// 04/26/05 Fixed detection of neg. Energy
//
//**************************************************************************
/* ***********************************************************
* THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
* REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
* INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
* COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
* TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
* POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
* INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
* YOUR USE OF THE PROGRAM.
*
* IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
* THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
* OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
* EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
* REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
* OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
* USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
* AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
* YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
* (U.S.$500).
*
* Unless otherwise stated, the Program written and copyrighted
* by Texas Instruments is distributed as "freeware". You may,
* only under TI's copyright in the Program, use and modify the
* Program without any charge or restriction. You may
* distribute to third parties, provided that you transfer a
* copy of this license to the third party and the third party
* agrees to these terms by its first use of the Program. You
* must reproduce the copyright notice and any other legend of
* ownership on each copy or partial copy, of the Program.
*
* You acknowledge and agree that the Program contains
* copyrighted material, trade secrets and other TI proprietary
* information and is protected by copyright laws,
* international copyright treaties, and trade secret laws, as
* well as other intellectual property laws. To protect TI's
* rights in the Program, you agree not to decompile, reverse
* engineer, disassemble or otherwise translate any object code
* versions of the Program to a human-readable form. You agree
* that in no event will you alter, remove or destroy any
* copyright notice included in the Program. TI reserves all
* rights not specifically granted under this license. Except
* as specifically provided herein, nothing in this agreement
* shall be construed as conferring by implication, estoppel,
* or otherwise, upon you, any license or other right under any
* TI patents, copyrights or trade secrets.
*
* You may not use the Program in non-TI devices.
* ********************************************************* */
#include "device.h"
#include "emeter.h"
#include "SendData.h"
#include "parameter.h"
#include "display.h"
#include "TimerA.h"
#include "portfunc.h"
// const and var definition
/// global flag for Edge detection
unsigned char ZXLDFGedge = 0;
/// global flag for Negative Energy
unsigned char negenfg = 0;
/// Saves firmware version during initialization.
unsigned int firmware_version;
/// Cumulated active energy.
float total_energy;
/// Last temperature measurement result.
unsigned int temperature;
//*************************************************************
struct ts_parameters s_parameters;
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ < 200
#pragma memory=constseg(INFOA)
#else
#pragma constseg=INFOA
#endif
#endif
#ifdef __CROSSWORKS_MSP430
#pragma constseg("INFO")
#endif
#ifdef __TI_COMPILER_VERSION__
#pragma DATA_SECTION(s_parameters_flash, ".infoA")
#endif
const struct ts_parameters s_parameters_flash =
{
defVRatio,
defIRatio,
defEnergyRatio,
defSET_PHASECORR1,
defSET_PHASECORR2,
defSET_GAINCORR1,
defSET_GAINCORR2,
defSET_V1OFFSET,
defSET_I1OFFSET,
defSET_I2OFFSET,
defSET_ADAPTI1,
defSET_ADAPTI2,
defSET_STARTCURR_INT,
defSET_STARTCURR_FRAC,
{defSET_INTRPTLEVL_LO,
defSET_INTRPTLEVL_HI},
defTempGain,
defTempOffset,
0, // P1Offset
0 // P2Offset
};
#ifdef withTempCorrection
#define PHI_Corr(x) (int)(x/(360ul*defSET_NOMFREQ)*POW_2_20 + 0.5)
const int phasecorr_table[] = {
PHI_Corr(-60*PHI_Temp_Ratio), // -40 <-> -30
PHI_Corr(-50*PHI_Temp_Ratio), // -30 <-> -20
PHI_Corr(-40*PHI_Temp_Ratio), // -40 <-> -10
PHI_Corr(-30*PHI_Temp_Ratio), // -10 <-> 0
PHI_Corr(-20*PHI_Temp_Ratio), // 0 <-> 10
PHI_Corr(-10*PHI_Temp_Ratio), // 10 <-> 20
PHI_Corr( 0*PHI_Temp_Ratio), // 20 <-> 30
PHI_Corr( 10*PHI_Temp_Ratio), // 30 <-> 40
PHI_Corr( 20*PHI_Temp_Ratio), // 40 <-> 50
PHI_Corr( 30*PHI_Temp_Ratio), // 50 <-> 60
PHI_Corr( 40*PHI_Temp_Ratio), // 60 <-> 70
PHI_Corr( 50*PHI_Temp_Ratio), // 70 <-> 80
PHI_Corr( 60*PHI_Temp_Ratio), // 80 <-> 85
};
#endif
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ < 200
#pragma memory=default
#else
#pragma constseg=default
#endif
#endif
#ifdef __CROSSWORKS_MSP430
#pragma dataseg(default)
#endif
unsigned int CalCyclCnt = 0; // Register for Cycle calculation of Calibration
unsigned int wfs1;
unsigned int wfs2;
unsigned int wfs3;
union ts_long_word energy;
union ts_long_word tempenergy;
signed long sumenergy = 0;
signed long maxenergy = 0;
unsigned long P_reading = 0;
unsigned int uiIntLevelRepeatCount = defSET_INTRPTLEVL_REPEAT;
void display_error(void)
{;}
//====================================================================
/**
* Analog front-end initialization routine.
*
* Configures the sigma-delta ADC module as analog front-end for
* a tamper-resistant meter using a current transformer and a
* shunt as current sensors (see configuration of channel 0 and 1).
*/
void init_analog_front_end(void)
{
/**
* First it makes sure that the Embedded Signal Processing is
* disabled, otherwise it wouldn't be possible to modify the
* SD16 registers.
*/
ESPCTL &= ~ESPEN;
/**
* Then the general configurations of the analog front-end are done
* that apply to all channels: clock selection (SMCLK) and divider
* settings (depending on SMCLK frequency) and reference voltage
* selections.
*/
SD16CTL= SD16SSEL_1 // Clock selection: SMCLK
#if (MCLK_FREQ == 2)
| SD16DIV_1 // divide by 2 => ADC clock: 1.094MHz
#endif
#if (MCLK_FREQ == 4)
| SD16DIV_2 // divide by 4 => ADC clock: 1.094MHz
#endif
#if (MCLK_FREQ == 8)
| SD16DIV_3 // divide by 8 => ADC clock: 1.094MHz
#endif
| SD16REFON; // Use internal reference
SD16INCTL0 = SD16INCH_0; // I1
SD16INCTL1 = SD16INCH_0; // I2
SD16INCTL2 = SD16INCH_0; // V
// -------------------------------------------------------------------
/**
* - Selection of ADC gain:
* - VIN,MAX(GAIN = 1) = 0.5V > VCT(Peak)
* - VIN,MAX(GAIN = 2) = 0.25V < VCT(Peak)
* - VIN,MAX(GAIN = 16) = 0.031V > VShunt(Peak)
* - VIN,MAX(GAIN = 32) = 0.015V < VShunt(Peak)
*/
// -----------------------------------------------------------
// Configure analog front-end channel 2 - Current 1
SD16INCTL0 |= I1_Gain; // Set gain for channel 0 (I1)
SD16CCTL0 = SD16OSR_256; // Set oversampling ratio to 256 (default)
// -----------------------------------------------------------
// Configure analog front-end channel 1 - Current 2
SD16INCTL1 |= I2_Gain; // Set gain for channel 1 (I2)
SD16CCTL1 = SD16OSR_256; // Set oversampling ratio to 256 (default)
// -----------------------------------------------------------
// Configure analog front-end channel 2 - Voltage
SD16INCTL2 |= V_Gain; // Set gain for channel 2 (V)
SD16CCTL2 = SD16OSR_256; // Set oversampling ratio to 256 (default)
/**
* \note
* Please note, that the oversampling ratio should be identical
* for all channels. Default is 256.
*/
} // End of init_analog_front_end()
//====================================================================
/**
* Sets one parameter of the ESP430CE1 module.
*
* The parameter \a param is loaded with \a data.
*
* \param param Parameter to be set.
* \param data Data to be loaded into parameter.
*/
void set_parameter(unsigned int param, unsigned int data)
{
volatile unsigned int timeout= 0xffff;
// /\ Prevent variable from being "optimized".
_DINT();
MBOUT1= data;
MBOUT0= param;
do
{
while (((MBCTL & IN0IFG) == 0) && ((--timeout) > 0)) ;
if (timeout == 0) { display_error(); _EINT(); return; }
} while ((MBIN0 != mPARAMSET) || (MBIN1 != param));
//_EINT();
}
//====================================================================
/**
* Read one parameter of the ESP430CE1 module.
*
* The parameter \a param is read
*
* \param param Parameter to be read.
*/
unsigned int read_parameter(unsigned int param)
{
volatile unsigned int timeout= 0xffff;
unsigned int temp;
// /\ Prevent variable from being "optimized".
_DINT();
MBOUT1= param;
MBOUT0= mREAD_PARAM;
do
{
while (((MBCTL & IN0IFG) == 0) && ((--timeout) > 0)) ;
if (timeout == 0) { display_error(); _EINT(); return(0); }
temp = MBIN1; // save data in temp variable to aviod overwrite
} while (MBIN0 != mPARAMRDY);
_EINT();
return (temp);
}
//====================================================================
/**
* Initializes ESP430CE1.
*
*/
void init_esp(unsigned char flashvars)
{
volatile unsigned int timeout;
// /\ Prevent variable from being "optimized".
// copy predevined init values to RAM
if (flashvars) s_parameters = s_parameters_flash;
/**
* Makes sure that the Embedded Signal Processing
* is enabled,
*/
ESPCTL |= ESPEN;
MBCTL = 0;
/**
* that it is not in measurement or calibration mode,
*/
if ((RET0 & 0x8000) != 0)
{
// Set Embedded Signal Processing into "Idle" mode
MBOUT1= modeIDLE; // ESP_IDLE;
MBOUT0= mSET_MODE;
timeout= 0xffff;
while (((RET0 & 0x8000) != 0) && (timeout-- > 0)) ;
}
/**
* and that it is ready to receive messages by requesting the
* firmware version.
*/
MBOUT0= mSWVERSION;
timeout= 0xffff;
do
{
while (((MBCTL & IN0IFG) == 0) && (timeout-- > 0)) ;
if (timeout == 0) { display_error(); return; }
} while (MBIN0 != mSWRDY);
firmware_version= MBIN1; // Save firmware version.
init_esp_parameters(flashvars);
} // End of init_esp()
//====================================================================
/**
* Initializes ESP430CE1 Paramters
*
*/
void init_esp_parameters(unsigned char flashvars)
{
volatile unsigned int timeout;
// /\ Prevent variable from being "optimized".
// copy predevined init values to RAM
if (flashvars) s_parameters = s_parameters_flash;
/**
* Then the parameters are initialized.
*
* Control 0: make settings for :
* - Use current channel I2 - tamper-detection
* - Count absolute active energy
* (negative energy is considered as tampering)
* - Switch DC removal alorithm on for I1
* - Switch DC removal alorithm on for I2
*/
set_parameter(mSET_CTRL0, defSET_CTRL0);
/**
* \Set Number of Measurement:
* e.g. 4096 * 50Hz. => int after 1sec
*/
set_parameter(mSET_INTRPTLEVL_LO, s_parameters.pSET_INTRPTLEVL.w[0]);
set_parameter(mSET_INTRPTLEVL_HI, s_parameters.pSET_INTRPTLEVL.w[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -