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

📄 measure.c

📁 用ADE7169F16单片机实现了单向多费4率电能表
💻 C
字号:
/*************************************
;Ade7169 demo program     
;*************************************
;AUTHOR:        Su RuTong
;DATE:          03 09 2006
;*************************************/


#include "hal.h"
#include "Measure.h"
#include "Public.h"
#include "utilities.h"
#include "UART.h"
#include "Storage.h"


unsigned long data _ade_int_evt_word;
// #define ADE_EVT_WORD _ade_int_evt_word

#define DEL_ADE_EVT(evt) (ADE_EVT_WORD&=~evt)
#define ADD_ADE_EVT(evt) (ADE_EVT_WORD|=evt)



/*
unsigned short DeltaWattActiveZ[4]={0,0,0,0};
unsigned short DeltaWattActiveF[4]={0,0,0,0};
unsigned short DeltaWattReactiveZ[4]={0,0,0,0};
unsigned short DeltaWattReactiveF[4]={0,0,0,0};
unsigned short DeltaWattVactiveZ[4]={0,0,0,0};
unsigned short DeltaWattVactiveF[4]={0,0,0,0};
*/
/*
// 当前时段表表号
//_sys_potinfo_s _SysPotInfo;
// 当前记量属性(正向尖,峰,平,谷;反向尖,峰,平,谷)
unsigned char PowerAttribute=0;
// 当前时段
unsigned char CurrentPotNum;
// delta energy
unsigned long _delta_energy[4];
// delta conter
unsigned char _delta_counter[4];
// delta energy left
unsigned long _delta_energy_left[4];
// delta energy / per second
unsigned long _delta_energy_sec[4];
// max demand power
unsigned long _delta_energy_min[4];
*/

// Tariff
//unsigned short CFAcc[4]={0,0,0,0};
//unsigned short WattActiveAcc[4]={0,0,0,0};
//unsigned short WattReactiveAcc[4]={0,0,0,0};

_sys_tariff_data idata curdata; //currentdata
_sys_inst_data idata instdata;

/*
__code const unsigned char _ade7758_wr[]=
{
    // 7-bits
    ADE_ADDR_APHCAL,// 0
    ADE_ADDR_BPHCAL,// 1
    ADE_ADDR_CPHCAL,// 2
    // 8-bits
    ADE_ADDR_WDIV,// 3
    ADE_ADDR_VARDIV,// 4
    ADE_ADDR_VADIV,// 5
    ADE_ADDR_OPMODE,// 6
    ADE_ADDR_MMODE,// 7
    ADE_ADDR_WAVMODE,// 8
    ADE_ADDR_COMPMODE,// 9
    ADE_ADDR_LCYCMODE,// 10
    ADE_ADDR_SAGCYC,// 11
    ADE_ADDR_SAGLVL,// 12
    ADE_ADDR_VPINTLVL,// 13
    ADE_ADDR_IPINTLVL,// 14
    ADE_ADDR_GAIN,// 15
    // 12-bits
    ADE_ADDR_AVRMSGAIN,// 16
    ADE_ADDR_BVRMSGAIN,// 18
    ADE_ADDR_CVRMSGAIN,// 20
    ADE_ADDR_AIGAIN,// 22
    ADE_ADDR_BIGAIN,// 24
    ADE_ADDR_CIGAIN,// 26
    ADE_ADDR_AWG,// 28
    ADE_ADDR_BWG,// 30
    ADE_ADDR_CWG,// 32
    ADE_ADDR_AVARG,// 34
    ADE_ADDR_BVARG,// 36
    ADE_ADDR_CVARG,// 38
    ADE_ADDR_AVAG,// 40
    ADE_ADDR_BVAG,// 42
    ADE_ADDR_CVAG,// 44
    ADE_ADDR_AVRMSOS,// 46
    ADE_ADDR_BVRMSOS,// 48
    ADE_ADDR_CVRMSOS,// 50
    ADE_ADDR_AIRMSOS,// 52
    ADE_ADDR_BIRMSOS,// 54
    ADE_ADDR_CIRMSOS,// 56
    ADE_ADDR_AWATTOS,// 58
    ADE_ADDR_BWATTOS,// 60
    ADE_ADDR_CWATTOS,// 62
    ADE_ADDR_AVAROS,// 64
    ADE_ADDR_BVAROS,// 66
    ADE_ADDR_CVAROS,// 68
    ADE_ADDR_APCFDEN,// 70
    ADE_ADDR_VARCFDEN,// 72
    // 16 bits
    ADE_ADDR_APCFNUM,// 74
    ADE_ADDR_VARCFNUM,// 76
    ADE_ADDR_ZXTOUT,// 78
    ADE_ADDR_LINECYC,// 80
    // 24 bits
    ADE_ADDR_MASK,// 82
    ERROR
};

__code const unsigned char _ade7758_read_only[]=
{
    // 8 bits
    ADE_ADDR_TEMP,
    ADE_ADDR_VPEAK,
    ADE_ADDR_IPEAK,
    ADE_ADDR_CHKSUM,
    ADE_ADDR_VERSION,
    // 12 bits
    ADE_ADDR_FREQ,
    // 16 bits
    ADE_ADDR_AWATTHR,
    ADE_ADDR_BWATTHR,
    ADE_ADDR_CWATTHR,
    ADE_ADDR_AVARHR,
    ADE_ADDR_BVARHR,
    ADE_ADDR_CVARHR,
    ADE_ADDR_AVAHR,
    ADE_ADDR_BVAHR,
    ADE_ADDR_CVAHR,
    // 24 bits
    ADE_ADDR_AIRMS,
    ADE_ADDR_BIRMS,
    ADE_ADDR_CIRMS,
    ADE_ADDR_AVRMS,
    ADE_ADDR_BVRMS,
    ADE_ADDR_CVRMS,
    ADE_ADDR_WFORM,
    ADE_ADDR_STATUS,
    ADE_ADDR_RSTATUS,
    ERROR
};
*/
//this function loads the ADE Register with the content of ByteH,ByteM,ByteL
void Write_ADE_SFR(char ByteM, char ByteL, char Register) {

///////  MDATH = 0x00;
  MDATM = ByteM;
  MDATL = ByteL;
  MADDPT = 0x80 | Register;

  return;
}

