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

📄 calibration.c

📁 TDK 6521 SOC 芯片 DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            adjust_gain (
                (int32_t)**punit++, 
                (int32_t)**pxcal++, 
                (int32_t)*pcm++)
            );    
    } while (--cnt);
}

// Adjust a CE gain parameter.
// 'unitmax':  Either VMAX or IMAX; It's odd that the same adjustment
//             routine works for both current and voltage, but it does.
// 'actual':   Known quantity.  LSB = units * 0.1 (same as VMAX and IMAX).
// 'measured': Same units as 'v0sqsum' or 'i0sqsum'.
static int32_t adjust_gain (int32_t unitmax, int32_t actual, int32_t measured)
{
    int32_t gain;

    // If noisy, near zero, measured may be negative.
    // Returns 4 * sqrt(), rounded to nearest bit; 
    measured = (int32_t)(4. * sqrt ((float)labsx (measured)) + 0.5);

    // Convert actual to RMS units.
    #if M6520 || TRACE11
    // Note, 162951 / 2 ~= 4 /(SQRT ((6.6952e-13 * 3600))), within 0.00002%.
    // The resolution of the gain is +/-(LSB/2) = 1 / (2 * UNITY) ~= 0.003%. 
    // Rounds to the nearest bit.  The 'unitmax' term is the rounding augend.
    // This calculation is engineered so even the demo PCB's
    // VMAX (600V) and IMAX (208A) will not cause overflow.
    actual = (( actual * 162951L ) + unitmax ) / (unitmax * 2L);

    #elif TRACE13
    // Note, 68745 ~= 4 /(SQRT ((9.4045e-13 * 3600))), within 0.00005%.
    // The resolution of the gain is +/-(LSB/2) = 1 / (2 * UNITY) ~= 0.003%. 
    // Rounds to the nearest bit.  The 'unitmax / 2' term is the rounding augend.
    // This calculation is engineered so even the demo PCB's..
    // VMAX (600V) and IMAX (208A) will not cause overflow.

    actual = (( actual * 68745L ) + ( unitmax / 2L )) / unitmax;
    #else
    #error unknown configuration
    #endif

    // 16384 = unity; calculation rounds to nearest bit
    // "measured/2" is the rounding addend
    // The resolution of the gain is +/-(LSB/2) = 1/(16384*2) ~= 0.003% 
    gain = (( actual * 16384L) + ( measured / 2L )) / measured;

    // Keep resolution within possible range, return the revised gain.
    return (max (min (gain, 32767L), -32767L));
}

#endif // AUTOCAL

#if NV_SELECT == NV_FLASH
#define MANY 0xFF
void cal_save (void)                    // Save the calibration.
{
    if (CalibrationCount != MANY)
        CalibrationCount++;		

    // Compute & store checksums.	
    LRC_Calc_NVR ((uint8x_t *) &Totals.Parms, sizeof (struct Parameters_t), TRUE);	
    chksum_ce ((int32x_t *) CE_PARM_BASE, CE_PARM_SIZE, TRUE);

    CE_DISABLE();
    memcpy_rx  ((uint8r_t *) r_Parms, (uint8x_t*) &Totals.Parms, sizeof (struct Parameters_t) );
    memcpy_rce ((uint8r_t *) CeData, (uint8x_t *) CE_PARM_BASE, CE_PARM_SIZE);
    CE_ENABLE();
}
#elif NV_SELECT == NV_EEPROM
#define MANY 0xFF
void cal_save (void)                    // Save the calibration.
{
    if (CalibrationCount != MANY)
        CalibrationCount++;		

    // Compute & store checksums.	
    LRC_Calc_NVR ((uint8x_t *) &Totals.Parms, sizeof (struct Parameters_t), TRUE);	
    CE_DISABLE();
    lrc_ce ((int32x_t *) CE_PARM_BASE, CE_PARM_SIZE, TRUE );

    #if EEPROM
    eeprom_enable();                    // Enable non-volatile store.
    memcpy_prce (
            EEPROM_CALIBRATION, 
            (int32x_t *) CE_PARM_BASE, 
            CE_PARM_SIZE );
    memcpy_prx (
            EEPROM_CALIBRATION + (CE_PARM_SIZE * 4), 
            (uint8x_t *) &Totals.Parms, 
            sizeof (struct Parameters_t) );
    eeprom_disable();                   // Disable non-volatile store.
    #endif
    CE_ENABLE();
} 
#else
#error unknown NV type
#endif                                  // Validate the restored calibration.

