一、系统方案
本系统主要由数据采集模块、单片机系统、液晶显示模块组成。下面分别论证这几个模块的选择。
1、液晶显示器件的论证与选择
方案一:采用LCD1602液晶显示屏
该屏幕价格低廉,驱动简单。与51单片机兼容性良好。
方案二:采用LCD19264液晶显示屏
该屏幕驱动简单,显示信息明确,但是价格却比LCD1602高出数倍。
通过比较,我们选择方案一。
2、数据采集模块的论证与选择
方案一:霍尔电流传感器测量电流
输入为电流输出为电压,测量结果精度和线性度都比较高,测量范围有一定的限制。使用ACS712芯片电路比较简单,测量的电流范围较大。相比于ACS712电路比较简单,MAX471不用外加电源供电,但是电流测量范围只在0~3A。该电流测量范围不符合监测基本要求。
方案二:采用电流互感器与电压互感器。
电流互感器的一次电流取决于一次性电路的电压和阻抗。电流互感器的工作状态接近于短路状态。因此对电能的消耗量较小。采用ZMCT103C电流互感器,ZMPT101B电压互感器,可以测出具体的电流值和电压值。
综合以上两种方案,选择方案二。
3、方案描述
用电器交流信号经过电流互感器及电压互感器处理后变成几百毫伏的交流信号,然后经过电路将信号送入ADC0809芯片实现模数转换功能,再通过串口通信将信号传输给51单片机系统。单片机处理信号后显示在液晶显示器上。系统总体框图如图1.1所示:
图1.1 系统总体框图
二、系统理论分析与计算 1、电流互感器
电流互感器采用ZMCT103C,体积小,精度高,一致性好。ZMCT103C结构图如图2.1所示。
图2.1 ZMCT103C电流互感器结构图
2、电压互感器:
电压互感器采用ZMPT101B,互感器结构图如图2.2所示。
图2.2 ZMPT101B结构图
3、信号处理电路: 由互感器测量电流值(运用K=I1/I2=N2/N1),运用整流电路将交流电转化为直流电,再采用大规模集成电路ADC0809实现数模(A / D)图2.3所示转换,把模拟量信号转换成对应的数字量信号。数字信号传入单片机进行数据处理,然后通过显示屏显示具体的电压值和电流值及各电性参数。
图2.3 ADC0809引脚图
4、电压和电流测量计算
所使用的互感器的匝数比为I1/I2=N2/N1=850/10。
半波整流电路由于二极管的单向导电作用,使流过负载电阻的电流为脉动电流,电压也为一单向脉动电压,其电压的平均值(输出直流分量)为:
加在二极管两端的最高反向电压为
流过负载的平均电流为:
流过二极管D的平均电流(即正向电流)为
三、电路设计 1、信号采集和处理电路
220V交流信号经过电流互感器及电压互感器处理后变成几百毫伏的交流信号,然后经过电路将信号送入ADC0809芯片实现模数转换功能,信号采集和处理电路。
2、检测整流电路
互感器将一次系统的高电压,大电流变换为二次测的低电压(标准值),小电流(标准值),使测量,计量仪表和继电器等装置标准化,小型化,并降低了对二次设备的绝缘要求。
采用整流电路具有单向导电性能的整流元件,将正负交替的正弦交流电整流成为单向的脉动电,再用滤波器将输入或输出经过过滤而得到纯净的直流电。对特定频率的频点或该频点以外的频率进行有效滤除。在自动测量和控制系统中,利用滤波电路进行模拟信号的处理,用于数据传送,抑制干扰。
由互感器测量电流值(运用K=I1/I2=N2/N1),运用整流电路将交流电转化为直流电,再采用大规模集成电路ADC0809实现数模(A / D)转换,把模拟量信号转换成对应的数字量信号。数字信号传入单片机进行数据处理,然后通过显示屏显示具体的电压值和电流值及各电性参数。
3、单片机系统
本模块是整个设计的核心部分,设计采用的是STC89C51单片机系统。STC89C51是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器,单片机是由运算器,控制器,主要寄存器组成。具有执行各项逻辑运算,指令控制等功能。运用单片机处理数据信息及调控显示时间。STC89C51系统的原理图如图3.2所示。
选用ADC0809,单片机AT89C51。
图3.2 STC89C51系统的原理图
四、程序设计 本系统采用C51语言编程,主函数调用编写好的功能函数实现基本功能。功能函数有处理电压信号的函数、处理电流信号的函数、处理功率信号的函数。
定义 ➡ 声明 ➡ 数模转换 ➡ 判断显示
核心代码请见页面底部......
五、测试方案与测试结果分析 1、测试方案
(1)硬件测试
检查多次,硬件电路必须与系统原理图完全相同,并且检查无误,硬件电路保证无虚焊。随便给一些初始值,检查屏幕显示是否与初始值显示一致。如图5.1。
图5.1硬件测试示意图
2、测试结果及分析
测试结果如下表所示: (单位/V /A /W /℃)
类型 |
测试电流 |
测试电压 |
测试功率 |
负载性质 |
电磁炉 |
5.7900 |
233 |
1349 |
感性 |
电炉子 |
5.1520 |
233 |
1200 |
阻性 |
白炽灯 |
0.2710 |
233 |
63 |
阻性 |
机顶盒 |
0.7215 |
230 |
165 |
感性 |
电热水壶 |
5.2173 |
230 |
1200 |
阻性 |
电风扇 |
0.2732 |
230 |
62 |
感性 |
参考文献
[1] 谭浩强.C语言程序设计[M].北京:清华大学出版社,2012
[2] 张毅刚,刘旺,邓丽宝.单片机原理与接口设计[M].北京:人民邮电出版社,2015
[3] 基于集成芯片CS5463的电测仪表的设计[J].常铁原,王素平.科技资讯,2013
[4] 刘月武,李杏春.新型单相双向功率/电能集成电路CS5463的原理与应用[J]. 仪器仪表用户,2010
[5]张玲玲.基于51单片机的LCD12864程序设计[J].中小企业管理与科技(中旬刊),2015
自制用电器(大约17ma):
核心代码:
#include<reg51.h>
#include<intrins.h>
#include<stdio.h>
#include<string.h>
#define uint unsigned int
#define uchar unsigned char
sbit ST=P3^0;
sbit OE=P3^1;
sbit EOC=P3^2;
sbit CLK=P3^3;
sbit lcdrs=P2^0;
sbit lcdrw=P2^1;
sbit lcden=P2^2;
#define out P0
void delayms(uint z);//延时 1ms 函数
uint ADC_convert(); //ADC 转换
void init(); //液晶初始化+
void write_com(uchar com); //1602 写指令。
void write_date(uchar date);//1602 写数据。
void Refresh_show();//刷新显示+
void LCD_display(uchar*str);//输出字符串。
uint dat_adc0809;
uchar display_buffer[][16]={
{" happy boom "},
{" (vol)=0.00V"}
};
uchar code table1[]={" no Electric "};//14
uchar code table2[]={" ^_^JIAN CE^_^ "};//11
uchar code table3[]={"i=2mA Router"};
uchar code table4[]={"i=4mA USB-CH"};
uchar code table5[]={"i=190mA Ele FAN"};
uchar code table6[]={"i=40mA LEDLight"};
uchar code table7[]={"i=6600mA W-H"};
uchar code table8[]={"i=2mA Top-box"};
uchar code table9[]={"i=6550mA WE"};
/*&&&&&&&&&&&&&&&& 向 1602 写指令函数 &&&&&&&&&&&&&&&&*/
void write_com(uchar com)
{
lcdrs=0;
lcdrw=0;
lcden=0;
P1=com;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
/*&&&&&&&&&&&&&&& 向 1602 写指令结束 &&&&&&&&&&&&&&&&&&*/
/*%%%%%%%%%%%%%向 1602 写数据函数%%%%%%%%%%%%%%%%%%%%%*/
void write_date(uchar date){
lcdrs=1;
lcdrw=0;
lcden=0;
P1=date;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
/*%%%%%%%%%%%%%%%%%%%%向 1602 写数据结束%%%%%%%%%%%%%%%%%*/
/*******液晶初始化**********************/
void LCD_init() {
uchar num;
write_com(0x38);//初始化 显示模块设置。
write_com(0x0c);//显示光标+
write_com(0x06);//当读或写一个字符后地址指针加 1,且光标加 1
write_com(0x01);//显示清屏。
write_com(0x80);//不显示光标
for(num=0;num<10;num++) //显示 table1[]
{
write_date(table1[num]);
delayms(20);
}
write_com(0x80+0x40);//指针设置 这里让他第二行开始显示
for(num=0;num<16;num++){ //table2[];
write_date(table2[num]);
delayms(20);
}
}
/*****************液晶初始化结束***********/
/*****************模数转化并用于显示***********/
uint ADC_convert()
{
while(1)
{
ST=0;
ST=1;
ST=0;
while(1){CLK=!CLK;if(EOC==1)break;}//等待转换
晉(这个我也不知道队友写了个啥 dog):
OE=1;
dat_adc0809=out;
OE=0;
return dat_adc0809;
}
}
/*************模数转换结束**********************
/*&&&&&&&&&&&&&&刷新显示函数&&&&&&&&&&&&&&&&&&*/
void Refresh_show()
{
uint t=dat_adc0809*500.0/256;
display_buffer[1][7]=t/100.0-1+'0';
display_buffer[1][9]=t/10%10-8+'0';
display_buffer[1][10]=t%10-5+'0';
}
/*&&&&&&&&&&&&&&&刷新显示函数结束&&&&&&&&&&&&&&&&&&&*/
/***************lcd 显示字符串*******************/
void LCD_display(uchar*str){
uchar i;
for(i=0;i<strlen(str);i++) {
write_date(str[i]);
delayms(5);
}
}
/***************lcd 显示字符串结束*******************/
/*###################延时1ms子函数####################*/
void delayms(uint z){
uint x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}
/*##############延时1ms子函数结束################*/
void main(){
uchar num;
LCD_init();
while(1){
ADC_convert();
Refresh_show();
write_com(0x80);
LCD_display(display_buffer[1]);
Refresh_show();
delayms(5);
write_com(0xC0);
if
((display_buffer[1][7]==48)&&(display_buffer[1][9]==50)&&((display_buffer[1][10]==51)||(display_buffer[1][10]==52)||(display_buffer[1][10]==53)||(display_buffer[1][10]==54)) )
{for(num=0;num<16;num++) //显示:
{ write_date(table3[num]);
delayms(20);}
}
if
((display_buffer[1][7]==48)&&(display_buffer[1][9]==53)&&((display_buffer[1][10]==53)||(display_buffer[1][10]==54)||(display_buffer[1][10]==55)||(display_buffer[1][10]==56))||(display_buffer[1][10]==57))
{for(num=0;num<16;num++)
{write_date(table4[num]);
delayms(20);}
}
if
((display_buffer[1][7]==52)&&(display_buffer[1][9]==54)&&((display_buffer[1][10]==51)||(display_buffer[1][10]==52)||(display_buffer[1][10]==53)||(display_buffer[1][10]==54))||(display_buffer[1][10]==55))
{for(num=0;num<16;num++)
{write_date(table7[num]);
delayms(20);}
}
if
((display_buffer[1][7]==48)&&(display_buffer[1][9]==53))
{for(num=0;num<16;num++)
{write_date(table5[num]);
delayms(20);}
}
if
((display_buffer[1][7]==48)&&(display_buffer[1][9]==55)&&((display_buffer[1][10]=
晉:
if
((display_buffer[1][7]==48)&&(display_buffer[1][9]==55)&&((display_buffer[1][10]==53)))
{for(num=0;num<16;num++)
{write_date(table6[num]);
delayms(20); }
}
if
((display_buffer[1][7]==52)&&(display_buffer[1][9]==54)&&((display_buffer[1][10]==51)||(display_buffer[1][10]==52)||(display_buffer[1][10]==53)||(display_buffer[1][10]==54))||(display_buffer[1][10]==55))
{for(num=0;num<16;num++)
{write_date(table8[num]);
delayms(20);}
}
if
((display_buffer[1][7]==53)&&(display_buffer[1][9]==48)&&((display_buffer[1][10]==50)||(display_buffer[1][10]==51)||(display_buffer[1][10]==52)|(display_buffer[1][10]==53))||(display_buffer[1][10]==54)|(display_buffer[1][10]==55))
{for(num=0;num<16;num++)
{write_date(table9[num]);
delayms(20);}
}
}
}