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

📄 rms.c

📁 TDK 6521 SOC 芯片 DEMO程序
💻 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 + -