#if NV_SELECT == NV_FLASH
bool cal_restore (void)                 // Restore the calibration.
{
    bool ok = 1;

    // get the CE's data
    memcpy_cer (
            (int32x_t *) CE_PARM_BASE, 
            &CeData[0], 
            CE_PARM_SIZE );
    // get the MPU's data
    memcpy_xr  ( 
            (uint8x_t *) &Totals.Parms, 
            (uint8r_t *) r_Parms, 
            sizeof (struct Parameters_t) );

    #if CONSTANTS_DBG
    // Make CE defaults visible to the AMD-51 ICE.
    // Note, if this code is enabled, overlap errors occur in the link,
    // but they do not cause defective operation.
    get_ce_constants ();
    #endif

    // test the data to see if it's valid
    ok &= LRC_Calc_NVR (
            (uint8x_t *) &Totals.Parms, 
            sizeof (struct Parameters_t), 
            FALSE);
    ok &= lrc_ce (
            (int32x_t *) CE_PARM_BASE, 
            CE_PARM_SIZE, 
            FALSE);

    if (!ok)
        Status |= CAL_BAD;  // dating, etc. is in the main loop
    else
        Status &= ~CAL_BAD;

    CE_ENABLE();

    return ok;
}
#elif NV_SELECT == NV_EEPROM && EEPROM
bool cal_restore (void)                 // Restore the calibration.
{
    bool ok = 1;
    enum EEPROM_RC data *state;

    #if EEPROM
    eeprom_enable();                    // Enable non-volatile store.
    CE_DISABLE();
    // get the CE's data
    ok &= memcpy_cepr (
            (int32x_t *) CE_PARM_BASE, 
            EEPROM_CALIBRATION, 
            CE_PARM_SIZE);
    // get the MPU's data
    state = memcpy_xpr (
	    (uint8x_t *) &Totals.Parms, 
	    EEPROM_CALIBRATION + (CE_PARM_SIZE * 4), 
	    sizeof (struct Parameters_t)
	    );
    ok &= eeprom_ok (state);
    eeprom_disable();                   // Disable non-volatile store.
    #endif

    #if CONSTANTS_DBG
    // Make CE defaults visible to the AMD-51 ICE.
    // Note, if this code is enabled, overlap errors occur in the link,
    // but they do not cause defective operation.
    get_ce_constants ();
    #endif

    // test the data to see if it's valid
    ok &= LRC_Calc_NVR (
            (uint8x_t *) &Totals.Parms, 
            sizeof (struct Parameters_t), 
            FALSE);
    ok &= lrc_ce (
            (int32x_t *) CE_PARM_BASE, 
            CE_PARM_SIZE, 
            FALSE);

    memset_ce(&apulsew,0);  // do not restore the pulse rates
    memset_ce(&apulser,0);  // they cause spurious pulses at start-up

    if (!ok)
        Status |= CAL_BAD;  // dating, etc. is in the main loop
    else
        Status &= ~CAL_BAD;

    CE_ENABLE();

    return ok;
}

// copy data from EEPROM to the CE's data area
bool memcpy_cepr (int32x_t * pDst, uint16_t pSrc, uint16_t len)
{
    int32_t xdata nv_data;
    enum EEPROM_RC data *state;
    bool ok = 1;

    for(; len != 0; --len)
    {
        state = memcpy_xpr ((uint8x_t *)&nv_data, pSrc, sizeof (int32_t));
        ok &= eeprom_ok (state);
        memset_ce (pDst++, nv_data);
        pSrc += sizeof (int32_t);
    }
    return ok;
}

// copy data from the CE's data area to EEPROM
void memcpy_prce (uint16_t pDst, int32x_t * pSrc, uint16_t len)
{
    int32_t xdata nv_data;

    for(; len != 0; --len)
    {
        nv_data = memget_ce (pSrc++);
        memcpy_prx (pDst, (uint8x_t *)&nv_data, sizeof (int32_t));
        pDst += sizeof (int32_t);
    }
}
#else
#error unknown NV type
#endif

