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

📄 setting.c

📁 该程序用msp430单片机开发了一款单相电子式多费率电能表
💻 C
字号:
// ****************************************************************************
//                             初始化时钟
// ****************************************************************************
void Init_FLL(void)
{
	FLL_CTL0 |= XCAP18PF;     // 配置电容
  SCFI0 = FLLD_1;  			    // Freq = 1.024MHz
  SCFQCTL = 32 - 1;

}
// ****************************************************************************
//                           提升主频到 8MHz
// ****************************************************************************
void Goto_High_Freq(void)
{
    //  提升主频前,应确认电源电压是合适跑高频
    SVSCTL |= (SVSON | 0x60);
	  // 等待电源电压到适合跑高频
    while ((SVSCTL & SVSOP));
    // 电源电压已适合CPU跑高频,SVS进入低电压检测复位状态
    SVSCTL |= PORON;
    // 提升主频到 8MHz
    SCFI0 = FN_4 | FLLD_2;
    SCFQCTL = 128 - 1;
    FLL_CTL0 |= DCOPLUS;
    for(unsigned int i=0;i<10000;i++)
    {
      _NOP();
    }
} 
/*************************************************/
/*        初始化系统硬件								 */
/*************************************************/
void Init_Sys_Hardware(void)
{
	P1OUT = 0x00;
	P1DIR = LED_YG_BIT + LED_WG_BIT + BIT4 + BIT5;
	P1IFG = 0x00;
	P1SEL = 0x00;
	P2OUT = EE_SCL_BIT + EE_SDA_BIT;
	P2DIR = EE_SCL_BIT + EE_SDA_BIT + BIT2;
	P2IES = 0x00;
	P2IFG = 0x00;
	P2IE  = 0;
	for (char i=0; i<20; i++)
  	{
   	  LCDMEM[i] = 0x00;
  	} 
        LCDCTL = LCDSG0_3 +LCD4MUX + LCDON;
	// 设置中断频率为 0.5s, 液晶时钟原32分频 */
	BTCTL = BT_fLCD_DIV32 | BT_fCLK2_DIV64 | BT_fCLK2_ACLK_DIV256;
	// 1s 中断使能 */  
	IE2 |= BTIE;
        BG_OUT |= BG_BIT; 
        bgbzh = 1;
        bgtimer = 0;
}

// ****************************************************************************
//           初始化定时器A和TIMERA CCR0       
// 说明:定时器时钟为ACLK, 定时器工作模式,连续计数模式
// 作用:定时检查能量累计,判断是否输出校表脉冲。
// ****************************************************************************
void Init_TA(void)
{
	TACTL = TACLR  | TASSEL_1;
 	TACTL |= MC_2;
} 

/*****************************************************************
*                        模拟前端初始化函数                      *
* 说明:配置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)
  {
    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;
// -------------------------------------------------------------------
//  * 配置电流通道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 + SD16GRP;
// -----------------------------------------------------------
//  *	配置电压通道
//  * 电阻分压,最大输入电压 VIN=(220 + 220*0.2)  * (1/991)*1.414 = 376 mV
//  * 选择增益放大倍速 GAIN = 1
  	SD16INCTL2= SD16GAIN_1;// 设置电压通道V1的增益放大倍数GAIN = 1
	SD16CCTL2 = SD16OSR_256 + SD16DF + SD16GRP;     // 设置电压通道V1过采样率为 256
  	SD16CONF0 = SD16CONF0_FUDGE;
   SD16CONF1 = SD16CONF1_FUDGE;
  }
  else
  {
  	  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)
    	{
    		return;
    	}
    	//判断反馈消息是否与发送的内容相符
  	} while ((MBIN0 != mPARAMSET) || (MBIN1 != param));
}
/********************************************************************
*                        初始化ESP430CE1模块                        *
*                                                                   *
********************************************************************/
void Init_ESP_Parameter(void)
{
	unsigned int timeout,i;// 定义超时溢出计数寄存器
 	ESPCTL |= ESPEN;// 确信嵌入式处理器在使能状态
  	MBCTL = 0;
  	if ((ESP430_STAT0 & ACTIVEFG) != 0)// 初始化前需要保证ESP不在测量状态或者校准状态
  	{
    	MBOUT1= modeIDLE;// 如果不是在空闲状态,则使它进入空想状态
    	MBOUT0= mSET_MODE;
    	timeout= 0xffff;// 等待进入空闲状态,以便后续的设置
   	while (((ESP430_STAT0 & ACTIVEFG) != 0) && (timeout-- > 0)) ;
  	}
  	MBOUT1 = 0;
  	MBOUT0 = modeRESET;
  	
  	for(i=0;i<50000;i++);
  	
  	MBOUT0= mSWVERSION;// 读ESP软件版本号
  	timeout= 0xffff;
  	do
  	{
    	while (((MBCTL & IN0IFG) == 0) && (timeout-- > 0)) ;
    	if (timeout == 0)
    	{
    		return;
    	}
  	} while (MBIN0 != mSWRDY);
	/*************** 初始化参数寄存器 ******************/
  	// 配置参数寄存器Control 0
  	Set_Parameter(mSET_CTRL0,defSET_CTRL0);     //241
  	// 设置相位校正寄存器
    Set_Parameter(mSET_PHASECORR1,Esp.iPhaseCorr1); //59
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_PHASECORR2,Esp.iPhaseCorr2);  //64
#endif
    Set_Parameter(mSET_ADAPTI1, Esp.uiAdaptI1);   //17060
