?? rms.c
字號:
/***************************************************************************
* This code and information is provided "as is" without warranty of any *
* kind, either expressed or implied, including but not limited to the *
* implied warranties of merchantability and/or fitness for a particular *
* purpose. *
* *
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
***************************************************************************/
//**************************************************************************
// DESCRIPTION: 71M65xx POWER METER - root-mean-square.
//
// AUTHOR: MTF
//
// HISTORY: See end of file
//**************************************************************************
// File: RMS.C
//
#include "options.h"
#if RMS_VALUES
#include "ce.h"
#include "defaults.h"
#include "lcd.h"
#include <math.h>
#include "mmath.h"
#include "meter.h"
// Decimals points: Vrms/Irms have an LSB of 0.1, the display is 1000
// A production meter might roll all the constants into these.
//
#if M6520 || TRACE11
#define IRMSSCALE 4.90945E-03 // (1000/10)*sqrt(6.6952e-13*3600)
#define VRMSSCALE 4.90945E-03 // (1000/10)*sqrt(6.6952e-13*3600)
#elif TRACE13
#define IRMSSCALE 5.81861E-03 // (1000/10)*sqrt(9.4045e-13*3600)
#define VRMSSCALE 5.81861E-03 // (1000/10)*sqrt(9.4045e-13*3600)
#else
#error Unknown device
#endif
/*** Public variables declared within this module ***/
// None.
/*** Private functions declared within this module ***/
static void display_vrms (int32_t xdata *d);
static uint32_t Vrms (int32_t xdata *w);
static void display_irms (int32_t xdata *d);
static uint32_t Irms (int32_t xdata *w);
static int32_t sqrt_rms (int32_t x);
/*** Private variables declared within this module ***/
int32x_t dummy;
//===========================================================================//
void Compute_RMS (void)
{
Irms_A = sqrt_rms (i0sqsum);
Vrms_A = sqrt_rms (v0sqsum);
Irms_B = sqrt_rms (i1sqsum);
#if EQUATION != _1ELEMENT_2WIRE
Vrms_B = sqrt_rms (v1sqsum);
#else
Vrms_B = 0;
#endif
#if EQUATION == _2ELEMENT_4WIRE_DELTA || EQUATION == _2ELEMENT_4WIRE_WYE || EQUATION == _3ELEMENT_4WIRE_WYE
Irms_C = sqrt_rms (i2sqsum);
#else
Irms_C = 0;
#endif
#if EQUATION == _2ELEMENT_4WIRE_DELTA || EQUATION == _3ELEMENT_4WIRE_WYE
Vrms_C = sqrt_rms (v2sqsum);
#else
Vrms_C = 0;
#endif
dummy = 0;
}
static int32_t sqrt_rms (int32_t x)
{
if (x < 0)
return (0);
else
return (lroundf(65536.0 * sqrt (x)));
}
static uint32_t Irms (int32_t xdata *w) // Sqrt (sumsq) * Imax * scale.
{
float f;
// A production meter, with an unchangeable accumulation interval,
// could roll the constants, Imax and sqrt() into a single constant.
f = ((float)(*w))/65536.0; // convert LSB to sqrt(i0sqsum)
// samples is from ce.c, the number of samples per accumulation interval
f *= IRMSSCALE * sqrt ( (32768. / 13.) / (float)(samples) );
f *= (float)Imax;
return lroundf(f);
}
static void display_irms (int32_t xdata *pf)
{
LCD_Number (Irms (pf), 6, 3); // Display upto six digits.
LCD_3DP (); // Three (3) Decimal Points.
LCD_Amps ();
}
// display Irms
void rms_i_lcd (uint8_t select_phase)
{
int32_t xdata *pf;
switch (select_phase)
{
default: // unused phase
pf = &dummy;
break;
case 1:
pf = &Irms_A;
break;
case 2:
pf = &Irms_B;
break;
#if EQUATION == _2ELEMENT_4WIRE_DELTA || EQUATION == _2ELEMENT_4WIRE_WYE || EQUATION == _3ELEMENT_4WIRE_WYE
case 3:
pf = &Irms_C;
break;
#endif
}
display_irms (pf);
}
static uint32_t Vrms (int32_t xdata *w) // sqrt (sumsq) * Vmax * scale.
{
float f;
// A production meter, with an unchangeable accumulation interval,
// could roll the constants, Vmax and sqrt() into a single constant.
f = ((float)(*w))/65536.0; // convert LSB to sqrt(v0sqsum)
// samples is from ce.c, the number of samples per accumulation interval
f *= VRMSSCALE * sqrt ( (32768. / 13.) / (float)(samples) );
f *= (float)Vmax;
return lroundf(f);
}
static void display_vrms (int32_t xdata *pf)
{
LCD_Number (Vrms (pf), 6, 3); // Display upto six digits.
LCD_3DP (); // Three (3) Decimal Points.
LCD_Volts ();
}
// display Vrms
void rms_v_lcd (uint8_t select_phase)
{
int32_t xdata * pv;
switch (select_phase)
{
case 1:
pv = &Vrms_A;
break;
// The 6521 is an exception, because it implements these
// by running a wire to VB
#if EQUATION == _2ELEMENT_3WIRE_DELTA || EQUATION == _2ELEMENT_4WIRE_WYE || EQUATION == _3ELEMENT_4WIRE_WYE
case 2:
pv = &Vrms_B;
break;
#endif
#if EQUATION == _2ELEMENT_4WIRE_DELTA || EQUATION == _3ELEMENT_4WIRE_WYE
case 3:
pv = &Vrms_C; // arrange to display zero for defaults
break;
#endif
default: // unused phase
pv = &dummy;
break;
}
display_vrms (pv);
}
/***************************************************************************
* History:
* $Log: rms.c,v $
* Revision 1.26 2006/10/13 00:51:11 tvander
* Removed compile options for 6530, 6515;
* renamed 6511 and 6513 to trace11 and trace13;
* Binary verified unchanged from previous version.
*
* Revision 1.25 2006/09/29 08:58:25 tvander
* Fixed display routine.
*
* Revision 1.24 2006/09/12 02:45:11 gmikef
* *** empty log message ***
*
* Revision 1.23 2006/09/09 01:14:51 gmikef
* *** empty log message ***
*
* Revision 1.22 2006/09/08 07:37:22 Michael T. Fischer
* *** empty log message ***
*
* Revision 1.21 2006/06/14 02:46:38 tvander
* Faster LCD display.
*
* Revision 1.20 2006/06/09 22:41:29 tvander
* Now makes the voltage from element B available in the 6520
*
* Revision 1.19 2006/05/25 03:31:46 tvander
* Renamed variables so nonvolatile variables can be switched to other definitions
* of watt-hours (e.g. from absolute value to volt-amps or imports)
* (meter.c, meter.h, pulse_src.c)
* FIxed power factors so they zero correctly.
* Fixed RMS to work with different accumulation interval.
*
* Revision 1.18 2006/05/18 23:18:53 tvander
* 16K and 32K
* First cut at new requirements.
* 32K 6521 is grossly tested.
* All others have a clean compile with C51 8.02
*
* Revision 1.17 2006/04/12 00:27:50 tvander
* Debugged compilation with equations 3 and 4, on 6513
*
* Revision 1.16 2006/03/03 11:30:55 Michael T. Fischer
* Prep for 6530 LCD, etc.
*
* Revision 1.15 2006/02/10 01:56:03 tvander
* Was truncating fractional part of rms values.
*
* Revision 1.14 2006/01/27 01:12:21 gmikef
* Handle "negative" squares.
*
* Revision 1.13 2006/01/20 21:28:19 gmikef
* Moved "CE_Constants" to "ce.c" to get around linker bug.
*
* Revision 1.11 2006/01/10 04:07:51 gmikef
* Added PDATA support for CE Outputs.
*
* Revision 1.10 2006/01/04 04:47:54 gmikef
* Switched RMS and VA calculations to use floating point. (and Calibration).
*
* Revision 1.10 2005/12/31 00:13:36 gmikef
* Switched to floating point arithmetic. Decided it is high even precision.
* It is faster and no more code space.
*
* Revision 1.8 2005/09/22 23:45:20 tvander
* Clean build all models and unit tests, updated copyright to be fore Teridian
*
* Revision 1.7 2005/09/13 19:26:56 tvander
* Release 6521 CLI version for early customers.
* RMS works.
* Accumulation interval to 1 second.
* Wrate slowed to 3.2 Kh/pulse for new accumulation interval.
* Pulse outputs inverted, so they start dark.
* LCD density increased from 1/3 bias to 1/2 bias, for demo PCB.
* VAh code is included, but untested.
*
* Revision 1.6 2005/08/30 18:20:38 gmikef
* *** empty log message ***
*
* Revision 1.5 2005/05/13 00:34:46 tvander
* 6511/32k works
* Integrated and debugged self-calibration.
* The build has one unused segment, and no other errors or warnings.
* default LCD and pulse displays appear OK.
* EEPROM, software timers and hardware timers are all integrated.
*
* Revision 1.4 2005/05/04 00:57:40 gmikef
* *** empty log message ***
*
* Revision 1.7 2005/05/03 02:18:53 gmikef
* *** empty log message ***
*
* Revision 1.6 2005/05/02 18:03:09 gmikef
* *** empty log message ***
*
* Revision 1.3 2005/04/30 02:15:27 gmikef
* *** empty log message ***
*
* Revision 1.5 2005/04/27 21:38:10 gmikef
* *** empty log message ***
*
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
* this program is fully protected by the United States copyright *
* laws and is the property of Teridian Semiconductor Corporation. *
***************************************************************************/
#endif // RMS_VALUES.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -