?? 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 + -