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

📄 emeter.c

📁 MSP430 examples or customized
💻 C
📖 第 1 页 / 共 2 页
字号:


/**
  *  Nominal Mains Frequency:
  *    e.g.  50Hz.
  */
  set_parameter(mSET_NOMFREQ, defSET_NOMFREQ);

/**
  * Phase Error Correction:
  * Sets phase error for current 1/2 at nominal mains frequency for
  * current transformer according to its specification
  * The phase error of the shunt is zero.
  */
  set_parameter(mSET_PHASECORR1, (int)s_parameters.pSET_PHASECORR1);
  set_parameter(mSET_PHASECORR2, (int)s_parameters.pSET_PHASECORR2);

/** Adjustment parameters for the two currents:
  * Current Transformer:
  *
  * There are two possibilties to adjust the two current
  * values:
  * -# Only one current value is scaled with a factor > 1
  *    to fit the others current's value. The factor
  *    for the later is set to 1.\n
  *    In this example current I1 would be scaled by 0.32/0.30 = 1.06667.
  *    (The RMS values at the maximum current are used to calculate the
  *     factor.)
  *    The current transformer's value is scaled to fit with
  *    shunt's value, because the shunt's values are bigger,
  *    so the current transformer's values are multiplied with
  *    a factor > 1 - otherwise the shunt's values would be
  *    multiplied with a factor < 1 and this would result
  *    in degraded accuracy.
  * -# Both currents are scaled with a factor > 1 to use the maximum FSR
  *    (Full Scale Range) at the maximum current Imax.\n
  *    In this example current I1 would be scaled by 0.44/0.30 = 1.46667
  *    and current I2 would be scaled by 0.44/0.32 = 1.25.
  *    (The RMS values at the maximum current are used to calculate the
  *     factor. VFSR(Peak) = 0.625 (see datasheet) => VFSR(RMS) = 0.44)
  */
  set_parameter(mSET_ADAPTI1, s_parameters.pSET_ADAPTI1); // = 1 * POW_2_14 = 16384
  set_parameter(mSET_ADAPTI2, s_parameters.pSET_ADAPTI2); // = 1 * POW_2_14 = 16384

/** Adjustment parameters Gain settings: */
  set_parameter(mSET_GAINCORR1, s_parameters.pSET_GAINCORR1);
  set_parameter(mSET_GAINCORR2, s_parameters.pSET_GAINCORR2);

/** Adjustment parameters Offset settings: */
  set_parameter(mSET_V1OFFSET, s_parameters.pSET_V1OFFSET);
  set_parameter(mSET_I1OFFSET, s_parameters.pSET_I1OFFSET);
  set_parameter(mSET_I2OFFSET, s_parameters.pSET_I2OFFSET);
  set_parameter(mSET_POFFSET1_LO, s_parameters.pSET_POFFSET1.w[0]);
  set_parameter(mSET_POFFSET1_HI, s_parameters.pSET_POFFSET1.w[1]);
  set_parameter(mSET_POFFSET2_LO, s_parameters.pSET_POFFSET2.w[0]);
  set_parameter(mSET_POFFSET2_HI, s_parameters.pSET_POFFSET2.w[1]);

/** Adjustment parameters start up currents: */
  set_parameter(mSET_STARTCURR_INT, s_parameters.pSET_STARTCURR_INT);
  set_parameter(mSET_STARTCURR_FRAC, s_parameters.pSET_STARTCURR_FRAC);

/** Adjustment parameters for DC Removal Periods: */
  set_parameter(mSET_DCREMPER, defSET_DCREMPER);

} // End of init_esp_parameter()


//====================================================================
/**
  * Starts energy measurement.
  *
  */
void start_measurement(void)
{
  // Set event message request flags:

  set_parameter(mSET_EVENT, defSET_EVENT );

  total_energy = 0;

  MBCTL= IN0IE;

  // Start measurement (set Embedded Signal Processing into "Measurement" mode)
  MBOUT1= modeMEASURE; //ESP_MEASURE;
  MBOUT0= mSET_MODE;
  OP_Mode = measure;
  _EINT();
} // End of start_measurement()

//====================================================================
//
//  * Starts calibration.
//  *
//
void start_calibration(void)
{
  volatile unsigned int timeout;
  //  /\  Prevent variable from being "optimized".

//
//  * ensure 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)) ;
  }
  MBCTL = 0;

  total_energy= 0;

  // Set event message request flags:
  set_parameter(mSET_EVENT,
                CALRDYME);  // Interrupt on "Calibration values ready"

  set_parameter(mSET_CALCYCLCNT, CalCyclCnt); // = set requested cycles for measurement


  // Start measurement (set Embedded Signal Processing into "Calibration" mode)
  set_parameter(mSET_MODE, modeCALIBRATION);
  OP_Mode = calibration;
  MBCTL = IN0IE;
  _EINT();

} // End of start_measurement()


