电表数据采集器.docx

上传人:b****5 文档编号:30157497 上传时间:2023-08-05 格式:DOCX 页数:18 大小:115.17KB
下载 相关 举报
电表数据采集器.docx_第1页
第1页 / 共18页
电表数据采集器.docx_第2页
第2页 / 共18页
电表数据采集器.docx_第3页
第3页 / 共18页
电表数据采集器.docx_第4页
第4页 / 共18页
电表数据采集器.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

电表数据采集器.docx

《电表数据采集器.docx》由会员分享,可在线阅读,更多相关《电表数据采集器.docx(18页珍藏版)》请在冰豆网上搜索。

电表数据采集器.docx

电表数据采集器

电表数据采集器

一、原理图

二、流程图

三、原程序

#include//AD7135直接与单片机相连采用查询的方法多路

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

#defineulongunsignedlong

#defineADP2P2

#defineADP0P0

#defineCD4051P1

#definefosc12//晶振频率

#definetime02000//定时2000us

#definejishu1000//假设AD输入电压与对应瞬时功率的基数

//1V对应1000w

uintidatajisuandu;//临时变量,用于计算电度数

uintidatatime0_0;//临时变量,用于计算定时

sbitSTAT7135=P1^7;//7135的启动端

sbitbusy=P2^6;//7135的忙端

sbitst=P2^5;//7135的选通端

sbitCS7221=P1^5;//7221的片选

sbitDIN7221=P1^4;//7221的数据端

sbitCLK7221=P1^6;//7221的时钟端

sbitSDA=P3^1;//2416的数据端

sbitSCL=P3^0;//2416的时钟端

//sbiten_24c16=P3^4;

ucharDISPBUF[8]={0,1,2,3,4,5,6,7};//显示缓冲区

ucharADBUF[40]=0;//AD缓冲区(万千百十个)*8

ucharTIME[2]=0;//用于定时

ucharBUF[5]=0;//数据处理缓冲区

voiddelay(uintn);//延时子程序

voidInitial7221(void);//MAX7221初始化

voidWR7221(ucharaddr,ucharData);//MAX7221写程序

voidMax7221Display(uchar*buffer);//MAX7221显示程序

voidtime2ms(void);//定时器0初始化程序

voidtime0_int(void);//定时器0中断服务程序

voidICL7135(void);//ICL71358路信号AD转换程序

voidSAVE(void);//电量存储转电度程序

voidstart_bit(void);//IIC开始条件

voidstop_bit(void);//IIC停止条件

voidmast_ack(void);//IIC应答

bitwrite_8bit(ucharch);//IIC写8位数据

ucharread24c16(uintaddress,uchar*shu);//IIC读字节数据

ucharwrite24c16(uintaddress,ucharddata);//IIC写字节数据

ucharpage_wr(uintfirstw_ad,uintcounter,uchar*firstr_ad);//IIC页写

ucharpage_rd(uintfirstrd_ad,uintcount,uchar*firstwr_ad);//IIC页读

main()

{//while(page_wr(0,120,0)==0);//初次使用时清电量数

Initial7221();//初始化7221

Max7221Display(&DISPBUF[0]);//开机默认显示0~7

delay(40);//延时

time2ms();//启动定时器

while

(1)

{

if(TIME[1]%10==0)//5秒时间到

{ICL7135();//启动8路AD转换

SAVE();//存储电能

}

}

}

voidWR7221(ucharaddr,ucharData)//MAX7221的写子程序

{

uchari;

CS7221=0;//片选有效

for(i=0;i<8;i++)//写8位地址

{

CLK7221=0;//时钟低

DIN7221=(addr&(0x80>>i))?

1:

0;//先发高位依次到低位

_nop_();

_nop_();

CLK7221=1;//时钟高上升沿锁数据

_nop_();

_nop_();

}

for(i=0;i<8;i++)//写8位数据

{

CLK7221=0;//时钟低

DIN7221=(Data&(0x80>>i))?

1:

0;//先发高位依次到低位

_nop_();

_nop_();

CLK7221=1;//时钟高上升沿锁数据

_nop_();

_nop_();

}

CS7221=1;//片选无效

}

voidInitial7221(void)//MAX7221初始化

{

WR7221(0x0A,0x0A);//亮度地址0AH,0x00~0x0F,0x0F最亮

WR7221(0x0B,0x07);//扫描LED个数地址0BH,0x00~0x07,最多扫描8个数码管

WR7221(0x0C,0x01);//工作模式地址0x0C.0x00:

关断;0x01:

正常

WR7221(0x09,0xFF);//编码模式地址0x09.0x00~0xFF:

哪一位为1,哪一位就支持编码

}

voidMax7221Display(uchar*buffer)//MAX7221显示子程序

{

uchari;

for(i=0;i<8;i++)//MAX7221的8个数码管显示

{

WR7221(i+1,*(buffer+i));//调MAX7221的写子程序

}

}

voiddelay(uintn)//延时程序

{

uinti,j;

for(i=0;i

for(j=0;j<1140;j++);

}

voidtime2ms(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

ET0=1;//打开定时器0中断

EA=1;//打开总中断

}

/*定时器0中断服务子程序,定时用于AD转换

1s约转换3次,8路信号约3s时间

为了时间充裕5s采集一次电能信号*/

voidtime0_int(void)interrupt1

{

TH0=(time0_0/256);//重装定时器0初值

TL0=(time0_0%256);

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秒的整数倍

}

}

voidICL7135(void)//启动8路AD转换