/***************************************************************************
 * History:
 * $Log: calibration.c,v $
 * Revision 1.36  2006/10/13 00:51:09  tvander
 * Removed compile options for 6530, 6515;
 * renamed 6511 and 6513 to trace11 and trace13;
 * Binary verified unchanged from previous version.
 *
 * Revision 1.35  2006/09/09 01:12:47  gmikef
 * *** empty log message ***
 *
 * Revision 1.34  2006/08/30 02:09:42  gmikef
 * *** empty log message ***
 *
 * Revision 1.33  2006/08/18 23:23:27  tvander
 * Added calibration.c back to build in order to cope with differential meter
 * equations, which it can calibrate, while caphased.c cannot.
 *
 * Revision 1.31  2006/04/12 00:26:26  tvander
 * Math is right for current and voltage gains.  Phase number is right for my test signal, i.e. zero phase.  Needs testing on a real meter.
 *
 * Revision 1.30  2006/03/06 03:36:33  Michael T. Fischer
 * More 6530 prep.
 *
 * Revision 1.29  2006/03/03 11:29:16  Michael T. Fischer
 * Prep for 6530 LCD, etc.
 *
 * Revision 1.28  2006/02/08 22:39:11  gmikef
 * *** empty log message ***
 *
 * Revision 1.27  2006/02/08 03:43:24  tvander
 * Made "import" the default power measurement mode, rather than net-metering
 *
 * Revision 1.26  2006/01/26 01:07:15  tvander
 * Debugged calibration.  It actually calibrates correctly.
 *
 * Revision 1.25  2006/01/25 01:04:23  tvander
 * Calibration compiles but does not calibrate
 *
 * Revision 1.24  2006/01/11 00:50:57  gmikef
 * *** empty log message ***
 *
 * Revision 1.22  2006/01/10 04:04:06  gmikef
 * Added PDATA support for CE Outputs.
 *
 * Revision 1.21  2006/01/04 04:47:51  gmikef
 * Switched RMS and VA calculations to use floating point. (and Calibration).
 *
 * Revision 1.19  2005/12/09 20:01:48  tvander
 * Clean build
 *
 * Revision 1.18  2005/12/09 19:42:09  tvander
 * Calibration save and restore now work in flash, and save and restore temp_nom
 * in the 6520's temp_raw value for the CE variables.
 *
 * Revision 1.17  2005/12/07 02:30:46  tvander
 * Added SO command.
 * Fixed uninitialized variable in tempoerature compensation of calibration.
 * Added xtal_freq to 6521 options, and alternative brownout baud rate
 * to reg652x.h
 * Rolled date.
 *
 * Revision 1.16  2005/12/07 01:43:51  tvander
 * tn in temperature compensation was not being initialized.
 *
 * Revision 1.15  2005/10/31 17:38:03  tvander
 * Includes improved EEPROM code with uwire.
 * Clean build, all build trees (Thank-you, Mike!)
 *
 * Revision 1.14  2005/10/15 02:18:08  tvander
 * Improved so compensation and extended trim can be separate options.
 * Also improved the flash version to save a nominal temperature.
 *
 * Revision 1.13  2005/10/06 23:36:08  tvander
 * Fixed calibration for 6520-- the nominal temperature is shifted left by
 * 9 bits.
 *
 * Revision 1.12  2005/10/06 23:01:36  tvander
 * Fixed I-147, default temperature compensation.
 *
 * Revision 1.11  2005/09/22 23:45:13  tvander
 * Clean build all models and unit tests, updated copyright to be fore Teridian
 *
 * Revision 1.10  2005/08/30 18:14:24  gmikef
 * *** empty log message ***
 *
 * Revision 1.9  2005/08/20 01:32:47  gmikef
 * *** empty log message ***
 *
 * Revision 1.8  2005/08/19 01:04:43  gmikef
 * *** empty log message ***
 *
 * Revision 1.7  2005/08/12 21:54:55  tvander
 * Calibration compiles with the EEPROM option.
 *
 * Revision 1.6  2005/08/12 06:00:27  gmikef
 * Added MPU temperature compensation for GAIN_ADJ.
 * Added changes to support new CE 6521 code.
 *
 * Revision 1.5  2005/08/10 02:00:29  gmikef
 * *** empty log message ***
 *
 * Revision 1.4  2005/07/14 20:15:50  tvander
 * ce code concentrated in ce.c
 * ce interface concentrated in ce652x.c, .h
 * Fixed 0-length read or write using flag protocol.
 * display.c is out of the build
 * kwh_initialize now reads the LRC.
 *
 * Revision 1.3  2005/06/16 18:58:43  tvander
 * Updates the debug values
 *
 * Revision 1.2  2005/06/10 22:57:07  tvander
 * Uses macros to reset watchdog and clear IE and RTC interrupts
 * Includes 6515 improvements in register defs.
 *
 * Revision 1.1  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.3  2005/04/30 02:12:43  gmikef
 * *** empty log message ***
 *
 *
 * Revision 1.2  2005/04/27 23:40:48  gmikef
 * Some MATH rountines now use 'idata'.
 * Added MATH_FAST flag to 'options.h".
 * Changed "6521B.Uv2" to max optimization.
 *
 * 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 /* calibration.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -