摘 要
单相用电器分析监测装置是一种通过采集并判断用电器的工作状态和特性参数(如电压、电流、功率因数等)来确定用电器的种类和工作状态的设备。本装置具有监测功能,即可以实时监测电流范围为0到5安培的用电器的工作状态并显示各个用电器的特性参数。我们采用飞思卡尔的K60芯片作为整个系统的控制核心,对电路的多项数据进行实时监测和显示。利用电流、电压互感器测试,其输出电压经过精密全波整流电路,再用单片机进行控制和显示。
关键词:单相用电器;分析监测;K60;电流互感器;电压互感器;AD采样
目录
一、系统方案. 1
1、主控制器件的论证与选择... 1
2、数据检测采集模块的论证与选择... 1
3、显示模块的论证与选择... 1
二、系统理论分析与计算. 2
1、K60控制模块的分析... 2
(1)AD采集转换模块... 2
(2)显示模块... 2
(3)串口通信... 2
2、整流滤波电路的分析计算... 2
(1)整体电路的设计思路... 2
(2)电阻阻值的选取... 3
(3)电容容值的确定... 3
三、电路与程序设计. 3
1、电路的设计... 3
(1)系统总体框图... 3
(2)数据监测采集模块子系统框图与电路原理图... 3
(3)辅助电源... 4
2、程序的设计... 5
(1)程序功能描述与设计思路... 5
(2)程序流程图... 5
四、测试方案与测试结果. 6
1、测试方案... 6
2、测试条件与仪器... 6
(1)测试结果(数据) 6
(2)测试分析与结论... 7
(3)心得体会... 7
五、参考文献. 7
附录1:电路原理图. 8
附录2:源程序. 8
单相用电器分析监测装置(K题)
【本科组】
本系统主要由单片机分析控制模块、辅助电源模块、数据检测采集模块、显示模块、无线传输模块组成,下面分别论证这几个模块的选择。
方案一:采用传统的51系列单片机。
51单片机运算能力强,编程灵活,但其内存较小,无内置AD,使用较为不便。
方案二:采用飞思卡尔的K60芯片作为控制核心。
基于ARM Cortex-M4内核的32位微控制器K60,具有强大的运算处理能力和丰富的内存空间。内置16位ADC模块,并可实现在线编程,检测精度高。
由于完成本题需要大量编程工作,对单片机内存和处理速度要求较高,且小组成员更熟悉K60的使用,故选择方案二。
方案一:采用电流互感器和K60内置ADC模块
电流互感器可将数值较大的一次电流转换为数值较小的二次电流,电压互感器可将数值较大的一次电压转换为数值较小的二次电压,将输出量通过采集电路,利用K60内部的ADC模块进行采集并转换分析。
方案二:采用CS5463计量芯片
CS5463内部的2个可编程放大器可采集电压和电流数据,△-∑调制器对模拟量采样处理,高速数字低通或可选的高通滤波器滤取可用电压电流数字信号,功率计算引擎计算各类型的功率,电压、电流,并将计算的值通过串行接口对外输出,接到K60进行分析。
但考虑到使用直接测量芯片可能不符合题设初衷,因此考虑采用方案一。
方案一:采用0.96寸OLED显示
OLED具有对比度高、耗电低、反应速度快等优点。但是,其价格较高,且尺寸达不到本小组的要求,不能同时显示多个内容。
方案二:采用1.8寸TFT
TFT式显示器具有高响应度、高亮度、高对比度等优点,能足够显示题目要求的内容。
综合分析考虑采用方案二。
K60内置的ADC具有16位、12位、10位和8位四种精度,由于12位的精度足够达到所采集的数据的大小,故选用12位的精度。采集过程中,先对ADC模块进行初始化,配置寄存器,再利用AD平均值函数计算并返回采集二十次的AD平均值。
主机的彩屏显示相应用电器的特性参数(如电压、电流、功率和功率因数),从机的彩屏显示从主机发送过来的相应用电器的开关状态。
两个HC-05蓝牙模块是两块K60单片机之间实现无线传输的桥梁,利用串口调试助手对蓝牙相关参数进行设置,程序中通过对两块蓝牙设置相同的波特率使两块蓝牙上电后能够自动连接。主机(接收和处理用电器状态的K60芯片)识别到相关用电器状态后马上发送给从机,从而达到发挥部分无线传输功能。
整流部分使用精密全波整流电路,利用LM358P双运放和两只整流二极管,其中U1和U2为LM358P内部的两个运放。电阻R1、R2和U1共同构成一个放大倍数为-1的反向放大电路;电阻R3、R4、R5和U2构成反向加法电路。在电路的输出端并联一个电容实现滤波,最后输出直流电。电路仿真图如下图1。
图1 整流滤波电路仿真图
要使反相放大电路满足放大倍数为-1,则电阻应满足R1=R2;同时反向加法电路中电阻应满足R4=R5=2*R3。故R1、R2和R3选用10KΩ,R4=R5=20KΩ。
在电路仿真过程中发现,电容容值过小时(10uF以下),电路能够快速稳定,但滤波效果不佳,当电容容值过大时,滤波效果很好,但电路响应速度慢,因此考虑将电容容值设为10uF为宜。
系统总体框图如图2所示,其中辅助电源给监测电路、K60芯片以及液晶显示屏供电。A、B测试点用来接入单相用电器特性参数测量仪。
图2 系统总体框图
1、数据监测采集子系统框图
图3 数据监测采集子系统框图
2、数据监测采集子系统电路
图4 电流、电压互感器电路
图5 数据监测采集子系统电路
辅助电源由变压部分、滤波部分、稳压部分组成。为整个系统提供多种稳定可调直流电压(其中包括3.3V、±5V、-9V、12V、±15电源),确保电路的正常稳定工作。这部分电路比较简单,都采用三端稳压管实现,原理图如下图6。
图6 辅助电源电路
1、程序功能描述
根据题目要求软件部分主要实现AD采集转换、控制彩屏显示和实现无线传输功能。
1)ADC部分:采集电路中用电器的特征参数(如电压、电流、功率、功率因数等),将其转换成数字量。
2)显示部分:显示用电器编号、工作状态、电流值、电压值等。
2、程序设计思路
不断采集数据并定义多个变量,将前后采集的数据不断对比,通过判断前后差值是否大于正常电路中该参数的波动幅度,来确定该用电器的工作状态,并输出其状态和参数。
1、主程序流程图
(1)硬件测试
搭建各个模块的实际电路,将各个模块通过杜邦线连接起来,用数字万用表对各电路的参数进行测量分析,记录结果。
(2)软件仿真测试
使用Altium Designer绘制电路原理图,另外,使用Multisim软件进行仿真测试,再将测试结果与实际电路进行对比,并记录结果。
(3)硬件软件联调
利用K60开发环境编辑或修改程序,使芯片AD口采集并转换电路中的特征参数,再利用显示屏进行显示,不断测试并检查数据,当发现数据出现异常时,调试程序并修改电路,直到得出正确结果。
测试条件:检查多次,仿真电路和硬件电路与系统原理图相同,经检查,电路无虚焊,无短路。
测试仪器:
序号 |
型号、名称 |
数量 |
备注 |
1 |
VC8045型数字万用表 |
1 |
深圳市胜利龙仪器仪表有限公司 |
2 |
UT70A数字万用表 |
1 |
优利德有限公司 |
3 |
LDS21010示波器 |
1 |
上海双旭电子有限公司 |
3、测试结果及分析
整体测试结果如下表所示:
用电器编号 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
显示采集值 |
90-93 |
185-192 |
425-450 |
735-750 |
1160-1200 |
1740-1770 |
>4000 |
显示电流值 |
10 |
23 |
42 |
53 |
93 |
187 |
8.2A |
测试蓝牙无线传输模块,当用电器插上时,与发送信号的芯片连接的显示屏显示该用电器的各项数据即采集量和电流,此时,接收端的显示屏上对应的用电器显示ON;当拔掉用电器时,发送端和接收端均显示OFF。
编号从1到7的用电器依次为1:用1.1W电阻自制的用电器;2:功率为3W的节能灯;3:功率为5W的节能灯;4:功率为7W的用电器,功率逐次增大;5:功率为10W的节能灯;6:20W功率的电烙铁;7:显示采集值表示的是控制电路并发送信号的K60芯片实时采集量,显示电流值为各个用电器的工作电流。 测试过程中,插上用电器后能够显示该用电器的各项数据,拔掉用电器时,被拔用电器显示OFF,其他用电器数据不变。
根据上述测试数据,硬件电路部分实现了滤波整流功能,K60芯片能够采集到电路的相关参数,并对数据进行转换和分析,另外实现了显示的功能,除此之外,两块K60芯片之间实现了无线传输功能。由此可以得出以下结论:
1、电路可接多个负载,并使其正常工作。
2、AD采集模块正常能够采集数据并转换成数字量。
3、显示模块可以正常显示,且同时显示多个内容。
4、蓝牙无线传输模块可以实现两块芯片之间的无线通信。
综上所述,本设计能够达到题目的一部分要求。
经过这次比赛,小组成员不仅加强了专业知识的巩固,还自学了一些专业相关的知识,锻炼了动手实践的能力,更深刻体会到团队合作的重要性,懂得了团队成员之间如何更好地合作沟通,共同进步。虽然比赛作品没能达到赛题的所有要求,但参与过程中大家都受益匪浅。
[1] 谭浩强.C语言程序设计[M].北京:清华大学出版社,2012
[2] 徐德宏,马皓,汪槱生.电力电子技术[M].北京:科学出版社,2006
[3] 黄志伟.全国大学生电子设计竞赛制作实训(第二版)[M].北京:北京航空航天大学出版社2011
控制电路并发送信号的K60芯片
void main(void)
{
PLL_Init(PLL180); //初始化PLL为180M、
ADC_Init(ADC0); //初始化ADC0模块
UART_Init(UART0,9600);
LCD_init(); //初始化TFT
DisableInterrupts; //禁止总中断
LCD_display_full(BLACK); //屏幕背景为黑色
LCD_P8X16Str(0,0,"AHNU ZXF WJ ZSC",YELLOW,BLACK); //字符串输出
LCD_P8X16Str(0,1,"No. mV mA W",ORANGE,BLACK); //字符串输出
LCD_P8X16Str(0,2,"1",WHITE,BLACK); //用电器1
LCD_P8X16Str(0,3,"2",WHITE,BLACK); //字符串输出
LCD_P8X16Str(0,4,"3",WHITE,BLACK); //字符串输出
LCD_P8X16Str(0,5,"4",WHITE,BLACK); //字符串输出
LCD_P8X16Str(0,6,"5",WHITE,BLACK); //字符串输出
LCD_P8X16Str(0,7,"6",WHITE,BLACK); //字符串输出
LCD_P8X16Str(0,8,"7",WHITE,BLACK); //字符串输出
//指示灯的初始化
GPIO_Init(PORTA, 17, 1,1);//插电器判定
GPIO_Init(PORTE, 26, 1,1);//拔电器判定
GPIO_Init(PORTC, 0, 1,1);//while循环判定
GPIO_Init(PORTD, 15, 1,1);//无插拔判定
CurrentValue0 = ADC_Ave(ADC0,ADC0_SE9,ADC_12bit,20)*(float)0.7434; //B1口 V0:基准电流。获取未插拔时的参数值
//主循环
while(1){
//测试蓝牙 UART_Put_Char(UART0,3); GPIO_Reverse(PORTC,0); time_delay_ms(500); //延时
GPIO_Reverse(PORTC,0);
CurrentValue_a = CurrentValue0;
time_delay_ms(500); //延时
//每隔0.2s获取当前电流值 与前一时刻进行比较 若差值大于正常波动,则等待。直到差值稳定在某一范围
CurrentValue_b = ADC_Ave(ADC0,ADC1_SE9,ADC_12bit,20);
Count2 = abs(CurrentValue_b - CurrentValue_a);
while(Count2 > Range){ //V2在增加
mark = 1;
CurrentValue_a = CurrentValue_b;
time_delay_ms(5000); //延时
CurrentValue_b = ADC_Ave(ADC0,ADC1_SE9,ADC_12bit,20);
Count2 = abs(CurrentValue_b - CurrentValue_a);
}
//如果没进入上述while循环,说明电流没有增加,不用进行下面的操作
if(mark == 1) {
CurrentValue1 = ADC_Ave(ADC0,ADC1_SE9,ADC_12bit,20); //B1口,V1不停获取电流值;
//若电路进行插拔(通过判断前后电流差是否大于Range) 则进行插、拔判断。无插拔则不响应
if((CurrentValue1 > CurrentValue0) ){ //判断是否插用电器
Count = CurrentValue1 - CurrentValue0; //获取变化值
CurrentValue0 = CurrentValue1;
GPIO_Reverse(PORTA,17);
time_delay_ms(1000); //延时
if(Count >= (E1-20) && Count <= (E1+20)){ //判断用电器1是否----插
kind = 1;
UART_Put_Char(UART0,kind);
sprintf(data1,"%4d",Count);
LCD_P8X16Str(2,2,data1,BLUE,BLACK);
}
if(Count >= (E2-20) && Count <= (E2+20)){ //判断用电器2是否----插
kind = 2;
UART_Put_Char(UART0,kind);
sprintf(data2,"%4d",Count);
LCD_P8X16Str(2,3,data2,BLUE,BLACK);
}
if(Count >= (E3-20) && Count <= (E3+20)){ //判断用电器3是否----插
kind = 3;
UART_Put_Char(UART0,kind);
sprintf(data3,"%4d",Count);
LCD_P8X16Str(2,4,data3,BLUE,BLACK);
}
if(Count >= (E4-20) && Count <= (E4+20)){ //判断用电器4是否----插
kind = 4;
UART_Put_Char(UART0,kind);
sprintf(data4,"%4d",Count);
LCD_P8X16Str(2,5,data4,BLUE,BLACK);
}
if(Count >= (E5-20) && Count <= (E5+20)){ //判断用电器5是否----插
kind = 5;
UART_Put_Char(UART0,kind);
sprintf(data5,"%4d",Count);
LCD_P8X16Str(2,6,data5,BLUE,BLACK);
}
if(Count >= (E6-20) && Count <= (E6+20)){ //判断用电器6是否----插
kind = 6;
UART_Put_Char(UART0,kind);
sprintf(data6,"%4d",Count);
LCD_P8X16Str(2,3,data6,BLUE,BLACK);
}
if(Count >= (E7-20) && Count <= (E7+20)){ //判断用电器7是否----插
kind = 7;
UART_Put_Char(UART0,kind);
sprintf(data7,"%4d",Count);
LCD_P8X16Str(2,3,data7,BLUE,BLACK);
}
}
if((CurrentValue0 > CurrentValue1) ){ //判断是否拔用电器
//判断是否拔用电器
Count = CurrentValue0 - CurrentValue1; //获取变化值
CurrentValue0 = CurrentValue1;
GPIO_Reverse(PORTE,26);
time_delay_ms(1000); //延时
if(Count >= (E1-20) && Count <= (E1+20)){ //判断用电器1是否----拔
kind = 10;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,2,"OFF ",RED,BLACK);
}
if(Count >= (E2-20) && Count <= (E2+20)){ //判断用电器2是否----拔
kind = 20;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,3,"OFF ",RED,BLACK);
}
if(Count >= (E3-20) && Count <= (E3+20)){ //判断用电器3是否----拔
kind = 30;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,4,"OFF ",RED,BLACK);
}
if(Count >= (E4-20) && Count <= (E4+20)){ //判断用电器4是否----拔
kind = 40;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,5,"OFF ",RED,BLACK);
}
if(Count >= (E5-20) && Count <= (E5+20)){ //判断用电器5是否----拔
kind = 50;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,6,"OFF ",RED,BLACK);
}
if(Count >= (E6-20) && Count <= (E6+20)){ //判断用电器6是否----拔
kind = 60;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,7,"OFF ",RED,BLACK);
}
if(Count >= (E7-20) && Count <= (E7+20)){ //判断用电器7是否----拔
kind = 70;
UART_Put_Char(UART0,kind);
LCD_P8X16Str(2,8,"OFF ",RED,BLACK);
}
}
}
sprintf(data8,"Value%4d",ADC_Ave(ADC0,ADC1_SE9,ADC_12bit,20));
LCD_P8X16Str(0,9,data8,CYAN,BLACK); //用电器1
time_delay_ms(500); //延时
GPIO_Reverse(PORTD,15);
}
}
接受信号的K60芯片程序
void main(void)
{
PLL_Init(PLL180); //初始化PLL为180M、
LCD_init(); //初始化TFT
DisableInterrupts; //禁止总中断
LCD_display_full(BLACK); //屏幕背景为黑色
LCD_P8X16Str(0,0,"AHNU: ZXF WJ ZSC",YELLOW,BLACK); //字符串输出
LCD_P8X16Str(0,1,"No. ON/OFF",WHITE,BLACK); //字符串输出
LCD_P8X16Str(0,2,"1",BLUE,BLACK); //用电器1
LCD_P8X16Str(0,3,"2",BLUE,BLACK); //用电器2
LCD_P8X16Str(0,4,"3",BLUE,BLACK); //用电器3
LCD_P8X16Str(0,5,"4",BLUE,BLACK); //用电器4
LCD_P8X16Str(0,6,"5",BLUE,BLACK); //用电器5
LCD_P8X16Str(0,7,"6",BLUE,BLACK); //用电器6
LCD_P8X16Str(0,8,"7",BLUE,BLACK); //用电器7
LCD_P8X16Str(0,9,"Just do it!",PURPLE,BLACK);
UART_Init(UART0,9600); //初始化UART0
while(1){
GPIO_Init(PORTC,0,GPO,0);
kind = UART_Get_Char(UART0);
GPIO_Init(PORTA,17,GPO,0);
switch(kind)
{
//用电器插入显示
case 1:
LCD_P8X16Str(8,2,"ON ",GREEN,BLACK); break; //用电器1插入
case 2:
LCD_P8X16Str(8,3,"ON ",GREEN,BLACK); break; //用电器2插入
case 3:
LCD_P8X16Str(8,4,"ON ",GREEN,BLACK); break; //用电器3插入
case 4:
LCD_P8X16Str(8,5,"ON ",GREEN,BLACK); break; //用电器4插入
case 5:
LCD_P8X16Str(8,6,"ON ",GREEN,BLACK); break; //用电器5插入
case 6:
LCD_P8X16Str(8,7,"ON ",GREEN,BLACK); break; //用电器6插入
case 7:
LCD_P8X16Str(8,8,"ON ",GREEN,BLACK); break; //用电器7插入
//用电器拔出显示
case 10:
LCD_P8X16Str(8,2,"OFF",RED,BLACK); break; //用电器1拔出
case 20:
LCD_P8X16Str(8,3,"OFF ",RED,BLACK); break; //用电器2拔出
case 30:
LCD_P8X16Str(8,4,"OFF ",RED,BLACK); break; //用电器3拔出
case 40:
LCD_P8X16Str(8,5,"OFF ",RED,BLACK); break; //用电器4拔出
case 50:
LCD_P8X16Str(8,6,"OFF ",RED,BLACK); break; //用电器5拔出
case 60:
LCD_P8X16Str(8,7,"OFF ",RED,BLACK); break; //用电器6拔出
case 70:
LCD_P8X16Str(8,8,"OFF ",RED,BLACK); break; //用电器7拔出
default:
LCD_P8X16Str(0,9,"Just do it!",CYAN,BLACK); break; //用电器等待插拔中
}
}
}