//this function reads the ADE Register and puts the result into ByteH, ByteM, ByteL
void Read_ADE_SFR(unsigned char __idata *Pointer, char Register) {
  char ByteH, ByteM, ByteL;

  MADDPT = Register;
  ByteH = MDATH;
  ByteM = MDATM;
  ByteL = MDATL;

  *Pointer = ByteL;
  *(Pointer+1) = ByteM;
  *(Pointer+2) = ByteH;
  return;
}

/*********************************************************************
  Input:None
  Output:None
  Sets up the ADE for 3200imp/kWh (uncalibrated) with CF1 = Watt, CF2 = VAR.
  Also enables CF1 and CF2 interrupts. All other ADE interrupts disabled.
  No loads disabled.
**********************************************************************/
void InitADE(void)
{
    Write_ADE_SFR(0x00, 0x80, MODE1);
    delay(2000);
    Write_ADE_SFR(0x00, 0x04, MODE1);
    Write_ADE_SFR(0x00, 0x45, MODE2);
    Write_ADE_SFR(0x00, 0x07, WAVMODE);
    Write_ADE_SFR(0x00, 0x55, NLMODE);
    Write_ADE_SFR(0x00, 0x00, ACCMODE);
    //read GAIN value from EEPROM
    ee_read_bytes(ADDR_OF_GAIN_VAL,tmp_buf,1);
    Write_ADE_SFR(0x00, tmp_buf[0], GAIN);

    Write_ADE_SFR(0x00, 0x10, CALMODE);
    Write_ADE_SFR(0x00, 0x14, LINCYC);
    Write_ADE_SFR(0x00, 0x00, WDIV);
    Write_ADE_SFR(0x00, 0x00, CF1NUM);
    
    // Load calibrat data from EEPROM
    // GAIN,CF1DEN,WGAIN,PHCAL,WATTOS

    ee_read_bytes(ADDR_OF_CF1DEN_VAL,tmp_buf,2);
    Write_ADE_SFR(tmp_buf[1], tmp_buf[0], CF1DEN);
    ee_read_bytes(ADDR_OF_WGAIN_VAL,tmp_buf,2);
    Write_ADE_SFR(tmp_buf[1], tmp_buf[0], WGAIN);
    ee_read_bytes(ADDR_OF_PHCAL_VAL,tmp_buf,1);
    Write_ADE_SFR(0x00, tmp_buf[0], PHCAL);
    ee_read_bytes(ADDR_OF_WATTOS_VAL,tmp_buf,2);
    Write_ADE_SFR(tmp_buf[1], tmp_buf[0], WATTOS);

    green=0;
    MIRQENH=green;
    MIRQENM=CF1INT;
    MIRQENL=green;
    //enable Energy Metering Interrupt
    IPSME  = 0;
    IEIP2 |= EADE;
    //IEIP2_bit.EADE = 1;
}

