單相飛控智能電表源碼,單相多功能電能表源碼。電能計量,485通訊,總線通訊,液晶顯示等功能
全部源碼下載:
單相多功能電能表源碼.rar
(80.05 KB, 下載次數: 48)
2016-4-6 15:25 上傳
點擊文件名下載附件
主程序預覽:
- ///
- /// @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
復制代碼
|