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