// Modifies R0 in register bank 0
void InitRMSThresh(void)
{
	// V100Thresh	; set threshold to 0x6970B
	// ; 0x5EED3
    // V100Thresh=0x5EED3;
	// V10Thresh	; set threshold to 0x6970B
	// ; 0x97E2

	// V1Thresh	; set threshold to 0x6970B
	// ; 0xF30
    // V1Thresh=0xF30;
	// Vp1Thresh	; set threshold to 0x6970B
	// ; 0x185
    // Vp1Thresh=0x185;

	// A10Thresh	
    // ; 0x39F19
    // A10Thresh=0x39F19;
    // A1Thresh	
	// ; 0x5CB6
    // A1Thresh=0x5CB6;
	// Ap1Thresh	
	// ; 0x945
    // Ap1Thresh=0x945;
	// Ap10Thresh	;
	// ; 0xED
    // Ap10Thresh=0xED;
	// Ap100Thresh	;
	// ; 0x18
	// Ap100Thresh=0x18
}


void GetVrms(void)
{
    unsigned char tmp[3];
    // Vrms=((ReadVRMS/V1Thresh)<<8)+((ReadVRMS%V1Thresh)/Vp1Thresh);  // 0.1v
    tmp[0]=VRMSH;
    tmp[1]=VRMSM;
    tmp[2]=VRMSL;
    instdata.Vrms=tmp[0];
    instdata.Vrms=(instdata.Vrms<<8)|tmp[1];
    instdata.Vrms=(instdata.Vrms<<8)|tmp[2];
    // instdata.chksum=instdata.PER_FREQ+instdata.Vrms+instdata.Vrms+instdata.Irms+instdata.Waveform[0]+instdata.Waveform[1];
}

void GetIrms(void)
{
    unsigned char tmp[3];
    // Arms=((ReadARMS/A1Thresh)<<8)+((ReadARMS%A1Thresh)/Ap1Thresh);  // 0.1A
    tmp[0]=IRMSH;
    tmp[1]=IRMSM;
    tmp[2]=IRMSL;
    instdata.Irms=tmp[0];
    instdata.Irms=(instdata.Irms<<8)|tmp[1];
    instdata.Irms=(instdata.Irms<<8)|tmp[2];
    // instdata.chksum=instdata.PER_FREQ+instdata.Vrms+instdata.Vrms+instdata.Irms+instdata.Waveform[0]+instdata.Waveform[1];
}

void GetADCWaveforms(unsigned char item)
{
    unsigned char tmp[3];
    tmp[0]=WAV1H;
    tmp[1]=WAV1M;
    tmp[2]=WAV1L;
    instdata.Waveform[item]=tmp[0];
    instdata.Waveform[item]=(instdata.Waveform[item]<<8)|tmp[1];
    instdata.Waveform[item]=(instdata.Waveform[item]<<8)|tmp[2];
    // instdata.chksum=instdata.PER_FREQ+instdata.Vrms+instdata.Vrms+instdata.Irms+instdata.Waveform[0]+instdata.Waveform[1];
}

void GetActiveEnergy(void)//(unsigned char item,unsigned char *dat)
{
    // Read_ADE_SFR();
}

void GetReactiveEnergy(void)//(unsigned char item,unsigned char *dat)
{
    // Read_ADE_SFR();
}
/*
void AccPulseCF1(unsigned char *dat)
{
    if(curdata.wattpulsecnt[curdata.tariff]%16) return;
    else{curdata.watthour[curdata.tariff] += curdata.wattpulsecnt[curdata.tariff]/3; }
}

void AccPulseCF2(unsigned char *dat)
{
    if(curdata.vartpulsecnt[curdata.tariff]%16) return;
    else{curdata.varthour[curdata.tariff] += curdata.vartpulsecnt[curdata.tariff]/3; }
}
*/

//#if 0
void _waveform_isr_proc(void)
{
}

void _current_peak_isr_proc(void)
{
}

void _voltage_peak_isr_proc(void)
{
}

void _line_cycle_isr_proc(void)
{
}

void _zx_timeout_isr_proc(void)
{
}
void _zx_isr_proc(void)
{
}
// config as reactive
void _CF2_isr_proc(void)
{
    curdata.vartpulsecnt[curdata.tariff] += 1;
    if(curdata.vartpulsecnt[curdata.tariff]%16) return;
    else{curdata.varthour[curdata.tariff] += curdata.vartpulsecnt[curdata.tariff]/3; }
}
// config as active
void _CF1_isr_proc(void)
{
    curdata.wattpulsecnt[curdata.tariff] += 1;
    if(curdata.wattpulsecnt[curdata.tariff]%16) return;
    else{curdata.watthour[curdata.tariff] += curdata.wattpulsecnt[curdata.tariff]/3; }
}

void _APE_ovfl_isr_proc(void)
{
}

void _REA_ovfl_isr_proc(void)
{
}

void _ACT_ovfl_isr_proc(void)
{
}

void _APE_hful_isr_proc(void)
{
}

void _REA_hful_isr_proc(void)
{
}

