电表数据采集器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
do{i=ADP2;}while((ADP2&0x01)!=0x01);//读7135的D1,直到D1为1
ADBUF[4+j*5]=ADP0&0x0f;//读7135的个位
//ADBUF[0]=j+1;//路号
//Max7221Display(&ADBUF[j*5]);//当频率慢时可以显示AD转换的结果
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
uchar DISPBUF[8]={0,1,2,3,4,5,6,7};//显示缓冲区
uchar ADBUF[40]=0;//AD缓冲区(万千百十个)*8
uchar TIME[2]=0;//用于定时
uchar BUF[5]=0;//数据处理缓冲区
void delay(uint n);//延时子程序
void Initial7221(void);//MAX7221初始化
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);
}
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
电表数据采集器
一、原理图
二、流程图
三、原程序
#include <reg51.h>//AD7135直接与单片机相连采用查询的方法多路
#include <absacc.h>
#include <intrins.h>
#define ucharunsigned char
#define uintunsigned int
_nop_();
}
CS7221 = 1;//片选无效
}
void Initial7221(void)//MAX7221初始化
{
WR7221(0x0A,0x0A);//亮度地址0AH,0x00~0x0F,0x0F最亮
WR7221(0x0B,0x07);//扫描LED个数地址0BH,0x00~0x07,最多扫描8个数码管
//把电能转化为千瓦时即度
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;//取电度数
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); //读原来电度数
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); //存新电度数
uchar i;
CS7221 = 0;//片选有效
for (i=0;i<8;i++)//写8位地址
{
CLK7221 = 0;//时钟低
DIN7221 = (addr&(0x80>>i)) ? 1:0;//先发高位依次到低位
_nop_();
_nop_();
CLK7221 = 1;//时钟高上升沿锁数据
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的十位
delay(40);//延时
time2ms();//启动定时器
while(1)
{
if(TIME[1]%10==0)//5秒时间到
{ICL7135();//启动8路AD转换
SAVE();//存储电能
}
}
}
void WR7221(uchar addr,uchar Data)//MAX7221的写子程序
{
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的千位
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页写
STAT7135=1;//7135启动端使能启动AD转换
CD4051=CD4051&0xf0;//设置CD4051的第一路信号输入AD
for (j=0;j<=7;j++)//8路循环测量
{
i=CD4051&0xf0;//读P1口的状态保护高位
CD4051=j|i;//通过j调节多路开关的转换
STAT7135=1;//7135启动端使能启动AD转换
{
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++);
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;
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);//千
{
while (paห้องสมุดไป่ตู้e_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];
TIME[0]++;
if (TIME[0]==250)//250*2ms=500ms=0.5s时间到
{
TIME[0]=0;//到0.5s时TIME[0]清0
TIME[1]++;//TIME[1]加1内存的0.5秒的整数倍
}
}
void ICL7135(void)//启动8路AD转换
{
uchar i,j;
for (i=0;i<=4;i++)
{
BUF[i]=BUF[i]+ADBUF[i+k*5];//本次的电能和原来的电能求和
}
while (page_wr(k*5,5,&BUF[0])==0);//存新的总电能
}
}
if (TIME[1]==120)//等于1分钟时做电度数的处理
{
TIME[1]=0;
for (k=0;k<=7;k++)//8路电能循环转换成电度数存储
#define ulongunsigned long
#define ADP2P2
#define ADP0P0
#define CD4051 P1
#define fosc12//晶振频率
#define time02000//定时2000us
#define jishu 1000//假设AD输入电压与对应瞬时功率的基数
void ICL7135(void);//ICL7135 8路信号AD转换程序
void SAVE(void);//电量存储转电度程序
void start_bit(void);//IIC开始条件
void stop_bit(void);//IIC停止条件
void mast_ack(void);//IIC应答
_nop_();
_nop_();
}
for (i=0;i<8;i++)//写8位数据
{
CLK7221 = 0;//时钟低
DIN7221 = (Data&(0x80>>i)) ? 1:0;//先发高位依次到低位
_nop_();
_nop_();
CLK7221 = 1;//时钟高上升沿锁数据
_nop_();
void WR7221(uchar addr,uchar Data);//MAX7221写程序
void Max7221Display(uchar *buffer);//MAX7221显示程序
void time2ms(void);//定时器0初始化程序
void time0_int(void);//定时器0中断服务程序
WR7221(0x0C,0x01);//工作模式地址0x0C. 0x00:关断;0x01:正常
WR7221(0x09,0xFF);//编码模式地址0x09. 0x00~0xFF:哪一位为1,哪一位就支持编码
}
void Max7221Display(uchar *buffer)//MAX7221显示子程序
//1V对应1000w
uint idata jisuandu;//临时变量,用于计算电度数
uint idata time0_0;//临时变量,用于计算定时
sbit STAT7135= P1^7;// 7135的启动端
sbit busy = P2^6;// 7135的忙端
sbit st = P2^5;// 7135的选通端
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 SAVE(void)//电能处理保存
{
uchar k,i;
ulong kk,kk1,kk2;
if (TIME[1]<120)//小于1分钟时120*0.5=60s简单加
{
for (k=0;k<=7;k++)//8路电能循环存储
{
while (page_rd(k*5,5,&BUF[0])==0);//读原来的电能各路5位数字
相关文档
最新文档