📄 att7027.c
字号:
#include <ATT7027.H>
#include <MAIN.H>
// #include <stddef.h>
void Flash_Write_ATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n);
void Flash_Read_ATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n);
void WriteCALATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n);
void ReadATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n);
void ReadCALATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n);
void EMU_Parameter_change1();
/*******************************************************************
写FLASH数据
函数原型: void Flash_Write_ATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n)
功能: 将要写的数据写到FLASH中
输入: addr 地址,n个数,mt_data存放RAM的指针
输出:
********************************************************************/
void Flash_Write_ATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n)
{
unsigned char i,ADDRL,ADDRH,TEMP;
CFMCFG|=0x04;// 允许系统调用
for(i=0;i<n;i++)
{
ADDRL=addr;
ADDRH=addr>>4;
TEMP=*mt_data;
BWPR=0xC3;//使能写PMOD[1:0]操作
BWPR=0x9B;//开启所有受保护位的写使能
/* #pragma asm
MOV R6,ADDRH //指定要擦除的页的高地址
MOV R7,ADDRL //指定要擦除的页的低地址
MOV R3,1 //指定要擦除DATA FLASH
LCALL 0FFD7H
MOV DPTRH0,ADDLH
MOV DPTRL0,ADDRL
MOV A,TEMP;
LCALL 0FFD9H
#pragma endasm */
addr=addr+1;
mt_data=mt_data+1;
}
}
/*******************************************************************
读FLASH数据
函数原型:void Flash_Read_ATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n)
功能: 读FLASH数据放到mt_data指针指向要存放的地址中
输入: addr子地址,n个数,*mt_data要存放的指针
输出:
********************************************************************/
void Flash_Read_ATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
{
*mt_data=CBYTE[addr];
addr=addr+1;
mt_data=mt_data+1;
}
}
/****************************************************************************
写数据到校表寄存器中
函数原型:void WriteCALATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n)
功能: 数据放到mt_data指针指向要存放的地址中
输入: addr子地址,n个数,*mt_data要存放的指针
输出 comm:the val which written to the registers.
writes Calibration registers at att7027 addr:the address of the first register.
******************************************************************************/
void WriteCALATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n)
{
unsigned char i,delay;
EPADR=0xA6;//ECR writes Calibration registers寄存器写保护使能
for(i=0;i<n;i++)
{
ECADR=addr; //write address
delay=10;
while(delay>0) delay--; // wait 4.8us
ECDATH=*(mt_data+2*i);//写入数据的高8位如果单字节数据可以忽略此操作
ECDATL=*(mt_data+1+2*i);//写入数据的低8位
addr=addr+1; //下一个校表参数
}
EPADR=0xA9; //ECR writes Calibration registers寄存器写保护禁止
}
/***********************************************************************
读电表寄存器数据
函数原型:void ReadATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n)
功能: 读电表寄存器数据放到mt_data指针指向要存放的地址中
输入: addr子地址,n个数,*mt_data要存放的指针
输出: This subroutine functions as reading n*bits registers from att7027.
Considering the compatibilities, reading the 24bits register as
3*8bits, and reads 8bits once.
***********************************************************************/
void ReadATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n)//*mt_data=xxxxxx00 n=3
{
unsigned char delay,i=0;
for(i=0;i<n;i++)
{
EPADR=addr; //write address
delay=10;
while(delay>0) delay--; // wait 4.8us
*(mt_data+3*i)=0;
*(mt_data+1+3*i)=EPDATH;//读数据的高位如果寄存器为2字节,EPDATH 为符号扩展位
*(mt_data+2+3*i)=EPDATM;//读数据的中间8位
*(mt_data+3+3*i)=EPDATL;//读数据的低8位
addr=addr+1;
}
}
/****************************************************************************
读电表校验寄存器数据
函数原型:void ReadCALATT7027(unsigned int addr,unsigned char *mt_data,unsigned char n)
功能: 读电表校验寄存器数据放到mt_data指针指向要存放的地址中
输入: addr子地址,n个数,*mt_data要存放的指针
Read Calibration registers at att7027
addr:the address of the first register.
comm:the val which written to the registers.
******************************************************************************/
void ReadCALATT7027(unsigned char addr,unsigned char *mt_data,unsigned char n)//*mt_data=xxxxxx00 n=3
{
unsigned char delay,i=0;
for(i=0;i<n;i++)
{
EPADR=addr; //write address
delay=10;
while(delay>0) delay--; // wait 4.8us
*(mt_data+2*i)=ECDATH;//读数据的高8位如果单字节数据可以忽略此操作
*(mt_data+1+2*i)=ECDATL;//读数据的低8位
addr=addr+1; //下一个校表参数
}
}
/****************************************************************************
电表寄存器经过转变为实际数据
函数原型:void EMU_Parameter_change1()
功能: 电表寄存器经过转变为实际数据
输入:
Read Calibration registers at att7027
addr:the address of the first register.
comm:the val which written to the registers.
******************************************************************************/
void EMU_Parameter_change1()
{
unsigned char i;
unsigned long *PA1,*PA2;
unsigned long tempA;
ReadATT7027(0,(unsigned char*)Emu_Parameter.Current_Waveform_Spl_I1,sizeof(Emu_Parameter));//SIZE_OF(Emu_Parameter,Current_Waveform_Spl_I1)Emu_Parameter_change
PA1=&(Emu_Parameter.Current_Waveform_Spl_I1);
// *temp1= SIZE_OF(EEPROM_DATA,Apparent_Power_Gain_GS2);
//*temp1= sizeof(Emu_Parameter.Current_Waveform_Spl_I1);
//*temp1= SIZE_OF(Emu_Parameter.Current_Waveform_Spl_I1);
PA2=&(Emu_Parameter_change.Current_Waveform_Spl_I1);
for(i=0;i<3;i++)// Current_Waveform_Spl_I1 Current_Waveform_Spl_I2 Voltage Waveform_Spl_U;
{
if((*PA1)>=0x8000) //2^15
*PA2=(0x10000-(*PA1)); //2^16
else *PA2=*PA1;
PA1=PA1+1;
PA2=PA2+1;
}
for(i=0;i<3;i++)// Active_Power_Waveform_Spl_P
{ //Reactive_Power_Waveform_Spl_Q Apparent Power Waveform_Spl_S ;
if((*PA1)>=0x800000) //2^23
*PA2=(0x1000000-(*PA1)); //2^24
else *PA2=*PA1;
PA1=PA1+1;
PA2=PA2+1;
}
for(i=0;i<3;i++)//Current_Rms_I1 Current_Rms_I2 Current_Rms_U;
{
tempA=(*(unsigned long*)&Emu_Parameter_change.EMU_Krms_Rms[i])>>16;
*PA2=((*PA1)*tempA);//Kp=5/234880*001000=2.1287466×10^(-4)
// PA=Emu_Parameter_change.EMU_Krms_Rms[i];
PA1=PA1+1;
PA2=PA2+1;
}
*PA2=(5529600/6/(*PA1))<<8; //femu =5529600Hz f=femu/6/UFREQ Current_Freq_U;
PA1=PA1+1;
PA2=PA2+1;
for(i=0;i<3;i++)// Active_Power_P Reactive_Power_Q Apparent_Power_S;
{
if((*PA1)>=0x800000) //2^23
*PA1=0x1000000-(*PA1); //2^24
tempA=*(unsigned long*)&Emu_Parameter_change.EMU_Krms_Kpqs[i]>>16;//Kpqs=1000/51673=0.01935
//*temp2=(*temp1)*(*tempA);//P=Kpqs*Preg=0.01935*(-47820)= -925.3 w
*PA2=((*PA1)*(tempA));
PA1=PA1+1;
PA2=PA2+1;
}
for(i=0;i<3;i++)// Active_Energy_P Reactive_Energy Apparent_Energy_S;
{
tempA=*(unsigned long*)meter_para.MeterConstantReal;
*PA2=((*PA1)/(tempA));
PA1=PA1+1;
PA2=PA2+1;
}
}
/****************************************************************************
电表通过RS485communicate进行校表
函数原型:void Calibration_meter(void)
功能: 读RS485communicate数据放到mt_data指针指向电表校验寄存器要存放的地址中
输入:
Read Calibration registers at att7027
addr:the address of the first register.
comm:the val which written to the registers.
******************************************************************************/
void Calibration_meter(void)
{
//unsigned char data_id;
//unsigned char cali_data[3];
/* data_id=rxdatabuffer[10];
//较表写命令
if((data_id>=0x41)&&(data_id<=0x48)||(data_id>=0x4A)&&(data_id<=0x4F))
{
cali_data[0]=rxdatabuffer[11];
cali_data[1]=rxdatabuffer[12];
// cali_data Data_ID write ram and ATT7027
WriteCALATT7027(data_id,&cali_data[0],2)
Write_EEPROM(2,&cali_data[0],(0x40+(data_id-1)*2));
}
//较表读电压电流
else if((data_id==0x0F)||(data_id==0x10))
{
rxdatabuffer[9]=6;
rxdatabuffer[8]+=0x40;
//返回数据在10-15
if(data_id==0x0F)
{
rxdatabuffer[10]=*((unsigned char *)&Emu_Parameter.Current_Rms_I1+2);
rxdatabuffer[11]=*((unsigned char *)&Emu_Parameter.Current_Rms_I1+3);
}
else if(data_id==0x10)
{
rxdatabuffer[10]=*((unsigned char *)&Emu_Parameter.Current_Rms_I2+2);
rxdatabuffer[11]=*((unsigned char *)&Emu_Parameter.Current_Rms_I2+3);
}
else
{
rxdatabuffer[10]=*((unsigned char *)&Emu_Parameter.Current_Rms_U+2);
rxdatabuffer[11]=*((unsigned char *)&Emu_Parameter.Current_Rms_U+3);
}
}
//错误命令回错误应答
else
{
rxdatabuffer[9]=1;
rxdatabuffer[8]+=0x40;
}
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -