📄 esp.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 + -