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

📄 powersupply.c

📁 单相多功能代码,计量芯片采用ADE7737做为计量,SPI通讯,仅供参考,不得用于商业
💻 C
字号:
#include "powersupply.h"

// 当前电流电压(A,B,C相电压;A,B,C相电流)
unsigned short CurrentVI[6];
// 电源状态标志
unsigned char PowerStateFlag=0;
// 电表运行状态
unsigned char MeterRunningState=0;
// 电表运行状态字
unsigned char MeterRunningStateWord=0x02;
// 电网状态字
unsigned char PowerNetStateWord=0;
// 失压失流状态
unsigned char LostVIStateWord=0;
// 有功功率相位
unsigned char PhaseActive=0;
// 无功功率相位
unsigned char PhaseReactive=0;
// 失压时间(分钟)
unsigned char PhaseLostVTime=0;
// 失流时间(分钟)
unsigned char PhaseLostITime=0;
// 电表运行时间
unsigned char MeterRunTime=0;
// 电池使用时间
unsigned char BatteryRunTime=0;
// 当前频率
unsigned short CurrentFreq=0;

/* Voltage detect
* 1. Save drop power time and times
* 2. Freeze power data when drop power
* 3. Perform every second
*/
void VoltageDetect(void)
{
    
}

#if 0
void SaveLowVoltageStartTime(unsigned long addr)
{
    unsigned long temp;
    
    SaveSystimeToDataflashByte4(addr);
    BcdShortAdd1AndWriteE2prom(addr+4);
    LoadSpecPwrDataCurSum((unsigned char *)&temp,0);
    VariationalDataWrite(addr+9,(unsigned char *)&temp,4);
}

void SaveLowVoltageTime(unsigned long addr,unsigned long addr1,unsigned char *runtime)
{
    unsigned long t,ts;
    unsigned char tt;
    
    VariationalDataRead(addr,(unsigned char *)&t,3);
    VariationalDataRead(addr1,(unsigned char *)&ts,3);
    tt=Hex2BcdChar(*runtime);
    t=__bcd_add_long(t,(unsigned long)tt);
    ts=__bcd_add_long(ts,(unsigned long)tt);
    VariationalDataWrite(addr,(unsigned char *)&t,3);
    VariationalDataWrite(addr1,(unsigned char *)&ts,3);
    *runtime=0;
}

/******************************************
* 掉电检测
******************************************/
void BreakPowerDetect(void)
{
    unsigned char flag;
    
    if(!(PWR_F0_IN&PWR_F0))
    {
        // 停电处理
        if(!(PowerStateFlag&PS_BREAKPOWER_FLAG))
        {
            // 扩展I/O的驱动管脚置低
            P6OUT&=~(STCP|MR|SHCP|DS);
            ExtIoState=0;
            
            P3DIR|=(ADE7758_DO);
            P3OUT&=~(ADE7758_DI|ADE7758_CLK|ADE7758_DO|ADE7758_CS);
            //P3OUT|=(ADE7758_DI|ADE7758_CLK|ADE7758_DO|ADE7758_CS);
            
            P2DIR|=ADE7758_IRQ;
            P2SEL&=~(RS485_TX);
            //P2OUT&=~(RS485_TX+ADE7758_IRQ);
            P2OUT&=~(RS485_TX);
            P2OUT|=ADE7758_IRQ;
            
            // 保存当天电量数据
            //StorePowerData();

            flag=0x5A;
            AptoticDataWrite(ADDR_OF_BREAK_POWER_FLAG,(unsigned char *)&flag,1);
            AptoticDataWrite(ADDR_OF_RAM,(unsigned char *)&TodayPower[0],164);
            AptoticDataWrite(ADDR_OF_RAM+164,(unsigned char *)&PwrData.chksum,sizeof(_sys_wat_data));
            // 保存停电时间
            SavePgmInfo(ADDR_OF_CP_IDX);
            MemSetTo0((unsigned char *)&CurrentVI[0],12);
            LostVIStateWord=0x77;
            //MeterRunningState=0x77;
            PowerNetStateWord=0x77;
            //BTCTL=BT_ADLY_1000+BT_fLCD_DIV128+BTFRFQ1;
            AlarmCtlWord|=ALARM_OF_POWERUP;
            PowerStateFlag|=PS_BREAKPOWER_FLAG;
        }
        LCDMEM[15]=0;
        LCDMEM[16]&=~(BIT0|BIT1);
    }
    else
    {
        // 来电处理
        if(PowerStateFlag&PS_BREAKPOWER_FLAG)
        {
            // 扩展I/O的驱动管脚置高
            P6OUT|=(STCP|MR|SHCP|DS);
            
            P3DIR=P3DIR_VAL;
            P3OUT=P3OUT_VAL;
            
            P2DIR&=~(ADE7758_IRQ);
            P2SEL|=RS485_TX;
            P2OUT|=RS485_TX;
            
            // 初始化7758
            SetSystemEvent(EVENT_INIT_ADE7758);
            // 保存来电时间
            SavePgmInfo(ADDR_OF_UP_IDX);
            //BTCTL=BT_ADLY_125+BT_fLCD_DIV128+BTFRFQ1;
            flag=0xA5;
            AptoticDataWrite(ADDR_OF_BREAK_POWER_FLAG,(unsigned char *)&flag,1);
            AlarmCtlWord&=~ALARM_OF_POWERUP;
            PowerStateFlag&=~(PS_BREAKPOWER_FLAG);
            // 初始化扩展I/O
            EXT_IO_HIGH();
        }
        //LCDMEM[15]|=(LCD_SY_INFO_N1|LCD_SY_INFO_N2|LCD_SY_INFO_N3|LCD_SY_INFO_N4);
        //LCDMEM[16]|=(BIT0|BIT1);
    }
}

