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

📄 esp.c

📁 MSP430FE42X复费率电表DEMO(编译器 IAR 3.42A)
💻 C
字号:
/*****************************************************************
*                        模拟前端初始化函数                      *
*                                                                *
* 说明:配置SD16 ADC模块                                         *
*       配置两个电流通道和一个电压通道,实现防窃电电表           *
*       电流通道I1使用锰铜分流器,电流通道I2使用电流互感器CT     ×
******************************************************************/
#define SD16CONF0_FUDGE     0xC0
#define SD16CONF1_FUDGE     0x40
void Init_Analog_Front_End_ESP(void)
{
  ESPCTL &= ~ESPEN;
  // 电网电压存在,初始化模拟前端为ESP
  if((POWER_TEST_IN & POWER_TEST_BIT) == POWER_TEST_BIT)
  {
//  	  * 进行模拟前端的共性配置:
//  	  * 选择时钟原SMCLK
//  	  * 选择时钟原分频系数,不同的主频下分频系数不同,分频结果均为1.094MHz
//  	  * 选择参考原


  	//SD16CTL= 0x800
  		//| SD16SSEL_1   // 时钟原: SMCLK
    	//| SD16DIV_3   // 8分频 => ADC clock: 1.094MHz
        //| SD16REFON;  // 选用内部参考原
    SD16CTL= 0x800
  		| SD16SSEL_1   // 时钟原: SMCLK
    	| SD16DIV_3   // 8分频 => ADC clock: 1.094MHz
        | SD16REFON;  // 选用内部参考原



// -------------------------------------------------------------------

//  *	配置电流通道I1
//  * 锰铜分流器
//  * 锰铜分流器电阻 Rs = 300 微欧
//  * 最大电流40A时
//  * 锰铜分流器的电压有效值 VRs(RMS) = 0.3 * 40 = 12mV
//  * 锰铜分流器的电压峰值 VRs(peak) = 16.97mV
//  * 当前置放大器放大倍数 GAIN = 16时, 最大输入电压 VIN = 16.97 * 16 = 271mV < 500mV
//  *                      GAIN = 32时, 最大输入电压 VIN = 16.97 * 32 = 543mV > 500mV
//  * 所以选择电流通道I1的放大倍数 GAIN = 16
//  *
//  */

#if SD16I1GAIN==1
    SD16INCTL0= SD16GAIN_1; // 设置电流通道I1的增益放大倍数GAIN = 1
#elif SD16I1GAIN==2
    SD16INCTL0= SD16GAIN_2;
#elif SD16I1GAIN==4
    SD16INCTL0= SD16GAIN_4;
#elif SD16I1GAIN==8
    SD16INCTL0= SD16GAIN_8;
#elif SD16I1GAIN==16
    SD16INCTL0= SD16GAIN_16;
#elif SD16I1GAIN==32
    SD16INCTL0= SD16GAIN_32;
#else
    SD16INCTL0= SD16GAIN_1;
#endif

    SD16CCTL0 = SD16OSR_256;       // 设置电流通道I1过采样率为 256
    SD16CCTL0 = SD16OSR_256 + SD16GRP;
		//SD16CCTL0 = SD16OSR_256 + SD16DF + SD16GRP;
// -------------------------------------------------------------------

//  * 配置电流通道I2
//  * 电流互感器CT
//  * 此通道暂时短接不用
#if SD16I2GAIN==1
    SD16INCTL1= SD16GAIN_1; // 设置电流通道I2的增益放大倍数GAIN = 1
#elif SD16I2GAIN==2
    SD16INCTL1= SD16GAIN_2;
#elif SD16I2GAIN==4
    SD16INCTL1= SD16GAIN_4;
#elif SD16I2GAIN==8
    SD16INCTL1= SD16GAIN_8;
#elif SD16I2GAIN==16
    SD16INCTL1= SD16GAIN_16;
#elif SD16I2GAIN==32
    SD16INCTL1= SD16GAIN_32;
#else
    SD16INCTL1= SD16GAIN_1;
#endif

    //SD16CCTL1 = SD16OSR_256;      // 设置电流通道I2过采样率为 256
    SD16CCTL1 = SD16OSR_256 + SD16GRP;
		//SD16CCTL1 = SD16OSR_256 + SD16DF + SD16GRP;

// -----------------------------------------------------------
//
//  *	配置电压通道
//  * 电阻分压,最大输入电压 VIN=(220 + 220*0.2)  * (1/991)*1.414 = 376 mV
//  * 选择增益放大倍速 GAIN = 1
//  */

  	SD16INCTL2= SD16GAIN_1;// 设置电压通道V1的增益放大倍数GAIN = 1
		
  	//SD16CCTL2 = SD16OSR_256 + SD16GRP;     // 设置电压通道V1过采样率为 256
		SD16CCTL2 = SD16OSR_256 + SD16DF + SD16GRP;     // 设置电压通道V1过采样率为 256


  	SD16CONF0 = SD16CONF0_FUDGE;
    SD16CONF1 = SD16CONF1_FUDGE;
  }

  else
  {
    //SD16CTL = 0x800
    //      | SD16VMIDON  // 温度传感器使能
    //      | SD16SSEL_1  // 时钟原选择 SMCLK
    //      | SD16DIV_3   // 时钟原8分频,ADC clock: 1.048576MHz
    //      | SD16REFON;  // 使用内部参考

    //SD16CTL = 0x800
          //| SD16VMIDON  // 温度传感器使能
          //| SD16SSEL_1  // 时钟原选择 SMCLK
          //| SD16DIV_3   // 时钟原8分频,ADC clock: 1.048576MHz
          //| SD16REFON;  // 使用内部参考


  	  SD16INCTL0 = 0;
  	  SD16CCTL0 = 0;
  	  SD16PRE0 = 0;

  	  SD16INCTL1 = 0;
  	  SD16CCTL1 = 0;
  	  SD16PRE1 = 0;

  	  SD16INCTL2 = SD16INCH_6 | SD16GAIN_1;   /* 选择温度传感器通道 */
  	  SD16CCTL2 = SD16DF | SD16SNGL | SD16IE; /* 过采样率为 256 */
  	  SD16PRE2 = 0;
  }
} // 模拟前端初始化函数结束

