📄 main.c
字号:
/*************************************************************************************
文件类型:
文件作用:
修改权限:
文件相关:
创 建 人:GeminiKQ
创建日期:2006.12.20
当前版本:Ver0.1
版本信息:Ver0.1 GeminiKQ
**************************************************************************************/
#define MAIN
#include "Tiger.h"
#include "typemeter.h"
//==================================================================
//系统默认较表参数
//==================================================================
unsigned long code meterprm_table[]=
{ 0x00000000, // 有功门限高
0xF2ED9618, // 有功门限低
0x00000000, // 有效值门限高
0x00654FD6, // 有效值门限低
0xffffffff, // 启动门限值高
0xffffffff, // 启动门限值低
0x010CA23A, // IA有效值比差
0x01609618, // IB有效值比差
0x00000000, // LA有效值比差
0x00000000, // LB有效值比差
0x00000000, // M有效值比差
0x00000000, // M有效值比差
0x00000000, // M有效值比差
0xFCCD0213, // PA比差
0xF37D0381, // PB比差
0xF4DB1D71 // 电压比差
};
//=========================================================================
//函数功能:通过入口ID号恢复各参数项 (数据存放在EEPROM中)
//入口参数:ID号
//返回参数:1:成功,0:失败 数据放在wr_buff中
//=========================================================================
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) // EEP中
{ data_addr.word[1]=(*ID_coretalbpoint[i]).dataaddr; // 取地址
datanum=(*ID_coretalbpoint[i]).datalong; // 要读的数据个数
Read_data(EEPROM,datanum); // 读函数
wr_buff[datanum]=0; // 读出的数据放在wr_buff[0]--wr_buff[datanum-1]中
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;
}
//================================================================
// 函数功能:从EEPROM中恢复meterprm_table[]表参数
// 如果恢复成功则返回,不成功,则加载meterprm_table[]表
//================================================================
void Recover_meter(void)
{ uint8 i;
Word32 read_buff;
for(i=0;i<16;i++)
{ if(recover_item(0x8500+i)==1) // 恢复系统参数正确(见meterprm_table[]表)
{ read_buff.lword=ReadMeterPara(i+18);
if(compare_x_byte(&read_buff.byte[0],wr_buff,4)==1) //与寄存器中参数比较,不同则写参数
{ read_buff.lword=Longdate_from_xbcd(wr_buff,4);
SetMeterCfg(read_buff.lword,(18+i));
}
}
else //恢复参数失败
{ read_buff.lword=ReadMeterPara(i+18);
if(read_buff.lword!=meterprm_table[i]) //与寄存器中参数比较,不同则写参数
{ read_buff.lword=meterprm_table[i];
SetMeterCfg(read_buff.lword,(18+i));
}
}
}
}
//==========================================
// 函数功能:禁止所有IO口的输入输出
//==========================================
void port_init(void)
{
// P1OE &= ~BIT0;
// P10FS = 0x01; //select second pluss output
P0OE = 0;
P1OE = 0;
P2OE = 0;
P3OE = 0xff;
P4OE = 0xff;
P5OE = 0xff;
P6OE = 0xff;
P0IE = 0;
P1IE = 0;
P2IE = 0;
P3IE = 0;
P4IE = 0;
P5IE = 0;
P6IE = 0;
}
//=================================================
// 函数功能: 初始化Timer0
//
//=================================================
void Init_Timer0(void)
{
TMOD = 0x01; // 工作在模式1
CKCON|=0x08; // clk/4
TL0 = 0xff; // 10ms
TH0 = 0xdf;
TR0 = 1; // 开定时器0
SetInterrupt(1); // 打开中断
}
//===========================================================
// 函数功能:初始化模拟部分
//
//===========================================================
void Inti_anlmode(void)
{ SetADC(1,8); //A通道电流,采用8倍增益
SetADC(2,8); //B通道电流,采用8倍增益
SetADC(3,8); //电压通道,采用8倍增益
SetMChannel(0,0); //关m通道
SetFrq(1); //60hz
}
//===============================================
// 函数功能:初始化计量系统
//
//===============================================
void Inti_metermode(void)
{
Inti_anlmode(); // AD增益
SetMeterFunc(0x80); // 关闭所有计量通道,关CF输出,开启启动潜动功能
SetMeterCfg(0xffffffff,22); //潜动门限高位
SetMeterCfg(0xffffffff,23); //潜动门限低位
InitMeter(); //初始化计量电路
Recover_meter(); //恢复校表参数
SetMeterFunc(0x8f); //开启电压和A通道计量,A通道输出,能量输出模式
count_opencftime=3; //CF延时3妙打开
}
//==========================================
// 函数功能:系统初始化,
// 备注:初始化模拟部分和数字部分寄存器
//===========================================
void Init_System(void)
{ battest=0; // 清电池欠压标志
// SetPLL(1);
port_init(); // 初始化io口
SetXRam(0); // 开启对XRAM的写保护
// Init_eeprom(); // 初始化EEPROM 上电误操作
Init_Timer0();
Inti_metermode();
OpenPDT(); // 打开调电检测功能
}
//======================================================
// 函数功能:复位计量模块
//
//======================================================
void reset_primjiaobiao(void)
{
Inti_metermode(); //初始化计量模块
buffer_energ[0]=0;
buffer_energ[1]=0;
}
//=====================================================
// 函数功能:检测CF脉冲是否异常
// 入口参数:CF脉冲数
// 返回数据:修正后的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脉冲
//===========================================================================
void read_encount(void)
{ unsigned char temp_CF,temp_data;
temp_data=ReadMeterFunc();
if((temp_data&0x40)!=0x40)
buffer_energ[0]=ReadMeterPara(12)+ReadMeterPara(9); //读有功脉冲数
else
buffer_energ[0]=ReadMeterPara(15);
if(buffer_energ[0]>buffer_energ[1]) // 如果脉冲数有增加
{ temp_CF=buffer_energ[0]-buffer_energ[1]; // 计算增加的脉冲数
temp_CF=check_jump(temp_CF); // 防飞走
sumCF_Z=sumCF_Z+temp_CF; // 能量脉冲累加
//qidong_time=0;
}
buffer_energ[1]=buffer_energ[0];
}
//==============================================================
//函数功能:恢复电量的整数部分,3个字节
//===============================================================
void Recover_int(unsigned int rec_id)
{
check_engint(rec_id); // 调用在 energradd.c 中
}
//-----------------------------------------------------
//函数功能:恢复电量数据
//备注:
//----------------------------------------------------
void Recover_eng(void)
{
Recover_int(ID_POSENGSUM); // ID_POSENGSUM 当前有功总电量ID号=0x0100
}
//======================================================
//函数功能:恢复参数
// 恢复的数据都在RAM中,恢复错误,则,中心设置
//======================================================
void Recover_prim(void)
{unsigned char i,len;
if(recover_item(ID_CHANGSHU)==0) // 如果脉冲常数恢复错误
{ wr_buff[0]=0;
wr_buff[1]=0x4; // 默认为400
wr_buff[2]=0;
} // 存放RAM地址 0x40
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]=01; // 默认参数1200
}
addr_baseonIDandtype(RAM,ID_BANTRATA); // 存放RAM地址 0x43
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]=0;
}
addr_baseonIDandtype(RAM,ID_COMADDR); // 存放RAM地址 0x44
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
len=(*ID_coretalbpoint[0]).datalong;
Write_data(RAM,len);
if(recover_item(ID_TIMERETUN)==0) //轮显时间
{
wr_buff[0]=5; //5秒
}
addr_baseonIDandtype(RAM,ID_TIMERETUN); // 存放RAM地址 0x50
data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
len=(*ID_coretalbpoint[0]).datalong;
Write_data(RAM,len);
}
//=============================================================
//函数功能:恢复停电时保存的数据
// 要恢复的数据都存放在EEPROM中
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -