http://www.docin.com/p-776411237.html
#include
#include"I2C.h"
#include
//#include
#include
#include
#include"struct.h"
#define zhilu 0
uchar code TAB0[]="Voltage:";
uchar code TAB1[]="Current:";
uchar code TAB2[]="Power:";
/*sbit SDI0_5460 = P0^2; //040 输出,5460A 输入
sbit SCK0_5460 = P0^1; //支路号 0
sbit SDO0_5460 = P0^0; //040 输入,5460A 输出*/
sbit SDI0_5460 = P0^3;
sbit SDO0_5460 = P0^1;
sbit SCK0_5460 = P0^5;
sbit CS_5460 = P0^4;
/***************************************全局变量定义
**************************************/
unsigned char rec_data[3] = {0};
unsigned char send_data[3] = {0};
unsigned char VOLT_AC_OFF_CONFIG[4];
unsigned char VOLT_RMS[4],I_RMS[4],I_RMS_OFFSET[4];
unsigned char U_RMS_GAIN[4],I_RMS_OFFSET_1[4];
unsigned int flag1,time;
unsigned int count1;
//标志位 flag,定时时间到标志 time
unsigned char IIC_DATA;
//24C16 存储数
据
unsigned char add_II_count,add_UU_count,add_PW_count;
unsigned int PW_INT[3];
unsigned char UU_COUNT;
unsigned char UU_REC_COUNT;
unsigned int UU_RMS_SAVE;
unsigned char UU_MAX;
unsigned char UU_MIN;
unsigned int i;
unsigned int UU_RMS;
unsigned int II_RMS;
unsigned char PEAK; //峰值系数
unsigned char status_data[3]={0};
unsigned int status_high8;
//unsigned char U_real[3],I_real[3],PW_real[3];
//unsigned char zhilu;//支路号
float PW_float;//功率值真实数据(浮点数)
float II_float;//电流值真实数据
float UU_float;//电压值真实数据
float PEAK_float;//峰值系数真实数据
unsigned char buf;
unsigned char tt;
bit time2;
void main()
{
flag1 = 0;
time = 0;
IIC_DATA = 0;
//定时变量
//定时变量
//存储器变量
add_II_count=0;
//存储电量的地址
add_UU_count=0;
add_PW_count=0;
count1 = 0;
//发送报文计数
UU_COUNT=0;
UU_REC_COUNT=0;
status_high8=0;
for(i=0;i<3;i++)
{
rec_data =0;
send_data=0;
//***************初始化接收和发送数组*********************//
}
CS_5460=0;
cs5460a_init();
//0支路初始化
//*****************************定时器
1***********************************//
载
工作方式0,16位定时器
TMOD=0x21;
TH1=0xFA;
TL1=0xFA;
//工作方式1,8位定时器自动重装
//波特率9600bit/s
TH0
TL0
=0x3c;
=0xb0;
//串口在工作方式1
SM0=0;
SM1=1;
PCON=0x80;//SMOD=1
TR0=1;
TR1=1;
REN=1;
ET0=1;
EA=1;
ES=1;
//串口中断允许
RI=0;
delay_ms(10);
//
//定时器0允许
//接收允许
//允许定时器0中断
/***初始化完毕后,电流、电压有效值需要空读一次**
Wait_DRDY_High(zhilu);
cs5460_READ(zhilu,0x16);
Clear_DRDY(zhilu);
Wait_DRDY_High(zhilu);
cs5460_READ(zhilu,0x18);
Clear_DRDY(zhilu);
*/
//jiaozhun();
//CS5460A校准函数
while(1)
{
if(time2==1)
{
time2=0;
//
待电压转换完成
//
周期电压有效值
//
//
Wait_DRDY_High();
cs5460_READ(0x18);
//00011000 地址12
inode[zhilu].UU[0]=rec_data[0];
_delay_us(10);
//等
//上一
ES=0;
SBUF=P0;
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].UU[0];
//SBUF=0x10;
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].UU[1];
//SBUF=0x10;
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].UU[2];
//SBUF=0x10;
while(!TI);
TI=0;
_delay_us(10);
_delay_us(100);
SBUF=inode[zhilu].II[0];
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].II[1];
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].II[2];
while(!TI);
TI=0;
_delay_us(10);
_delay_us(100);
SBUF=inode[zhilu].PW[0];
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].PW[1];
while(!TI);
TI=0;
_delay_us(10);
SBUF=inode[zhilu].PW[2];
while(!TI);
TI=0;
_delay_us(10);
ES=1;
_delay_us(10);
//打开串口中断
}
}
}
/**********************************************************
************
*CS5460A初始化函数
***********************************************************
***********/
voidcs5460a_init()
{
write_command(0xff);
write_command(0xff);
write_command(0xff);
write_command(0xfe);
//sys1
//sys1
//sys1
//sys0
/*************后续的*****************/
//配置寄存器
cs5460_write(0x40);
send_data[0]=0x00;//增益为Gi=10
// send_data[0]=0x01;//增益为Gi=50
send_data[1]=0x00;
// send_data[2]=0x61;//打开电流、电压滤波器,
send_data[2]=0xe1;//打开电流、电压滤波器
//采样数据稳定关键:
//
send_data[2]=0x01; //关闭电流、电压滤波器
/*
send_data[0]=0xff;//写数据3,16~23位,高字节
send_data[1]=0xff;//写数据2,8~f位,中低字节
send_data[2]=0xff;//写数据1, 低0~7位,低字节
*/
cs5460_write(0x5e);
//清除状态寄存器
send_data[0]=0x00;
send_data[1]=0x00;
send_data[2]=0x00;
cs5460_write(0x74);
send_data[0]=0x00;
send_data[1]=0x00;
send_data[2]=0x00;
cs5460_write(0x78);
send_data[0]=0x00;
send_data[1]=0x34;
send_data[2]=0x9c;
cs5460_write(0x4c);
//写中断屏蔽寄存器
//写控制寄存器
//写EOUT脉冲输出寄存器
send_data[0]=0x00;
send_data[1]=0x0f;
send_data[2]=0xa0;
N=4000
// send_data[1]=0x01;
10次,计算得到N=400
// send_data[2]=0x90;
//计算周期为1s,得到
//每秒钟计算10次,即每秒钟采样
//此时读电能寄存器的值就是有功功率
cs5460_write(0x4A);
//写CYCLECOUNT寄存器
_delay_us(10);
// Wait_DRDY_High(n);
cs5460_READ(0x1e);
send_data[0]=rec_data[0];
send_data[1]=rec_data[1];
send_data[2]=rec_data[2];
cs5460_write(0x5e);
_delay_us(10);
write_command(0xe8);
//读状态寄存器
//写状态寄存器
//启动
CS5460A
}
/**********************************************************
************
*CS5460A清状态寄存器最高位DRDY位
***********************************************************
**********
voidClear_DRDY(unsignedcharn)
{
send_data[0]=0xff;//写数据3,16~23位,高字节
send_data[1]=0xff;//写数据2,8~f位,中低字节
send_data[2]=0xff;//写数据1, 低0~7位,低字节
cs5460_write(n,0x5e);//写指令,状态寄存器
}*/
/**********************************************************
************
*CS5460A等待状态寄存器最高位DRDY位置1,表明转换完毕
***********************************************************
***********/
voidWait_DRDY_High()
{
while(1)
{
cs5460_READ(0x1e);
if((rec_data[0]&0x80)!=0)break;//判断DRDY位,转换结束就置位。
//读状态寄存器
}
}
/*voidjiaozhun(unsignedcharn)
{
Clear_DRDY();
write_command(n,0xa0);//发送POWER_HALT命令
_delay_ms(1);
==============================================
======
第二阶段:校准交流增益寄存器。方法:将电压和电流输入加
至满幅,读取增益寄存器的值。
-----------------------------------------------------
write_command(n,0xcd);//写电流校准命令寄存器
Wait_DRDY_High(); //等待校准完成
cs5460_READ(n,0x20); //读电流偏置寄存器
_delay_ms(10);
Clear_DRDY();
write_command(n,0xd5);//写电压校准命令寄存器
_delay_ms(10);
Wait_DRDY_High(); //等待校准完成
//写电流校准命令寄存器
//等待校准完成
//******读电流增益寄存器
//写电压校准命令寄存器
//等待校准完成
//******读电压增益寄存器
*******
Clear_DRDY();
write_command(0xce);
_delay_ms(1);
Wait_DRDY_High();
cs5460_READ(0x04);
_delay_ms(1);
Clear_DRDY();
write_command(0xd6);
_delay_ms(1);
Wait_DRDY_High();
cs5460_READ(0x08);
********
_delay_ms(1);
_delay_ms(1);
Clear_DRDY();
_delay_ms(10);