{

uchari,j;

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转换

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

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的千位

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的十位

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转换的结果

}

}

}

voidSAVE(void)//电能处理保存

{

uchark,i;

ulongkk,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位数字

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路电能循环转换成电度数存储

{

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];

//把电能转化为千瓦时即度

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);//读原来电度数

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);//千

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);//存新电度数

DISPBUF[0]=k+1;//显示户号

DISPBUF[1]=0xf;//显示2个F

DISPBUF[2]=0xf;

DISPBUF[3]=BUF[0];//显示此时电度数

DISPBUF[4]=BUF[1];

DISPBUF[5]=BUF[2];

DISPBUF[6]=BUF[3];

DISPBUF[7]=BUF[4];

Max7221Display(&DISPBUF[0]);//送显示

delay(20);//延时

}

}

}

/*-----------------------------------------------

调用方式:

voidstart_bit(void)

函数说明:

开始位

-----------------------------------------------*/

voidstart_bit(void)

{

SCL=1;_nop_();

SDA=1;_nop_();

SDA=0;_nop_();

SCL=0;_nop_();

}

/*-----------------------------------------------

调用方式:

voidstop_bit(void)

函数说明:

停止位

-----------------------------------------------*/

voidstop_bit(void)

{

SDA=0;_nop_();

SCL=1;_nop_();

SDA=1;_nop_();

}

/*-----------------------------------------------

调用方式:

voidmast_ack(void)

函数说明:

主答函数

-----------------------------------------------*/

voidmast_ack(void)

{

SCL=0;_nop_();

SDA=0;_nop_();

SCL=1;_nop_();

SCL=0;_nop_();

SDA=1;_nop_();

}

/*-----------------------------------------------

调用方式:

write_8bit(ucharch)

函数说明:

写一个字节(8位)数据

-----------------------------------------------*/

bitwrite_8bit(ucharch)

{

uchari=8;

bitfan_w;

SCL=0;_nop_();

while(i--)

{

SDA=(bit)(ch&0x80);_nop_();

ch<<=1;

SCL=1;_nop_();

SCL=0;_nop_();

}

SDA=1;_nop_();

SCL=1;_nop_();

fan_w=SDA;

SCL=0;_nop_();

return(fan_w);

}

/*----------------------------------------------

调用方式:

ucharread24c16(uintaddress,uchar*shu)

函数说明:

读24c16指定地址数据(字节读)

-----------------------------------------------*/

ucharread24c16(uintaddress,uchar*shu)

{

uchardatardata;

uchari=8;

EA=0;//避免与串口通讯等中断冲突

start_bit();

if(write_8bit(0xA0)!

=0){

stop_bit();EA=1;return(0);

}

if(write_8bit(address)!

=0){

stop_bit();EA=1;return(0);

}

start_bit();

if(write_8bit(0xA1)!

=0){

stop_bit();EA=1;return(0);

}

while(i--)

{

rdata<<=1;

SCL=1;_nop_();

if(SDA)rdata|=0x01;

SCL=0;_nop_();

}

stop_bit();

EA=1;

*shu=rdata;

return

(1);

}

/*-----------------------------------------------

调用方式:

voidwrite24c16(uintaddress,ucharddata)

函数说明:

写数据到24c16的指定地址(字节写)

-----------------------------------------------*/

ucharwrite24c16(uintaddress,ucharddata)

{

EA=0;//避免与串口通讯等中断冲突

start_bit();

if(write_8bit(0xA0)!

=0){

stop_bit();EA=1;return(0);

}

if(write_8bit(address)!

=0){

stop_bit();EA=1;return(0);

}

if(write_8bit(ddata)!

=0){

stop_bit();EA=1;return(0);

}

stop_bit();

EA=1;

return

(1);

}

/*-----------------------------------------------

调用方式:

voidpage_wr(uintfirstw_ad,uintcounter,uintdata*firstr_ad)

函数说明:

页面写函数,firstw_ad为写入字节单元的首地址,

*firstr-ad为被写入数据所在首地址指针

counter为写入数据字节数

-----------------------------------------------*/

ucharpage_wr(uintfirstw_ad,uintcounter,uchar*firstr_ad)

{

uchardata*ufirstr_ad;

ufirstr_ad=firstr_ad;

start_bit();

if(write_8bit(0xA0)!

=0){

stop_bit();return(0);

}

if(write_8bit(firstw_ad)!

=0){

stop_bit();return(0);

}

while(counter--)

{

if(write_8bit(*ufirstr_ad)!

=0){

stop_bit();return(0);

}

ufirstr_ad++;

}

stop_bit();

return

(1);

}

/*-----------------------------------------------

调用方式:

voidpage_rd(uintfirstrd_ad,uintcount,uintfirstwr_ad)

函数说明:

页面读函数,firstrd-ad为所读字节首地址,count为读字节数

*ufirstwr-ad为读出数据存储首地址指针

-----------------------------------------------*/

ucharpage_rd(uintfirstrd_ad,uintcount,uchar*firstwr_ad)

{

ucharj=8;

uchardata*ufirstwr_ad;

ufirstwr_ad=firstwr_ad;

start_bit();

if(write_8bit(0xA0)!

=0){

stop_bit();return(0);

}

if(write_8bit(firstrd_ad)!

=0){

stop_bit();return(0);

}

start_bit();

if(write_8bit(0xA1)!

=0){

stop_bit();return(0);

}

while(count--)

{

uchari=8;

while(i--)

{

(*ufir

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1