//====================================================================
void set_esp_active(void)
{
      // Restart measurement (set Embedded Signal Processing into "Measurement" mode)
      SD16CTL |= SD16REFON;         // Switch Reference on
      ESPCTL &= ~(0x08 + ESPSUSP);  // Set ESP into Active Mode
      MBCTL= IN0IE;                 // Enable Mailbox Interrupts


      // Startmeasurement (set Embedded Signal Processing into "Measurement" mode)
      //  ensure that it is not in measurement or calibration mode,
      if ((RET0 & 0x8000) == 0)
      {
        // Set Embedded Signal Processing into "Idle" mode
        MBOUT1= modeMEASURE; // modeMEASURE;
        MBOUT0= mSET_MODE;
      }
      OP_Mode = measure;
#ifdef TIMERA_PULSE_OUTPUT
      Init_TimerA();        // Start TimerA
#endif

      SVSCTL = 0x70;  // set SVS to 2.65 V to detect voltage drops below save operating area
}
//====================================================================
void set_esp_idle(void)
{
      // Stop measurement (set Embedded Signal Processing into "Idle" mode)
      // Set Embedded Signal Processing into "Idle" mode
      MBOUT1= modeIDLE; // ESP_IDLE;
      MBOUT0= mSET_MODE;
      while ((RET0 & 0x8000) != 0); // Wait for Idle mode

      // Shut donw ESP (set Embedded Signal Processing into "Suspend" mode)
      // ensure that it is not in measurement or calibration mode,
      if ((RET0 & 0x8000) == 0)
      {
          ESPCTL |= 0x08 + ESPSUSP;   // Set ESP into Suspend Mode
                                      // incl.  Bug Fix for Suspend Mode
      }

      // wait 10 clock till proper access to the SD16 is possilbe (9 clock are required)
      _NOP();_NOP();_NOP();_NOP();_NOP();
      _NOP();_NOP();_NOP();_NOP();_NOP();

      MBCTL &= ~(IN0IFG + IN0IE);    // Clear any Pending MB interrupt and disable
                                     // ESP interrupt
      SD16CTL &= ~SD16REFON; // Switch Reference off
      OP_Mode = idle;
#ifdef withDisplay
      DisplayIDLE();
      //LCD_OFF;        // Switch LCD off
#endif // withDisplay
      P1OUT |= 0x03;   // set P1.0 + P1.1 -> LED off

#ifdef TIMERA_PULSE_OUTPUT
      TACTL = TACLR | MC_0 | TASSEL_1; // Stop TimerA
      TACCTL0 &= ~CCIFG;               // Clear Pending ISR for CCR0
#endif

      SVSCTL = 0x00;  // switch SVS off

}   // End of idle_esp()


//====================================================================
/**
  * Interrupt service routine for messages sent by ESP430CE1.
  *
  */
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ < 200
interrupt[ESP430_VECTOR] void esp_isr(void)
#else
#pragma vector=ESP430_VECTOR
__interrupt void esp_isr( void )
#endif
#endif

#ifdef __CROSSWORKS_MSP430
void esp_isr(void)   __interrupt[ESP430_VECTOR]
#endif