void SetFreqSel(unsigned char sel)
{
    Ade7758Write(ADE_ADDR_MMODE,&sel,1);
    AptoticDataWrite(ADDR_OF_ADE_BASE+3*7,&sel,1);
    EnsurePeriodOfTime();
}

// A,B,AB,C,AC,BC,ABC
const unsigned long _LowVoltageItemAddr[]=
{
    ADDR_OF_LV_PHA_LATELY_T,
    ADDR_OF_LV_PHB_LATELY_T,
    ADDR_OF_LV_PHAB_LATELY_T,
    ADDR_OF_LV_PHC_LATELY_T,
    ADDR_OF_LV_PHAC_LATELY_T,
    ADDR_OF_LV_PHBC_LATELY_T,
    ADDR_OF_LV_PHABC_LATELY_T,
    ADDR_OF_LI_PHA_LATELY_T,
    ADDR_OF_LI_PHB_LATELY_T,
    ADDR_OF_LI_PHAB_LATELY_T,
    ADDR_OF_LI_PHC_LATELY_T,
    ADDR_OF_LI_PHAC_LATELY_T,
    ADDR_OF_LI_PHBC_LATELY_T,
    ADDR_OF_LI_PHABC_LATELY_T,
};
// A,B,AB,C,AC,BC,ABC
const unsigned long _LowVoltageStopTimeItemAddr[]=
{
    ADDR_OF_LV_PHA_STOP_T,
    ADDR_OF_LV_PHB_STOP_T,
    ADDR_OF_LV_PHAB_STOP_T,
    ADDR_OF_LV_PHC_STOP_T,
    ADDR_OF_LV_PHAC_STOP_T,
    ADDR_OF_LV_PHBC_STOP_T,
    ADDR_OF_LV_PHABC_STOP_T,
    ADDR_OF_LI_PHA_STOP_T,
    ADDR_OF_LI_PHB_STOP_T,
    ADDR_OF_LI_PHAB_STOP_T,
    ADDR_OF_LI_PHC_STOP_T,
    ADDR_OF_LI_PHAC_STOP_T,
    ADDR_OF_LI_PHBC_STOP_T,
    ADDR_OF_LI_PHABC_STOP_T,
};
//
const unsigned long _LostVISumTime[]=
{
    ADDR_OF_LV_SUM_T,
    ADDR_OF_LI_SUM_T,
};
//
const unsigned long _LostVIStartTime[]=
{
    ADDR_OF_LV_LATELY_T,
    ADDR_OF_LI_LATELY_T,
};
//
const unsigned long _LostVIStopTime[]=
{
    ADDR_OF_LV_STOP_T,
    ADDR_OF_LI_STOP_T,
};
//
const unsigned char _MModeVal[]=
{
    0,1,0,2,0,1,0,0
};
/******************************************
* 电压检测
******************************************/
void PhaseVoltageDetect(void)
{
    unsigned long vtemp;
    unsigned char i[2],temp[2];
    unsigned char lvisw=LostVIStateWord;
    unsigned char mrs=MeterRunningState;
    unsigned char pnsw=PowerNetStateWord&0x70;

    // 如果没有掉电,则读相电压
    if(!(PowerStateFlag&PS_BREAKPOWER_FLAG))
    {
        for(i[0]=0;i[0]<3;i[0]++)
        {
            vtemp=0;
            if(Ade7758Read(ADE_ADDR_AIRMS+i[0],(unsigned char *)&vtemp,3)==OK)
            {
                // 取低2字节
                vtemp>>=8;
                if(vtemp&0x00008000)
                {
                    vtemp=(~(vtemp)+1);
                    vtemp&=0x0000FFFF;
                }
                
                vtemp*=_SysPotInfo.currentcoe;
                vtemp/=1000;
                
                // 失流及断流检测
                temp[0]=PS_LIA_PHA<<i[0];
                if((unsigned short)vtemp<_SysPotInfo.losti_con)
                {
                    // 置失流标志
                    if(!(lvisw&temp[0]))
                    {
                        lvisw|=temp[0];
                    }
                    if(vtemp<10)
                    {
                        // 置断流标志
                        if(!(mrs&temp[0]))
                        {
                            mrs|=temp[0];
                        }
                    }
                    else
                    {
                        // 清断流标志
                        if(mrs&temp[0])
                        {
                            mrs&=~(temp[0]);
                        }
                    }
                }
                else
                {
                    // 清断流标志
                    if(mrs&temp[0])
                    {
                        mrs&=~(temp[0]);
                    }
                    // 清失流标志
                    if(lvisw&temp[0])
                    {
                        lvisw&=~(temp[0]);
                    }
                }
                // 保存当前电流
                CurrentVI[i[0]+3]=(unsigned short)vtemp;
            }
            
            vtemp=0;
            // 读电压有效值
            if(Ade7758Read(ADE_ADDR_AVRMS+i[0],(unsigned char *)&vtemp,3)==OK)
            {
                // 取低2字节
                vtemp>>=8;
                if(vtemp&0x00008000)
                {
                    vtemp=(~(vtemp)+1);
                }

                // 失压检测
                temp[0]=PS_LVA_PHA<<i[0];
                if((unsigned short)vtemp<_SysPotInfo.lostv_con)
                {
                    // 置失压标志
                    if(!(lvisw&temp[0]))
                    {
                        lvisw|=temp[0];
                    }
                    if((unsigned short)vtemp<110)
                    {
                        // 置断压标志
                        if(!(mrs&temp[0]))
                        {
                            mrs|=temp[0];
                        }
                    }
                    else
                    {
                        // 清断压标志
                        if(mrs&temp[0])
                        {
                            mrs&=~(temp[0]);
                        }
                    }
                }
                else
                {
                    // 清失压标志
                    if(lvisw&temp[0])
                    {
                        lvisw&=~(temp[0]);
                    }
                    // 清断压标志
                    if(mrs&temp[0])
                    {
                        mrs&=~(temp[0]);
                    }
                }
                
                temp[0]=(PS_NET_OVER_PHA<<i[0]);
                // 过压检测
                if((unsigned short)vtemp>_SysPotInfo.regv_max)
                {
                    // 置过压标志
                    if(!(pnsw&temp[0]))
                    {
                        pnsw|=temp[0];
                    }
                }
                else
                {
                    // 清过压标志
                    if(pnsw&temp[0])
                    {
                        pnsw&=~(temp[0]);
                    }
                    // 清过压标志
                    if(pnsw&temp[0])
                    {
                        pnsw&=~(temp[0]);
                    }
                }
                
                // 保存当前电压
                CurrentVI[i[0]]=(unsigned short)vtemp;
            }
        }
    }
    if((lvisw==0)&&((mrs&0x7F)==0)&&(pnsw==0))
    {
        LCDMEM[LCD_CN_INFO_ADDR_ALARM]&=~LCD_CN_INFO_ALARM;
    }
    else
    {
        LCDMEM[LCD_CN_INFO_ADDR_ALARM]|=LCD_CN_INFO_ALARM;
    }
    temp[0]=_SysPotInfo.ade7758_info[7]&0xFC;
    temp[0]|=_MModeVal[mrs&0x07];
    if(temp[0]!=_SysPotInfo.ade7758_info[7])
    {
        SetFreqSel(temp[0]);
    }
    MeterRunningState=mrs;
    pnsw=(pnsw|(mrs&0x07));
    PowerNetStateWord=pnsw;
    if(LostVIStateWord!=lvisw)
    {
        temp[0]=LostVIStateWord&0x07;
        temp[1]=(LostVIStateWord>>4)&0x07;
        i[0]=lvisw&0x07;
        i[1]=(lvisw>>4)&0x07;
        for(mrs=0;mrs<2;mrs++)
        {
            if(temp[mrs]!=i[mrs])
            {
                pnsw=mrs*7;
                if(temp[mrs]!=0)
                {
                    SaveLowVoltageTime(_LowVoltageItemAddr[temp[mrs]-1+pnsw]+6,_LostVISumTime[mrs],(unsigned char *)&PhaseLostVTime);
                }
                else
                {
                    SaveLowVoltageStartTime(_LostVIStartTime[mrs]);
                }
                if(i[mrs]!=0)
                {
                    SaveLowVoltageStartTime(_LowVoltageItemAddr[i[mrs]-1+pnsw]);
                }
                else
                {
                    SaveSystimeToDataflashByte4(_LostVIStopTime[mrs]);
                    SaveSystimeToDataflashByte4(_LowVoltageStopTimeItemAddr[temp[mrs]-1+pnsw]);
                }
            }
        }
    }
    LostVIStateWord=lvisw;
}

