当前位置:文档之家› 电表数据采集器

电表数据采集器

#define ulongunsigned long
#define ADP2P2
#define ADP0P0
#define CD4051 P1
#define fosc12//晶振频率
#define time02000//定时2000us
#define jishu 1000//假设AD输入电压与对应瞬时功率的基数
{
while (page_rd(k*5,5,&BUF[0])==0);//读原来的电能各路5位数字
for (i=0;i<=4;i++)
{
BUF[i]=BUF[i]+ADBUF[i+k*5];//本次的电能和原来的电能求和
}
while (page_wr(k*5,5,0)==0);//清寄存的电能
kk=(ulong)BUF[0]*10000+(ulong)BUF[1]*1000+(ulong)BUF[2]*100+(ulong)BUF[3]*10+(ulong)BUF[4];
kk2=kk%7200;//kk1为电度数kk2余数
BUF[0]=(uchar)(kk2/100); //分两部分存储电度的余数100为界
BUF[1]=(uchar)(kk2%100);
while(page_wr(100+k*2,2,&BUF[0])==0);//电度的存余数
while (page_rd(50+k*5,5,&BUF[0])==0); //读原来电度数
void WR7221(uchar addr,uchar Data);//MAX7221写程序
void Max7221Display(uchar *buffer);//MAX7221显示程序
void time2ms(void);//定时器0初始化程序
void time0_int(void);//定时器0中断服务程序
do{i=ADP2;}while((ADP2&0x04)!=0x04);//读7135的D3,直到D3为1
ADBUF[2+j*5]=ADP0&0x0f;//读7135的百位
do{i=ADP2;}while((ADP2&0x02)!=0x02);//读7135的D2,直到D2为1
ADBUF[3+j*5]=ADP0&0x0f;//读7135的十位
//1V对应1000w
uint idata jisuandu;//临时变量,用于计算电度数
uint idata time0_0;//临时变量,用于计算定时
sbit STAT7135= P1^7;// 7135的启动端
sbit busy = P2^6;// 7135的忙端
sbit st = P2^5;// 7135的选通端
i=busy;//读7135的正在转换忙端
do{i=busy;}while(busy==0);//忙端为0时等待直到开始转换
do{i=busy;}while(busy==1);//忙端为1时正在转换等待
STAT7135=0;//7135禁止AD转换
do{i=ADP2;}while((ADP2&0x010)!=0x010);//读7135的D5,直到D5为1
_nop_();
_nop_();
}
for (i=0;i<8;i++)//写8位数据
{
CLK7221 = 0;//时钟低
DIN7221 = (Data&(0x80>>i)) ? 1:0;//先发高位依次到低位
_nop_();
_nop_();
CLK7221 = 1;//时钟高上升沿锁数据
_nop_();
BUF[2]=(uchar)(((kk1%10000)%1000)/100); //百
BUF[3]=(uchar)((kk1%100)/10);//十
BUF[4]=(uchar)((kk1%100)%10);//个
while(page_wr(50+k*5,5,&BUF[0])==0); //存新电度数
电表数据采集器
一、原理图
二、流程图
三、原程序
#include <reg51.h>//AD7135直接与单片机相连采用查询的方法多路
#include <absacc.h>
#include <intrins.h>
#define ucharunsigned char
#define uintunsigned int
uchar i;
CS7221 = 0;//片选有效
for (i=0;i<8;i++)//写8位地址
{
CLK7221 = 0;//时钟低
DIN7221 = (addr&(0x80>>i)) ? 1:0;//先发高位依次到低位
_nop_();
_nop_();
CLK7221 = 1;//时钟高上升沿锁数据
if ((ADP2&0x010)==0x010)//D5为1开始读AD转换结果
{
//STAT7135=0;
ADBUF[j*5]=ADP0&0x0f;//读7135的万位
do{i=ADP2;}while((ADP2&0x08)!=0x08);//读7135的D4,直到D4为1
ADBUF[1+j*5]=ADP0&0x0f;//读7135的千位
}
void time2ms(void)//T0定时器初始化
{
TMOD=0x01;// T0工作方式1
/* 2ms定时设置*/
time0_0 = 65536-time0*fosc/12;//计算初值
TH0=(time0_0/256);//装定时器0初值
TL0=(time0_0%256);
TR0=1;//启动定时器0
delay(40);//延时
time2ms();//启动定时器
while(1)
{
if(TIME[1]%10==0)//5秒时间到
{ICL7135();//启动8路AD转换
SAVE();//存储电能
}
}
}
void WR7221(uchar addr,uchar Data)//MAX7221的写子程序
{
{
uchar i;
for (i=0;i<8;i++)//MAX7221的8个数码管显示
{
WR7221(i+1,*(buffer+i));//调MAX7221的写子程序
}
}
void delay(uint n)//延时程序
{
uint i,j;
for (i=0;i<n;i++)
for (j=0;j<1140;j++);
kk1=kk1+(ulong)BUF[0]*10000+(ulong)BUF[1]*1000+(ulong)BUF[2]*100+(ulong)BUF[3]*10+(ulong)BUF[4];
//原来的电度和新的电度数相加
BUF[0]=(uchar)(kk1/10000);//万
BUF[1]=(uchar)((kk1%10000)/1000);//千
sbit CS7221 = P1^5;// 7221的片选
sbit DIN7221 = P1^4;// 7221的数据端
sbit CLK7221 = P1^6;// 7221的时钟端
sbit SDA=P3^1;//2416的数据端
sbit SCL=P3^0;//2416的时钟端
//sbit en_24c16=P3^4;
bit write_8bit(uchar ch);//IIC写8位数据
uchar read24c16(uint address,uchar *shu);//IIC读字节数据
uchar write24c16(uint address,uchar ddata);//IIC写字节数据
uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad);//IIC页写
ET0=1;//打开定时器0中断
EA=1;//打开总中断
}
/*定时器0中断服务子程序,定时用于AD转换
1s约转换3次,8路信号约3s时间
为了时间充裕5s采集一次电能信号*/
void time0_int(void) interrupt 1
{
TH0=(time0_0/256);//重装定时器0初值
TL0=(time0_0%256);
//把电能转化为千瓦时即度
while(page_rd(100+k*2,2,&BUF[0])==0);//读上次余数
kk=kk*jishu+(ulong)BUF[0]*100+(ulong)BUF[1];// (jishu*1000)/(10000*12*60)=jishu/7200
kk1=kk/7200;//取电度数
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad);//IIC页读
main()
{//while(page_wr(0,120,0)==0);//初次使用时清电量数
Initial7221();//初始化7221
Max7221Display(&DISPBUF[0]);//开机默认显示0~7
void ICL7135(void);//ICL7135 8路信号AD转换程序
相关主题