/*********************************************************************
*                       设置ESP430CE1模块参数函数                    *
*                                                                    *
* 参数寄存器地址送入\a param                                         *
* 设置的内容送入\a data                                              *
*                                                                    *
*********************************************************************/
void Set_Parameter(unsigned int param, unsigned int data)
{
  	unsigned int timeout= 0xffff; //定义超时溢出计数寄存器

  	MBOUT1= data;      // 写本次邮箱发送的数据
  	MBOUT0= param;     // 写本次邮箱发送的地址
  	do
  	{
    	//等待ESP430CE1的反馈信息
    	while (((MBCTL & IN0IFG) == 0) && (timeout-- > 0)) ;
    	if (timeout == 0)
    	{
    		//display(ERROR);
    		return;
    	}
    	//判断反馈消息是否与发送的内容相符
  	} while ((MBIN0 != mPARAMSET) || (MBIN1 != param));
}  // End of Set_Parameter()


/********************************************************************
*                        初始化ESP430CE1模块                        *
*                                                                   *
********************************************************************/
void Init_ESP_Parameter(void)
{
	// 定义超时溢出计数寄存器
	unsigned int timeout,i;
  	// 确信嵌入式处理器在使能状态

  	ESPCTL |= ESPEN;
  	MBCTL = 0;

  	// 初始化前需要保证ESP不在测量状态或者校准状态
  	if ((ESP430_STAT0 & ACTIVEFG) != 0)
  	{
    	// 如果不是在空闲状态,则使它进入空想状态
    	MBOUT1= modeIDLE;
    	MBOUT0= mSET_MODE;
    	timeout= 0xffff;
    	// 等待进入空闲状态,以便后续的设置
    	while (((ESP430_STAT0 & ACTIVEFG) != 0) && (timeout-- > 0)) ;
  	}

  	MBOUT1 = 0;
  	MBOUT0 = modeRESET;

  	for(i=0;i<50000;i++);

  		
  	// 读ESP软件版本号
  	MBOUT0= mSWVERSION;
  	timeout= 0xffff;
  	do
  	{
    	while (((MBCTL & IN0IFG) == 0) && (timeout-- > 0)) ;
    	if (timeout == 0)
    	{
    		//display(ERROR);
    		return;
    	}
  	} while (MBIN0 != mSWRDY);
	
	/*************** 初始化参数寄存器 ******************/

  	// 配置参数寄存器Control 0
  	Set_Parameter(mSET_CTRL0,defSET_CTRL0);     //

  	

  	
  	// 设置相位校正寄存器
    Set_Parameter(mSET_PHASECORR1,SM.Cfg.EspPar.iPhaseCorr1);
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_PHASECORR2,SM.Cfg.EspPar.iPhaseCorr2);
#endif