void _ACT_hful_isr_proc(void)
{
}

    //
void _OR_all_en_sta(void)
{
}

void _fault_isr_proc(void)
{
}

void _VAR_sign_chg_isr_proc(void)
{
}

void _WATT_sign_chg_isr_proc(void)
{
}

void _APP_noload_isr_proc(void)
{
}

void _REA_noload_isr_proc(void)
{
}

void _ACT_noload_isr_proc(void)
{
}
//#endif

code const _ADE_PROC_PTR _ade_int_handle[]=
{
    // H byte
    _reserved,
    _reserved,
    //#if 0
    _waveform_isr_proc,
    _current_peak_isr_proc,
    _voltage_peak_isr_proc,
    _line_cycle_isr_proc,
    _zx_timeout_isr_proc,
    _zx_isr_proc,
    // M byte
    _CF2_isr_proc,
    _CF1_isr_proc,
    _APE_ovfl_isr_proc,
    _REA_ovfl_isr_proc,
    _ACT_ovfl_isr_proc,
    _APE_hful_isr_proc,
    _REA_hful_isr_proc,
    _ACT_hful_isr_proc,
    // L byte
    _OR_all_en_sta,
    _fault_isr_proc,
    _VAR_sign_chg_isr_proc,
    _WATT_sign_chg_isr_proc,
    _APP_noload_isr_proc,
    _REA_noload_isr_proc,
    _ACT_noload_isr_proc, 
    //#endif
};

void ParseADEInt(void)
{
    unsigned long i;
    for(i=0;i<sizeof(_ade_int_handle)/sizeof(_ADE_PROC_PTR);i++)
	{
		if((ADE_EVT_WORD&(BIT0<<i)))
		{
			// do_sys_chk();
			_ade_int_handle[i]();
			DEL_ADE_EVT(BIT0<<i);
			// CLR_WDT();
			// _do_regs_chk();
		} 
	}
	// clear int flag
	MIRQSTH = 0;
	MIRQSTM = 0;
	MIRQSTL = 0;
}

// energy interrupt service
#ifdef __IAR_SYSTEMS_ICC__
#pragma vector=iade
#pragma register_bank=1
__interrupt void _ade_isr(void)
#else
void _ade_isr(void) interrupt 9 using 2
#endif
{
    unsigned char i,j,k;
    
    i  = MIRQENH;
    i &= MIRQSTH;
    j  = MIRQENM; 
    j &= MIRQSTM;
    k  = MIRQENL;
    k &= MIRQSTL;
    //i=((EIRQENH&EIRQSTH)<<8)|(EIRQENM&EIRQSTM);
    ADE_EVT_WORD=i;//(EIRQENH&EIRQSTH);
    ADE_EVT_WORD=(ADE_EVT_WORD << 8)|j;//(EIRQENM&EIRQSTM);
    ADE_EVT_WORD=(ADE_EVT_WORD << 8)|k;//(EIRQENL&EIRQSTL);
    // ADE_EVT_WORD=( ((EIRQENH&EIRQSTH)<<16)| ((EIRQENM&EIRQSTM)<<8)| (EIRQENL&EIRQSTL) );
    if(ADE_EVT_WORD)
    {
        ParseADEInt();
    }
}

void _ReadVRMS(void)
{
    GetVrms();
    Uart_buf[3]=(unsigned char)(instdata.Vrms);
    Uart_buf[4]=(unsigned char)(instdata.Vrms>>8);
    Uart_buf[5]=(unsigned char)(instdata.Vrms>>16);
    Uart_buf[6]=(unsigned char)(instdata.Vrms>>24);
    // ACK
    Uart_buf[1]=5;
    _uart_start_tx();
}

void _ReadIRMS(void)
{
    GetIrms();
    Uart_buf[3]=(unsigned char)(instdata.Irms);
    Uart_buf[4]=(unsigned char)(instdata.Irms>>8);
    Uart_buf[5]=(unsigned char)(instdata.Irms>>16);
    Uart_buf[6]=(unsigned char)(instdata.Irms>>24);
    // ACK
    Uart_buf[1]=5;
    _uart_start_tx();
}

void _ReadActive(void)
{
}

void _ReadRActive(void)
{
}

void _ReadRA(void)
{
}

void _ReadRR(void)
{
}

void SavePowerData(void)
{
    __disable_interrupt();
    ee_write_bytes(ADDR_OF_STA_RDDATA_AP_S,(unsigned char idata *)&curdata.watthour[curdata.tariff],4);
    ee_write_bytes(ADDR_OF_STA_RDDATA_RAP_S,(unsigned char idata *)&curdata.varthour[curdata.tariff],4);
    __enable_interrupt();
}









⌨️ 快捷键说明

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