标题:
单片机单相电能表源码
[打印本页]
作者:
niuzhihong
时间:
2016-4-3 08:04
标题:
单片机单相电能表源码
单相飞控智能电表源码,单相多功能电能表源码。电能计量,485通讯,总线通讯,液晶显示等功能
0.png
(43.89 KB, 下载次数: 140)
下载附件
2016-4-6 15:25 上传
全部源码下载:
单相多功能电能表源码.rar
(80.05 KB, 下载次数: 48)
2016-4-6 15:25 上传
点击文件名下载附件
下载积分: 黑币 -5
主程序预览:
///
/// @file main.c
/// 系统主程序
///
///
///=====================================================================================
///
#define MAIN
#define AUTOCAL
#include "Liger.h"
#include "typemeter.h"
/**
* 系统默认校表参数
*
* Detailed description starts here.
* 该表记录的电能表的默认校准参数,但系统发生恢复参数失败或是第一次上电等
* 情况时,会从该表中恢复参数
*/
unsigned long code meterprm_table[]=
{ 0x00000000, //有功门限高1
0x5A55D125, //有功门限低1
0x00000000, //有功门限高2
0xA3E30760, //有功门限低2
0x0000001a, //有效值门限高1
0x67F16719, //有效值门限低1
0x0018F380, //启动门限1
0x0018F380, //启动门限2
0x022EA846, //有功功率比差1
0x022EA846, //有功功率比差2
0xFE75A15D, //U比差
0x10000000, //I1比差
0x10000000, //I2比差
0x00000000, //补偿1
0x00000000, //补偿2
0x05, //A通道角差校正
0x05, //B通道角差校正
0x00000000, //有功启动门限高位
0xB4ABA24A, //有功启动门限低位
0x00000001, //无功启动门限高位
0x47C60EC0 //无功启动门限低位
};
/**
* 根据所给的ID号从外部存储器中恢复数据项,恢复的数据会放在wr_buff中
* @param chk_id 数据项ID
* @return 1 成功
* 0 失败
//limin 修改 返回值恒定为0
*/
unsigned char recover_item(unsigned int chk_id)
{
unsigned char i,j,num,value,datanum;
value=0;
num=addr_from_coreID(1,chk_id);
for(i=0;i<num;i++)
{ if((*ID_coretalbpoint[i]).stortype==EEPROM)
{ data_addr.word[1]=(*ID_coretalbpoint[i]).dataaddr;
datanum=(*ID_coretalbpoint[i]).datalong;
Read_data(EEPROM,datanum);
wr_buff[datanum]=0;
for(j=0;j<datanum-1;j++) //校验和判断
{ wr_buff[datanum]+=wr_buff[j];
}
if(wr_buff[datanum]==(wr_buff[datanum-1]-0x33)) //如果校验和正确
{
if((*ID_coretalbpoint[i]).datatype==BCD)
{
if(check_X_bcd((datanum-1),wr_buff)==1) //BCD嘛校验
{
value=1; //检测到合法数据,放在wr_buff中
break;
}
}
else
{
value=1; //检测到合法数据,放在wr_buff中
break;
}
}
}
}
return value;
}
//===================================================================================
//函数功能:恢复第一个脉冲的门限
//
//=====================================================================================
void Recover_pd01(void)
{ unsigned char i,value;
Word32 read_buff;
//40 bit
for(i=0;i<2;i++) //门限值恢复
{
if(recover_item(0x8500+i)==1) //恢复参数正确
{ read_buff.lword=Longdate_from_xbcd(&wr_buff[1],4);
u8PMdatah=wr_buff[0];
u32PMdatal= read_buff.lword;
u8PMdatah=u8PMdatah<<1;
if((u32PMdatal&0x80000000)==0x80000000)
u8PMdatah|=0x01;
u32PMdatal=u32PMdatal<<1;
SetMeterCfg(0x10f4+i*6);
}
else //恢复参数失败
{ u8PMdatah=(uint8)meterprm_table[2*i];
u32PMdatal=meterprm_table[1+2*i];
u8PMdatah=u8PMdatah<<1;
if((u32PMdatal&0x80000000)==0x80000000)
u8PMdatah|=0x01;
u32PMdatal=u32PMdatal<<1;
SetMeterCfg(0x10f4+i*6);
}
}
for(i=0;i<2;i++)
{value=0;
ReadMeterPara(0x10f5+i*6);
if(recover_item(0x8503+i)==1) //防潜门限值设定
{ read_buff.lword=Longdate_from_xbcd(&wr_buff[0],4);
if(u32PMdatal!= read_buff.lword)
{ u32PMdatal= read_buff.lword;
value=1;
}
}
else //恢复参数失败
{ if(u32PMdatal!=meterprm_table[6+i])
{ u32PMdatal=meterprm_table[6+i];
value=1;
}
}
if(value==1)
{
u32PMdatal <<= 1;
SetMeterCfg(0x10f5+i*6);
}
}
}
//===================================================================
//函数功能:恢复第一个CF之后的门限值
//===================================================================
void Recover_pd(void)
{ unsigned char i,value;
Word32 read_buff;
for(i=0;i<2;i++) //门限值恢复
{ value=0;
ReadMeterPara(0x10f4+i*6);
if(recover_item(0x8500+i)==1) //恢复参数正确
{ read_buff.lword=Longdate_from_xbcd(&wr_buff[1],4);
if(u8PMdatah!=wr_buff[0])
{ u8PMdatah=wr_buff[0];
value=1;
}
if(u32PMdatal!=read_buff.lword)
{ u32PMdatal= read_buff.lword;
value=1;
}
}
else //恢复参数失败
{ if(u8PMdatah!=(uint8)meterprm_table[2*i])
{ u8PMdatah=(uint8)meterprm_table[2*i];
value=1;
}
if(u32PMdatal!=meterprm_table[1+2*i])
{ u32PMdatal=meterprm_table[1+2*i];
value=1;
}
}
if(value==1)
SetMeterCfg(0x10f4+i*6);
}
for(i=0;i<2;i++)
{ value=0;
ReadMeterPara(0x10f5+i*6);
if(recover_item(0x8503+i)==1) //防潜门限值设定
{ read_buff.lword=Longdate_from_xbcd(&wr_buff[0],4);
if(u32PMdatal!= read_buff.lword)
{ u32PMdatal= read_buff.lword;
value=1;
}
}
else //恢复参数失败
{ if(u32PMdatal!=meterprm_table[6+i])
{ u32PMdatal=meterprm_table[6+i];
value=1;
}
}
if(value==1)
{
SetMeterCfg(0x10f5+i*6);
}
}
}
//===============================================================================
//函数功能:恢复除门限值之外的参数
//================================================================================
void Recover_metprim(void)
{ uint8 i,value;
unsigned char xdata *point;
Word32 read_buff;
for(i=0;i<7;i++) //参数恢复
{ value=0;
ReadMeterPara(0x10dd+i*6);
if(recover_item(0x8505+i)==1) //恢复参数正确
{ read_buff.lword=Longdate_from_xbcd(&wr_buff[0],4);
if(u32PMdatal!=read_buff.lword)
{ u32PMdatal= read_buff.lword;
value=1;
}
}
else //恢复参数失败
{ if(u32PMdatal!=meterprm_table[8+i])
{ u32PMdatal=meterprm_table[8+i];
value=1;
}
}
if(value==1)
SetMeterCfg(0x10dd+i);
}
point=&PHCCtrl1;
for(i=0;i<2;i++) //角差值设定
{ if(recover_item(0x850e+i)==1)
{ if(*(point+i)!=wr_buff[0])
*(point+i)=wr_buff[0];
}
else //恢复参数失败
{ if(*(point+i)!=meterprm_table[15+i])
*(point+i)=meterprm_table[15+i];
}
}
}
/**
* 回复校表参数
* @param void
* @return void
*/
void Recover_meter(void)
{
Recover_pd01(); //恢复门限
Recover_metprim(); //恢复比差等其他参数
}
/**
* 初始化IO口
* @param void
* @return void
*/
void port_init(void)
{
P0OE = DISABLE_PORT_OUTPUT_ALL;
P1OE = DISABLE_PORT_OUTPUT_ALL;
P2OE = DISABLE_PORT_OUTPUT_ALL;
P3OE = DISABLE_PORT_OUTPUT_ALL;
P4OE = DISABLE_PORT_OUTPUT_ALL;
P5OE = DISABLE_PORT_OUTPUT_ALL;
P6OE = DISABLE_PORT_OUTPUT_ALL;
P7OE = DISABLE_PORT_OUTPUT_ALL;
P8OE = DISABLE_PORT_OUTPUT_ALL;
P0IE = DISABLE_PORT_INPUT_ALL;
P1IE = DISABLE_PORT_INPUT_ALL;
P2IE = DISABLE_PORT_INPUT_ALL;
P3IE = DISABLE_PORT_INPUT_ALL;
P4IE = DISABLE_PORT_INPUT_ALL;
P5IE = DISABLE_PORT_INPUT_ALL;
P6IE = DISABLE_PORT_INPUT_ALL;
P7IE = DISABLE_PORT_INPUT_ALL;
P8IE = DISABLE_PORT_INPUT_ALL;
P2OE&=(~BIT5); //输出使能
P2OD|=BIT5; //输出高电平
}
void IO_Sleep()
{
P0OE = DISABLE_PORT_OUTPUT_ALL;
P1OE = DISABLE_PORT_OUTPUT_ALL;
P2OE = DISABLE_PORT_OUTPUT_ALL;
P3OE = DISABLE_PORT_OUTPUT_ALL;
P4OE = DISABLE_PORT_OUTPUT_ALL;
P5OE = DISABLE_PORT_OUTPUT_ALL;
P6OE = DISABLE_PORT_OUTPUT_ALL;
P7OE = DISABLE_PORT_OUTPUT_ALL;
P8OE = DISABLE_PORT_OUTPUT_ALL;
P0IE = DISABLE_PORT_INPUT_ALL;
P1IE = DISABLE_PORT_INPUT_ALL;
P2IE = DISABLE_PORT_INPUT_ALL;
P3IE = DISABLE_PORT_INPUT_ALL;
P4IE = DISABLE_PORT_INPUT_ALL;
P5IE = DISABLE_PORT_INPUT_ALL;
P6IE = DISABLE_PORT_INPUT_ALL;
P7IE = DISABLE_PORT_INPUT_ALL;
P8IE = DISABLE_PORT_INPUT_ALL;
}
/**
* 初始化TIMER0,10ms中断一次
* @param void
* @return void
*/
void Init_Timer0(void)
{
TMOD = 0x01; // 工作在模式1
CKCON|=0x08; // clk
TL0 = 0xff; //10ms
TH0 = 0x7f;
TR0 = 1; // 开定时器0
SetInterrupt(1); //打开中断
}
/**
* 初始化ADC,设定当前的测量频率
* @param void
* @return void
*/
void Inti_anlmode(void)
{
InitAnalog(); //初始化模拟模块
SetADC(SETADC_IA,SETADC_CLOSE); //A通道电流关闭
SetADC(SETADC_IB,SETADC_IT16); //B通道电流,采用16倍增益
SetADC(SETADC_U,SETADC_IT1); //电压通道,采用1倍增益
SetMChannel(SETM_TEMP,SETM_T1); //开m通道,1倍增益,测量温度测量模式
Alt_50_60Hz(ALT_50HZ); //50hz
PowerDown=0;
}
/**
* 初始化计量系统
* @param void
* @return void
*/
void Inti_metermode(void)
{
SysCtrl&=0xef; //开启计量电路时钟
PMCtrl4=0x00;
PMCtrl1&=(~0xe0);
Inti_anlmode(); // AD增益
PMCtrl1=0x70; //选择B通道剂量
InitMeter(); //初始化计量电路
u32PMdatal=0x01;
SetMeterCfg(0x10f5); //潜动门限1
SetMeterCfg(0x10fb);
Recover_meter(); //恢复校表参数
PMCtrl1=0x7b; //使能U,B,UM通路,选择B路计量,使能角差校准
PMCtrl3=0x20; //一路有功计量,一路无功计量,开启次谐波滤波
PMCtrl4=0x20; //??????
CFCtrl=0x00; //用正反有功产生CF1
CFNumber=0;
CF1Number=0;
ULowFlag=0;
CF1Flag=0;
CFFlag=0xd5;
count_opencftime=100; //CF延时1妙打开
F_PmIdle = 0;
pmIdleCnt = 0;
}
/**
* 系统初始化,初始化模拟部分和数字部分寄存器
* @param void
* @return void
*/
void Init_System(void)
{
port_init(); //初始化io口
SetXRam(1); //开启对XRAM的写保护
Init_Timer0();
Inti_metermode();
}
/**
* 复位计量模块,当检测到计量有问题是会调用该函数
* @param void
* @return void
*/
void reset_primjiaobiao(void)
{
Inti_metermode(); //初始化计量模块
}
/**
* 检测CF脉冲是否有异常,通过将1s内产生的CF脉冲个数与门限CF脉冲个数比较,决定是否需要复位计量模块
* @param data_cf CF脉冲个数
* @return 0 脉冲个数异常
* data_cf 正常脉冲个数
*/
unsigned long check_jump(unsigned char data_cf)
{
unsigned long value;
if(data_cf>max_CF)
{
value=0; //停止能量计量
if(count_errenergmode<10)
{
count_errenergmode++;
reset_primjiaobiao(); //重新初始化计量模块
}
}
else
{
count_errenergmode=0;
value=data_cf;
}
return value;
}
/**
* 读取CF active energy 脉冲个数,累加脉冲
* @param void
* @return void
*/
/*
void read_encount(void)
{
unsigned char temp_CF1,temp_CF2,temp_data;
unsigned int Temp_CFNumber;
temp_data=PMCtrl4;
temp_CF1=0;
ReadMeterPara(0x10f2);
buffer_energ[0]=u32PMdatal;
ReadMeterPara(0x10f3); //读有功脉冲数
buffer_energ[2]=u32PMdatal;
if(buffer_energ[0]>buffer_energ[1]) //如果脉冲数有增加
{ temp_CF1=buffer_energ[0]-buffer_energ[1]; //计算增加的脉冲数
temp_CF1=check_jump(temp_CF1); //防飞走
}
if(buffer_energ[2]>buffer_energ[3])
{
temp_CF2=buffer_energ[2]-buffer_energ[3];
// temp_CF2=check_jump(temp_CF2); //防飞走
}
if(CFFlag==0x55)
{
if((temp_CF1!=0)||(temp_CF2!=0))
{
sumCF_Z=sumCF_Z+temp_CF1+temp_CF2; //能量脉冲累加
}
}
if(CFFlag==0xd5)
{
if((temp_CF1==1)||(temp_CF2==1))
{
sumCF_Z=sumCF_Z+temp_CF1+temp_CF2+1;
CFFlag=0x55;
}
}
buffer_energ[1]=buffer_energ[0];
buffer_energ[3]=buffer_energ[2];
ReadMeterPara(0x10f2);
Temp_CFNumber=u32PMdatal;
if(Temp_CFNumber>0xf000)
{
buffer_energ[1]=0;
u32PMdatal=0;
SetMeterCfg(0x10f2);
}
ReadMeterPara(0x10f3);
Temp_CFNumber=u32PMdatal;
if(Temp_CFNumber>0xf000)
{
buffer_energ[3]=0;
u32PMdatal=0;
SetMeterCfg(0x10f3);
}
}
*/
/**
* 恢复电量整数部分,3字节
* @param rec_id 电量整数部分的ID
* @return void
*/
void Recover_int(unsigned int rec_id)
{
check_engint(rec_id);
}
/**
* 恢复电量小数部分,在存放小数的时候,每走1万度存放的位置向后移动一个字节
* @param void
* @return void
*/
void Recover_dot(unsigned int dotaddress,unsigned int ID)
{
unsigned int temp_addr;
addr_baseonIDandtype(RAM,ID);
temp_addr=(*ID_coretalbpoint[0]).dataaddr;
temp_addr=(ram[temp_addr]&0x0f);
data_addr.lword=dotaddress+temp_addr;
Read_data(EEPROM,1);
if(checkone_bcd(wr_buff[0])==0)
{
Read_data(EEPROM,1);
if(checkone_bcd(wr_buff[0])==0)
wr_buff[0]=0;
}
addr_baseonIDandtype(RAM,ID);
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr+3;
Write_data(RAM,1);
}
//=========================================================
//函数功能:恢复电量数据
//=========================================================
void Recover_eng(void)
{
Recover_int(ID_POSENGSUM); //恢复组合电量整数部分
Recover_dot(EEP_Save_engdot,ID_POSENGSUM); //恢复组合电量小数部分
Recover_int(0x0200); //正向
Recover_dot(EEP_Save_engdotZ,0x0200);
Recover_int(0x0300); //反向
Recover_dot(EEP_Save_engdotF,0x0300);
}
/**
* 恢复电能表的参数,如果读取外部存储器失败,将默认的参数写入存储器
* @param void
* @return void
*/
void Recover_prim(void)
{
unsigned char i,len;
wr_buff[0]=0;
wr_buff[1]=0x12; //默认为1200
wr_buff[2]=0;
addr_baseonIDandtype(RAM,ID_CHANGSHU);
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
Write_data(RAM,(*ID_coretalbpoint[0]).datalong);
if(recover_item(ID_BANTRATA)==0) //如果恢复波特率出错
{
wr_buff[0]=0x08; //默认参数2400
}
addr_baseonIDandtype(RAM,ID_BANTRATA);
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
Write_data(RAM,(*ID_coretalbpoint[0]).datalong);
if(recover_item(ID_COMADDR)==0) //恢复表地址错误
{
for(i=0;i<6;i++)
wr_buff[i]=0x11;
}
addr_baseonIDandtype(RAM,ID_COMADDR);
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
len=(*ID_coretalbpoint[0]).datalong;
Write_data(RAM,len);
if(recover_item(0x8400)==0) //恢复表号错误0000001
{ for(i=0;i<5;i++)
wr_buff[i]=0;
wr_buff[5]=0x01;
}
addr_baseonIDandtype(RAM,0x8400);
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
len=(*ID_coretalbpoint[0]).datalong;
Write_data(RAM,len);
}
/**
* 恢复CF脉冲余量
* @param void
* @return void
*/
void Recover_tindiandata(void)
{
data_addr.word[1]=EEP_Save_cf; //CF 恢复
Read_data(EEPROM,2);
if(wr_buff[1]==(wr_buff[0]+0x33))
{ if(wr_buff[0]>128)
wr_buff[0]=0;
}
else
wr_buff[0]=0;
sumCF=wr_buff[0];
}
/*
void RTCIOOff()
{
CfgPort(4,0);
P1ID&=~(BIT0);
P1OE|=BIT0;
P1IE&=~(BIT0);
}
*/
//==================================================
//函数功能:恢复数据
//备注:
//===================================================
void Recover_data(void)
{
Recover_eng(); //恢复电量
Recover_tindiandata(); //恢复停电时保存的数据
Recover_prim(); //恢复参数
}
/**
* 检测当前的供电模式
* @param void
* @return 1 市电供电
* 0 电池供电
*/
unsigned char check_powertype(void)
{
unsigned char value;
if((Systate&0x01)==0x01)
value=1; //正常供电
else
{
if((Systate&0x01)==0x01)
value=1;
else
value=0;
}
return value;
}
/**
* 初始化系统各个模块
* @param void
* @return void
*/
void Init_modul(void)
{
Init_disp(); //初始化显示模块
init_RTCmode(); //初始化RTC模块
int_energeadd(); //初始化能量计量模块
Init_checkmode(); //初始化check模块
init_485comm(); //初始化485模块
InitInfrComm(); //初始化红外模块
Initcommu(); //初始化通讯驱动
Init_Mchannel(); //初始化M通道
SysInitAutoCal(); //初始化自动校
}
/**
* 初始化停电模块
* @param void
* @return void
*/
void ini_sleepmode(void)
{ CfgInterrupt(0); //关所有中断
EA=0; //关总中断
// time_jihuo=0;
// time_lostiv=0;
// CfgPort(4,0); //秒脉冲输出打开
port_init(); //禁止IO口输入输出
}
/**
* 停电初始化
* @param void
* @return void
*/
//void Init_jihuo(void)
//{
// Init_disp(); //初始化显示模块
// sta_meterrun=5; //激活模式
// time_jihuo=0;
//}
/**
* 停电保存各类数据,备注:包括:电量小数,CF脉冲位数,当月平均功率因数、停电时间
* @param void
* @return void
*/
void savedata_tingdian(void)
{
//======================================================================CF
wr_buff[0]=sumCF;
wr_buff[1]=wr_buff[0]+0x33;
data_addr.word[1]=EEP_Save_cf;
Write_data(EEPROM,2);
}
/**
* 开启CF脉冲输出
* @param void
* @return void
*/
void Open_CF(void)
{
unsigned char i;
if(count_opencftime==0)
{ i=PMCtrl4;
if((i&0x18)!=0x18) //如果cf没有开
{
i=PMCtrl4;
if((i&0x18)!=0x18)
{ i|=0x18; //开CF
PMCtrl4=i;
SetInterrupt(14); //开CF1中断
}
}
}
if(ULowFlag==0)
{ if(CFNumber>=1)
{ ULowFlag=1;
Recover_pd(); //第一个脉冲之后,恢复正常门限值
}
}
}
//计量防潜动 判断
void pm_Idle(void)
{
unsigned int temp_int;
unsigned long xdata temp;
//if((PMCtrl4&0x18)==0)
// return;
//--------------------------获取脉冲常数
addr_baseonIDandtype(RAM,ID_CHANGSHU); //获取脉冲常数指针
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
Read_data((*ID_coretalbpoint[0]).stortype,(*ID_coretalbpoint[0]).datalong);
temp_int=value_hex_from_2bcd(&wr_buff[1]);
if((temp_int>12800)||(temp_int<200)) //脉冲常数是否异常
temp_int=1200;
///计算0.4%IB启动电流时的功率
temp=meterprm_table[1];
temp >>= 11;
temp |= (meterprm_table[0]<<21);
temp *= type_Ib;
temp /= 2250;
temp *= temp_int;
temp *= type_volit; //220V x 10A /100
temp /= 312500;
ReadMeterPara(DATAP);
if(u32PMdatal&0x80000000)
u32PMdatal = (~u32PMdatal) +1;
if(u32PMdatal>=((temp*6)/10) ) //加启动电流时的功率的 60%
{
if(F_PmIdle)
{
if(pmIdleCnt<5)
pmIdleCnt++;
else
{
F_PmIdle = 0;
pmIdleCnt = 0;
PMCtrl4 &= ~BIT5; //关闭防潜功能, 复位防潜能量桶
PMCtrl4 |= BIT5; //开启防潜,重新进行防潜计算
}
}
else
pmIdleCnt = 0;
}
else if(u32PMdatal<= ((temp*3)/10) ) //加启动电流时的功率的 30%
{
if(!F_PmIdle)
{
if(pmIdleCnt<5)
pmIdleCnt++;
else
{
F_PmIdle = 1;
pmIdleCnt = 0;
}
}
else
pmIdleCnt = 0;
}
}
/**
* 流程描述
*
* 主程序根据系统状态寄存器的状态来判断当前是执行哪类操作
* RTC 唤醒 (BIT2) 快速休眠(注意快速休眠必须配合PLL快速流程,不然无法休眠)
* 看门狗复位(BIT4) 恢复系统状态
* IO口复位(BIT3) 更新显示
* 正常上电(BIT0) 正常上电流程
*/
void main(void)
{ uint8 dispflashtime,waketime;
jumpsta:
F0=1;
CLKFRQ=1;
SPCFNC=0x01;
XBYTE [0x8002] = 0x86;
SPCFNC=0x00;
SetMeterFunc(0); //关CF输出
if(Systate & BIT2) // rtc reset
{ CtrlMEAS = 0x80; //关LDO33
if(sta_meterrun==run_sleepdisp) //程序在停电显示模式
{ waketime=0;
dispflashtime++;
if(dispflashtime==5)
{ Disp_close();
}
else if(dispflashtime==10)
{ if(BatteryInfo==1)
Disp_err1(); //显示err1
else
Disp_oninsleep(); //显示电量
}
else if(dispflashtime==15)
{ Disp_close();
}
else if(dispflashtime>19)
{ dispflashtime=0;
Disp_oninsleep(); //显示电量
}
if(save_lastday!=RTCHC)
{ save_lastday=RTCHC;
times_cutpower++;
if(times_cutpower>TIMDISOCUTP) //显示7天,超过7点则进入休眠模式
{ times_cutpower=0;
CloseLCD();
sta_meterrun=run_sleep; //进入睡眠模式
waketime=3; //一天唤醒一次
}
}
}
else
waketime=3;
CfgRTC(0,waketime); //32768,定时唤醒
if(check_powertype()==1)
{ ClearWDT();
goto jumprun;
}
Sleep();
if(check_powertype()==1)
{ ClearWDT();
goto jumprun;
}
}
#ifdef DEBUG
#else
else if(Systate & BIT4)
{ SetPLL(SETPLL_3_2M); //开启pll
Init_System();
Recover_data(); //恢复数据 re
Init_modul();
EA = 1; //开总中断
ClearWDT();
}
#endif
else if(Systate & BIT3) // io reset
{if(check_powertype()==1)
{ ClearWDT();
goto jumprun;
}
Sleep();
}
else // 正常上电复位
{
jumprun:
SetPLL(SETPLL_3_2M); //开启pll
Init_System();
Recover_data(); //恢复数据
Init_modul();
EA = 1; //开总中断
ClearWDT();
}
/**
* 正常运行部分,该部分中,系统反复执行以下流程
* RTC时钟刷新模块
* 计量模块CF打开
*
*/
run_zhengchang:
while(check_powertype()==1) //市电供电
{
PowerDown=0;
ClearWDT(); //喂狗
if(check_powertype()==0)
break;
Rtc_refreshmode(); //时钟刷新
if(check_powertype()==0)
break;
commu_mode(); //通讯模块
if(check_powertype()==0)
break;
Open_CF();
if(check_powertype()==0)
break;
display_mode(); //显示模块
if(check_powertype()==0)
break;
energ_addmode(); //能量计量模块
if(check_powertype()==0)
break;
check_mode(); //自检模块
if(check_powertype()==0)
break;
Mchannelmode(); //M通道测量
}
//==============================================================================================停电处理部分
if(check_powertype()== 0) //电池供电
{ while(1)
{ if(check_powertype()==1)
{ ClearWDT();
PowerDown=0;
goto run_zhengchang;
}
else
{ PowerDown++;
delay_1ms();
ClearWDT();
if(PowerDown>3)
goto xiumian;
}
}
xiumian:
savedata_tingdian(); //停电保存数据
ClearWDT();
CfgRTC(0,0); //32768,1秒唤醒
ini_sleepmode(); //初始化停电模式
IO_Sleep();
times_cutpower=0; //停电计时器
dispflashtime=0; //闪烁时间
Ini_sleepdisp();
if(check_powertype()==1)
{ ClearWDT();
goto jumpsta;
}
sta_meterrun=run_sleepdisp; //程序进入停电显示模式
Sleep();
}
else
goto run_zhengchang;
}
//=========================================================================================停电激活
#undef AUTOCAL
#undef MAIN
复制代码
作者:
从头再来1
时间:
2016-4-3 10:40
你好,能够把源码发给我学习一下,可以吗?谢谢!!!
作者:
admin
时间:
2016-4-3 13:08
卖源码,请到供求信息发布去
作者:
小小号
时间:
2017-7-1 10:51
楼主,有没有更详细的电能表设计方案
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1