#ifdef TAMPER_DETECTION
  	// 设置两电流通道自适应因子
    Set_Parameter(mSET_ADAPTI1, SM.Cfg.EspPar.uiAdaptI1);
    Set_Parameter(mSET_ADAPTI2, SM.Cfg.EspPar.uiAdaptI2);
#endif
  	
  	Set_Parameter(mSET_GAINCORR1, SM.Cfg.EspPar.uiGainCorr1);
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_GAINCORR2, SM.Cfg.EspPar.uiGainCorr2);
#endif
    Set_Parameter(mSET_POFFSET1_LO, *(int*)(&SM.Cfg.EspPar.lPowerOffset1));
  	Set_Parameter(mSET_POFFSET1_HI, *(((int*)(&SM.Cfg.EspPar.lPowerOffset1))+1));
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_POFFSET2_LO, *(int*)(&SM.Cfg.EspPar.lPowerOffset2));
  	Set_Parameter(mSET_POFFSET2_HI, *(((int*)(&SM.Cfg.EspPar.lPowerOffset2))+1));
#endif
		
#if	PULSE_MEASURE_MODE==2	
	  Set_Parameter(mSET_INTRPTLEVL_LO, *(int*)(&SM.Cfg.EspPar.ulIntrptLevl));
  	Set_Parameter(mSET_INTRPTLEVL_HI, *(((int*)(&SM.Cfg.EspPar.ulIntrptLevl))+1));
#endif		

    //Set_Parameter(mSET_CALCYCLCNT, CALCYCLCNT_INIT);

    Set_Parameter(mSET_STARTCURR_FRAC, *(int*)(&SM.Cfg.EspPar.ulStartCurrent));
    Set_Parameter(mSET_STARTCURR_INT, *(((int*)(&SM.Cfg.EspPar.ulStartCurrent))+1));

    // 设置电网正常频率 50Hz
  	Set_Parameter(mSET_NOMFREQ, SM.Cfg.EspPar.uiNomFreq);

    //Set_Parameter(mSET_VDROPCYCLS, VDROPCYCLS_INIT);



#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_RATIOTAMP, RATIOTAMP_INIT);	
  	Set_Parameter(mSET_ITAMP, ITAMP_INIT);
#endif  	

    Set_Parameter(mSET_VDROPLEVEL, VDROPLEVEL_INIT);

  	Set_Parameter(mSET_VPEAKLEVEL, VPEAKLEVEL_INIT);

    Set_Parameter(mSET_IPEAKLEVEL, IPEAKLEVEL_INIT);

    Set_Parameter(mSET_DCREMPER, DCREMPER_INIT);

 } // End of init_esp_parameter()


/*******************************************************************
*                         这个函数使ESP进入测量状态                *
*******************************************************************/
void Start_Measurement(void)
{
   	Set_Parameter(mSET_EVENT,
                defSET_EVENT);  // 当事件<新的能量值准备好>发生时发出中断请求

  	MBCTL= IN0IE;	//接收邮箱0中断使能

  	//_EINT();

  	// 开始测量(使ESP进入测量模式)
  	MBOUT1= modeMEASURE;
  	MBOUT0= mSET_MODE;
#ifdef PULSE_TIMEA_GEN
        TACCR0 = TAR + TIMERA_PULSE_PERIOD;
 	TACCTL0 = CCIE;
#endif
} // End of start_measurement()


void Set_IdleMode(void)
{
   unsigned int timeout= 0xffff;

  MBCTL = 0;

  if ((ESP430_STAT0 & ACTIVEFG) != 0)
  	{
    	// 如果不是在空闲状态,则使它进入空想状态
    	MBOUT1= modeIDLE;
    	MBOUT0= mSET_MODE;
    	timeout= 0xffff;
    	// 等待进入空闲状态,以便后续的设置
    	while (((ESP430_STAT0 & ACTIVEFG) != 0) && (timeout-- > 0)) ;
  	}
#ifdef PULSE_TIMEA_GEN
 	TACCTL0 = 0;
#endif
}

void Start_Calibration(void)
{
    Set_Parameter(mSET_EVENT,
                CALRDYME);  // 当事件<新的能量值准备好>发生时发出中断请求

    do
    {
      MBOUT1 = mSET_EVENT;
      MBOUT0 = mREAD_PARAM;
    }while(MBIN0!=mPARAMRDY&&MBIN1!=CALRDYME);

  	//_EINT();

  	// 开始测量(使ESP进入测量模式)
  	MBOUT1= modeCALIBRATION;
    MBOUT0= mSET_MODE;

    MBCTL= IN0IE;	//接收邮箱0中断使能
}

⌨️ 快捷键说明

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