#ifdef __TI_COMPILER_VERSION__
__interrupt void esp_isr(void);
ESP430_ISR(esp_isr)
__interrupt void esp_isr(void)
#endif
{
  unsigned int msg_data = MBIN1;
  unsigned int msg      = MBIN0;


//  P1OUT |= 0x01;    // set P1.0  //////////

  if (msg == mEVENT)
  {
    //
    //  * Get the Calibration data
    //
    if ((msg_data & CALRDYFG) == CALRDYFG) // Calibration data available
    {
        if ( OP_Mode == calibration)
        {
          energy.w[0] = ACTENERGY1_LO;
          energy.w[1] = ACTENERGY1_HI;
#ifdef withUARTComm
          TX_Mode = tx_cal;
#endif // withUARTComm
          OP_Mode = done;
          // Set Embedded Signal Processing into "Measure" mode
          msg_data = 0; // prevent that the other functions in the ISR are executed

          set_parameter(mSET_EVENT, defSET_EVENT );
          // Start measurement (set Embedded Signal Processing into "Measurement" mode)
          MBOUT1= modeMEASURE; //ESP_MEASURE;
          MBOUT0= mSET_MODE;
        }
    } // End of if ((msg_data & CALRDY)

    msg_data = msg_data & defSET_EVENT ; //mask with event request mask

    //
    //  * Get the WFS
    //
    if ((msg_data & WFSRDYFG)) // New Waveform Samples available
    {
        wfs1 = WAVEFSV1;
        wfs2 = WAVEFSI1;
        wfs3 = WAVEFSI2;
/*
        if (TX_Mode == 1)
        {
          while ((U0IFG&UTXIFG0)==0);            // wait till TX buf empty
          TXBUF0=(wfs1>>8) & 0xFF;                        // transmit ch

          while ((U0IFG&UTXIFG0)==0);            // wait till TX buf empty
          TXBUF0=(wfs1) & 0xFF;                        // transmit ch

          while ((U0IFG&UTXIFG0)==0);            // wait till TX buf empty
          TXBUF0=(wfs2>>8) & 0xFF;                        // transmit ch

          while ((U0IFG&UTXIFG0)==0);            // wait till TX buf empty
          TXBUF0=(wfs2) & 0xFF;                        // transmit ch

          while ((U0IFG&UTXIFG0)==0);            // wait till TX buf empty
          TXBUF0=0xa5;                        // transmit ch
        }
*/
    }

//
//  * Get Energy and create Pulses
//
#ifdef TIMERA_PULSE_OUTPUT
    if ((msg_data & ILREACHEDFG)) //
    {
        P_reading ++;
    }
#else
    if (uiIntLevelRepeatCount == (defSET_INTRPTLEVL_REPEAT/2))
    {
#ifndef INVERT_PULSE
        P1OUT &= ~BIT1;          // Clear Bit which may has been set in last ISR call
#else
        P1OUT |= BIT1;
#endif
    }
    if ((msg_data & ILREACHEDFG)) //
    {
        uiIntLevelRepeatCount --;
        if (uiIntLevelRepeatCount == 0)
        {
            P1OUT ^= BIT1;       // Toggle P1.1
            uiIntLevelRepeatCount = defSET_INTRPTLEVL_REPEAT;
        }
    }
#endif  // TIMERA_PULSE_OUTPUT

    if (msg_data & ZXTRFG)
    {
        ZXLDFGedge = 1;
    }
    if ((msg_data & ZXLDFG) && ZXLDFGedge)
    {
        ZXLDFGedge = 0;
    }

/*
//  DO NOT USE THIS FLAG AS IT IS NOT WORKING OK IN THIS VERSION !!!
    if (msg_data & NEGENFG) // Negativ Energy measured ?
    {
//      P1OUT |= 0x01;    // set P1.0
    }
    else
    {
//      P1OUT &= ~0x01;   // clear P1.0
    }
*/

/**
  * Accumulates the active energy depending on the tampering flag so
  * that always the "worst case" energy is calculated.
  */
    if ((msg_data & ENRDYFG))
    {
      static unsigned char temp_count = defTemp_repeat;


       if ((ACTENERGY1_HI & 0x8000) > 0 ) {// Negativ Energy measured ?
        negenfg = 1;        // set global neg. Energy Flag
//            P1OUT |= 0x01;    // set P1.0
       }else {
//            P1OUT &= ~0x01;   // clear P1.0
         negenfg = 0;        // clear global neg. Energy Flag
       }

#if I2SENSOR != NONE               // Tampering (I1 << I2 or I2 >> I1)?
      if (!(msg_data & I2GTI1FG) ) {// I1 > I2?
        energy.w[0] = ACTENERGY1_LO;
        energy.w[1] = ACTENERGY1_HI;
      } else {// I1 < I2!
        energy.w[0] = ACTENERGY2_LO;
        energy.w[1] = ACTENERGY2_HI;
      }
#else
        energy.w[0] = ACTENERGY1_LO;
        energy.w[1] = ACTENERGY1_HI;
#endif

      if (msg_data & NEGENFG) // Negativ Energy measured ?
         total_energy -= (float)energy.l;
      else
         total_energy += (float)energy.l;

      //total_energy += (float)energy.l;

      //
      //  * The seconds are counted based on the ESP430CE1 energy ready interrupts.
      //
      temp_count--;
      if ((temp_count == 0) && (defTemp_repeat != 0)) {
        //
        //  * Every minute a temperature measurement is requested.
        //
        temp_count = defTemp_repeat;
        sys_status |= RequestTemp;       // set mark that a Temp. Measurement is requested
      }

      sys_status |= NewValues;           // set mark that new samples are available
      if (OP_Mode != idle) LPM3_EXIT;    // back to active mode after ISR

    } // End of if ((msg_data & ENRDY)
  } // End of if (MBIN0 == mEVENT)


  if (msg == mTEMPRDY)
  {
    //
    //  * The temperature is saved as soon as it is delivered by the ESP430.
    //
    temperature= msg_data;
    sys_status |= NewTemp;
  }
}

//====================================================================
/**
  * Interrupt service routine for SD16 (Dummy).
  *
  */
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ < 200
interrupt[SD16_VECTOR] void SD16_isr(void)
#else
#pragma vector=SD16_VECTOR
__interrupt void SD16_isr( void )
#endif
#endif

#ifdef __CROSSWORKS_MSP430
void SD16_isr(void)   __interrupt[SD16_VECTOR]
#endif

#ifdef __TI_COMPILER_VERSION__
__interrupt void SD16_isr(void);
SD16_ISR(SD16_isr)
__interrupt void SD16_isr(void)
#endif
{
}

⌨️ 快捷键说明

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