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

📄 emeter.c

📁 430系列开发之MSP430FE42x开发代码实例
💻 C
📖 第 1 页 / 共 2 页
字号:
  *    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, defSET_ADAPTI1); // = 1 * POW_2_14 = 16384
  set_parameter(mSET_ADAPTI2, defSET_ADAPTI2); // = 1 * POW_2_14 = 16384

/** \par 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);

/** \par 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);

/** \par 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;
} // End of start_measurement()

//====================================================================
//
//  * Starts calibration.
//  *
//
void start_calibration(void)
{
  volatile unsigned int timeout;
  //  /\  Prevend 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)) ;
  }

  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;
} // End of start_measurement()


//====================================================================
/**
  * 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__
void esp_isr(void)   __interrupt[ESP430_VECTOR] 
#endif
{
  unsigned int msg_data = MBIN1;
  unsigned int msg      = MBIN0;

#ifdef ExtIntLevel
unsigned int i = def_togglerepeat;
#endif

  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 "Idle" mode
//          MBOUT1= modeIDLE; // ESP_IDLE;
          MBOUT1= modeMEASURE; //ESP_MEASURE;
          MBOUT0= mSET_MODE;
          
          msg_data = 0; // prevent that the other functions in the ISR are executed
        }
    } // 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
// WFS could always be copied
    {
        wfs1 = WAVEFSV1;
        wfs2 = WAVEFSI1;
        wfs3 = WAVEFSI2;   
    }

//
//  * Get Energy and create Pulses
//
#ifndef ExtIntLevel
    if ((msg_data & ILREACHEDFG)) // 
    {
        static unsigned int i = defSET_INTRPTLEVL_REPEAT;
        i--;
        if (i == 0)
        {
          P1OUT ^= 0x02;    // toggle P1.1
          i = defSET_INTRPTLEVL_REPEAT;
        }
    }
#else
    if (msg_data & ZXTRFG)
    {
        ZXLDFGedge = 1;
        if (sumenergy >= s_parameters.pSET_TOGGLELEVEL)
        {
            sumenergy -= s_parameters.pSET_TOGGLELEVEL;
            i--;
            if (i == 0)
            {
              P1OUT ^= 0x02;    // toggle P1.1
              i = s_parameters.pSET_TOGGLELEVEL;
            }
        }
    }
    if ((msg_data & ZXLDFG) && ZXLDFGedge)
    {
        
        ZXLDFGedge = 0;
        
        tempenergy.w[0] = ACTENSPER1_LO;
        tempenergy.w[1] = ACTENSPER1_HI;
        sumenergy += tempenergy.l;
        if (tempenergy.l > maxenergy) {maxenergy = tempenergy.l;};
        if (sumenergy >= s_parameters.pSET_TOGGLELEVEL)
        {
            sumenergy -= s_parameters.pSET_TOGGLELEVEL;
            i--;
            if (i == 0)
            {
              P1OUT ^= 0x02;    // toggle P1.1
              i = def_togglerepeat;
            }
        }
    }
#endif

/**
  * Accumulates the active energy depending on the tampering flag so
  * that always the "worst case" energy is calculated.
  */
    if ((msg_data & ENRDYFG)) // Tampering (I1 << I2 or I2 >> I1)?
//    if ((msg_data & ILREACHED) == ILREACHED) // Tampering (I1 << I2 or I2 >> I1)?
    {
      unsigned int i;
      unsigned int * a = (unsigned int *) RET0_;
      unsigned int * b = (unsigned int *) &savedRET[0];
      static unsigned char temp_count = Temp_repeat;
      
      
      for (i=0; i != ((RET31_ - RET0_)/2); i++)
      {
         *b++ = *a++;
      }
      
      if (!(msg_data & I2GTI1FG) ) // I1 > I2?
      {
        energy.w[0] = RET8;
        energy.w[1] = RET9;
      } else // I1 < I2!
      {
        energy.w[0] = ACTENERGY1_LO;
        energy.w[1] = ACTENERGY1_HI;
      }
      
      total_energy += (float)energy.l;

      //
      //  * The seconds are counted based on the ESP430CE1 energy ready interrupts.
      //
      temp_count--;
      if (temp_count == 0)
      {
        //
        //  * Every minute a temperature measurement is requested.
        //
        temp_count = Temp_repeat;
        MBOUT0= mTEMP;
      }  

      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;
  } 
  
  // Test if S1 was pressed
  if (P2IFG & 0x04)  
  {
      P2IFG &= ~0x04;  //clear flag
#ifdef withDisplay
      DisplayNextData(); //next display mode
#endif // withDisplay
  }

  // Test if S2 was pressed
  if (P2IFG & 0x08)  
  {
      P2IFG &= ~0x08;  //clear flag
      
      // 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 |= ESPSUSP;   // Set ESP into Suspend Mode
//          ESPCTL = 0;            // Set ESP into Off 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();
      SD16CTL &= ~SD16REFON; // Switch Reference off
      OP_Mode = idle;
      DisplayIDLE();
      //LCD_OFF;        // Switch LCD off
      P2IE  |= 0x08;  //enable interrupt
      _BIS_SR_IRQ(LPM3_bits);   // not back to active mode after ISR
      
  }
  
  P1OUT &= ~0x01;    // clear P1.0

}

⌨️ 快捷键说明

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