单相飞控智能电表源码,单相多功能电能表源码。电能计量,485通讯,总线通讯,液晶显示等功能
全部源码下载:
单相多功能电能表源码.rar
(80.05 KB, 下载次数: 47)
主程序预览:
- ///
- /// @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
复制代码
|