#ifdef TAMPER_DETECTION
  	// 设置两电流通道自适应因子
    Set_Parameter(mSET_ADAPTI2, Esp.uiAdaptI2);   //31250
#endif
  	Set_Parameter(mSET_GAINCORR1, Esp.uiGainCorr1); //19319
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_GAINCORR2, Esp.uiGainCorr2);    //18998
#endif
    Set_Parameter(mSET_POFFSET1_LO, *(int*)(&Esp.lPowerOffset1)); //0
  	Set_Parameter(mSET_POFFSET1_HI, *(((int*)(&Esp.lPowerOffset1))+1)); //0
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_POFFSET2_LO, *(int*)(&Esp.lPowerOffset2)); //52612
  	Set_Parameter(mSET_POFFSET2_HI, *(((int*)(&Esp.lPowerOffset2))+1));
#endif
    Set_Parameter(mSET_STARTCURR_FRAC, *(int*)(&Esp.ulStartCurrent));  //0
    Set_Parameter(mSET_STARTCURR_INT, *(((int*)(&Esp.ulStartCurrent))+1));  //0
    // 设置电网正常频率 50Hz
  	Set_Parameter(mSET_NOMFREQ, Esp.uiNomFreq);   //50
#ifdef TAMPER_DETECTION
    Set_Parameter(mSET_RATIOTAMP, Esp.RATIOTAMP_INIT);	//18022
  	Set_Parameter(mSET_ITAMP, Esp.ITAMP_INIT);          //320
#endif  	
    Set_Parameter(mSET_VDROPLEVEL, VDROPLEVEL_INIT);   //4096

  	Set_Parameter(mSET_VPEAKLEVEL, VPEAKLEVEL_INIT); //32767

    Set_Parameter(mSET_IPEAKLEVEL, IPEAKLEVEL_INIT);    //32767

    Set_Parameter(mSET_DCREMPER, DCREMPER_INIT);      //5

} 

/*******************************************************************
*                         这个函数使ESP进入测量状态                *
*******************************************************************/
void Start_Measurement(void)
{
   	Set_Parameter(mSET_EVENT, defSET_EVENT);  // 当事件<新的能量值准备好>发生时发出中断请求
  	MBCTL= IN0IE;	//接收邮箱0中断使能
  	// 开始测量(使ESP进入测量模式)
  	MBOUT1= modeMEASURE;
  	MBOUT0= mSET_MODE;
   TACCR0 = TAR + TIMERA_PULSE_PERIOD;
 	TACCTL0 = CCIE;
} // 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)) ;
  	}
 	TACCTL0 = 0;
}



//*************ROM区校验计算函数*************************/
unsigned char ChkSum(unsigned char *Ptr,int Len)
{
  unsigned char Sum=0x33;
   while(Len>0)
   {
      Sum += *Ptr;
      Ptr++;
      Len--;
   }
   return(Sum);
}

⌨️ 快捷键说明

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