void LowVoltageDetect(void)
{
    unsigned char temp;

    temp=LostVIStateWord&0x07;
    if(temp)
    {
        PhaseLostVTime++;
        if(PhaseLostVTime>60)
        {
            SaveLowVoltageTime(_LowVoltageItemAddr[temp-1]+6,ADDR_OF_LV_SUM_T,(unsigned char *)&PhaseLostVTime);
        }
    }
    
    temp=(LostVIStateWord>>4)&0x07;
    if(temp)
    {
        PhaseLostITime++;
        if(PhaseLostITime>60)
        {
            SaveLowVoltageTime(_LowVoltageItemAddr[temp+6]+6,ADDR_OF_LI_SUM_T,(unsigned char *)&PhaseLostITime);
        }
    }
}

void SaveTotleTime(unsigned long addr,unsigned char t)
{
    unsigned long ttmp;
    
    VariationalDataRead(addr,(unsigned char *)&ttmp,4);
    t=Hex2BcdChar(t);
    ttmp=__bcd_add_long(ttmp,(unsigned long)t);
    VariationalDataWrite(addr,(unsigned char *)&ttmp,4);
}

void SaveRunTime(void)
{
    // 保存电表运行时间
    MeterRunTime++;
    if(MeterRunTime>=60)
    {
        SaveTotleTime(ADDR_OF_METER_RUNTIME,MeterRunTime);
        MeterRunTime=0;
    }
    if(PowerStateFlag&PS_BREAKPOWER_FLAG)
    {
        BatteryRunTime++;
        if(BatteryRunTime>=60)
        {
            SaveTotleTime(ADDR_OF_BATTERY_RUNTIME,BatteryRunTime);
            BatteryRunTime=0;
        }
    }
    else
    {
        if(BatteryRunTime)
        {
            SaveTotleTime(ADDR_OF_BATTERY_RUNTIME,BatteryRunTime);
            BatteryRunTime=0;
        }
    }
}
#endif

⌨️ 快捷键说明

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