电表数据采集器.docx
- 文档编号:30157497
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:18
- 大小:115.17KB
电表数据采集器.docx
《电表数据采集器.docx》由会员分享,可在线阅读,更多相关《电表数据采集器.docx(18页珍藏版)》请在冰豆网上搜索。
电表数据采集器
电表数据采集器
一、原理图
二、流程图
三、原程序
#include
#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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电表 数据 采集