50HZ正弦交流信号有效值的测量V3.0
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
目录
摘要 (I)
1. 设计原理 (1)
2. 系统硬件设计 (1)
2.1电阻分压以及阻抗匹配模块 (1)
2.2 有效值检波模块 (2)
2.3 ADS1115电压检测模块 (3)
2.4单片机控制及显示模块 (3)
2.5系统整体原理图 (4)
3程序框图 (5)
4资源分配表 (5)
5源程序 (6)
5.1主程序 (6)
5.2液晶显示程序 (8)
5.3 ADS1115启动程序 (11)
6性能分析 (19)
6.1实物测试图 (19)
6.2测量数据分析 (20)
7总结与体会 (21)
参考文献 (22)
摘要
有效值能直接反应交流信号的能量大小,具有简单的叠加性,计算起来方便,对于研究功率、噪声、失真度、频谱纯度等有十分重要的作用。
因此,有效值在实际应用中使用十分广泛。
本文主要介绍了对50HZ正弦交流信号有效值的测量方法的设计与实现。
根据要求,测量电路由电阻分压网络、基于OPA277的阻抗匹配模块、基于AD637的有效值检测模块以及基于ADS1115的电压测量模块组成,控制部分选用STC89C52单片机,所测量的有效值通过LCD1602显示。
关键词:有效值、AD637、STC89C52单片机
1. 设计原理
图1 系统整体结构图
由图1系统整体框图可知,此测量有效值系统主要由分压网络、阻抗匹配、有效值检波、电压测量、单片机控制以及液晶显示等模块组成。
题目要求的输入信号输入范围为0~15V ,这远远大于一般有效值检波以及AD 转换芯片的输入电压值,因此,在前级需要加一级电阻分压网络,将输入信号的幅值衰减一般,使其适合测量。
本系统选用的有效值检波模块基于AD637芯片,AD637是一个高精度RMS-DC 转换芯片,但其输入阻抗较小,在信号输入前通过一级运算放大器进行阻抗匹配,提升电路整体的稳定性,经过AD637的转换,输出对应交流信号的直流有效值,在单片机的控制下,ADS1115进行电压检测,并将检测的值返回给单片机通过LCD1602显示。
此系统对控制芯片的要求并不高,选用52单片机足以实现所需求的功能。
单片机首先对内部定时器以及LCD1602进行初始化后,进入等待模式,当达到所设定的时间时,进入中断开启ADS1115进行电压值的测量,并将测量值通过LCD1602显示,之后退出中断等待下一次中断的来临。
2. 系统硬件设计
2.1电阻分压以及阻抗匹配模块
由于题目所要求的电压范围为0~15V ,大于一般芯片的测量范围,因此采用两个10K 的电阻进行分压,使输入信号衰减一半,如图2所示,衰减后的信号1/2电阻分压网
络阻抗匹配有效值检波ADS1115测量有
效值
单片机控制
LCD1602显示有
效值信号输入
通过OPA277进行阻抗匹配,以提升系统整体的稳定性。
图2 电阻分压及阻抗匹配电路
2.2 有效值检波模块
为了实现对有效值
的检测,需先将交流信
号转化成直流有效值,
如图3所示,在此系统
中,选用AD637完成此
功能。
AD637是一款完
整的高精度、单芯片均
方根直流转换器,可计
算任何复杂波形的真均
方根值。
它提供集成电
路均方根直流转换器前
所未有的性能,精度、带宽图3 有效值检波电路
和动态范围与分立和模块式设计相当。
AD637提供波峰因数补偿方案,允许以最高为10的波峰因数测量信号,额外误差小于1%。
宽带宽允许测量200 mV均方根、频率最高达600 kHz的输入信号以及1 V均方根以上、频率最高达8 MHz 的输入信号。
片内缓冲放大器既可以用作输入缓冲,也可以用于有源滤波器配置。
该滤波器可以用来降低交流纹波量,从而提高精度。
满足题目对精度0.01V,误差小于0.02V的要求。
2.3ADS1115电压检测模块
经过前级AD637的转换,输入ADS1115的信号为直流有效值,ADS1115是具有16位分辨率的高精度模拟到数字转换器(ADC),其数据传输通过一个2I C 兼容串行接口,四个2I C从地址,由2.0V至5.5V单电源供电。
ADS1115可以执行转换速率高达每秒860个样本(SPS)。
板载PGA的ADS1115提供从电源的输入范围为±256mV的低,允许大型和小型的信号进行高分辨率测量。
如图4所示,使用ADS1115测量电压,足以满足精度的要求。
图4 ADS1115电压检测电路图
2.4单片机控制及显示模块
系统的控制部分由52单片机实现,单片机具有体积小,操作方便,应用灵活,运行稳定准确等特点,现以广泛应用于各领域。
此系统对控制部分要求不高,在单片机最小系统的基础上增加一些基本外设即可。
如图5所示,最小系统由单片STC89C52、复位电路、振荡电路组成,振荡电路为单片机工作提供时钟源,但程序跑飞的时候,可通过控制电路使程序从头开始执行。
图中与单片机相连的是LCD1602液晶显示屏,1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5*7或者5*11等点阵
字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。
通过单片机控制LCD1602可显示设定的英文字符和数字等信息。
图5 单片机控制及显示电路
2.4系统整体原理图
如图6所示,是此系统的整体电路图。
图6 系统整体电路图
3程序框图
如图7所示,是此系统的程序流程框图。
开始
初始化
LCD1602
初始化定时器
等待中断
否
定时到达设定
时间
是
开启ADS1115
测量电压
显示测量电压
值
图7 程序流程图
4 资源分配表
为实现此系统,单片机的资源分配如表1所示。
表1 单片机资源分配表
5 源程序
5.1 主程序
#include "LCD1602.h"
#include "ads1115.h"
char i=0,flag;
char show_zifu[]={"Design by lq"}; float resultdata=0;
void set_time()
{
//定时1ms
EA = 1;
TMOD |= 0X01;
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
TF0 = 0;
}
void main()
{
lcd_init();
set_time();
for(i=0;i<12;i++)
{
lcd_sendcmd(0x80+i);
lcd_senddat(show_zifu[i]);
}
lcd_sendcmd(0xc0);
lcd_senddat('V');
lcd_sendcmd(0xc1);
lcd_senddat(':');
while(1)
{
if(flag == 1)
{
resultdata = AD_last(0) *2;
lcd_show_float(0xc2,resultdata);
flag = 0;
}
}
}
void inter() interrupt 1
{
static uint j=0;
j++;
while(j==200)
{
flag = 1;
j=0;
}
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
TR0 = 1;
TF0 = 0;
}
5.2液晶显示程序
#ifndef __LCD1602_H__
#define __LCD1602_H__
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
/************
各IO口声明
************/
sbit LCD1602_EN=P0^5;
sbit LCD1602_RW=P0^6;
sbit LCD1602_RS=P0^7;
#define lcd_DATA P2
/****************
各io口定义值的替换
*****************/
#define LCD1602_EN_H LCD1602_EN = 1 #define LCD1602_EN_L LCD1602_EN = 0 #define LCD1602_RW_H LCD1602_RW = 1 #define LCD1602_RW_L LCD1602_RW = 0
#define LCD1602_RS_H LCD1602_RS = 1 #define LCD1602_RS_L LCD1602_RS = 0
/***************
子函数名
****************/
void delay(uint s);
void lcd_input_byte(uchar byte);
void lcd_sendcmd(uchar cmd);
void lcd_senddat(uchar dat);
void lcd_init();
void lcd_show_float(uchar add,float num);
/**************
***************/
#endif
#include "LCD1602.h"
void delay(uint s)
{
uint i,j;
for (i=0;i<s;i++)
for (j=1;j<=110;j++) ;
}
void lcd_input_byte(uchar byte)
{
LCD1602_RW_L;
lcd_DATA = byte;
LCD1602_EN_L;
LCD1602_EN_H;
delay(10);
}
void lcd_sendcmd(uchar cmd)
{
LCD1602_RS_L;
lcd_input_byte(cmd);
}
void lcd_senddat(uchar dat)
{
LCD1602_RS_H;
lcd_input_byte(dat);
}
void lcd_init()
{
lcd_sendcmd(0x38); /*设置2行数据,5*7数据*/ lcd_sendcmd(0x38);
lcd_sendcmd(0x08); /*显示关闭*/
lcd_sendcmd(0x01); /*显示清屏*/
lcd_sendcmd(0x06); /*显示光标移动设置*/
lcd_sendcmd(0x0c); /*显示开及光标移动*/ delay(50);
}
void lcd_show_float(uchar add,float num)
{
uchar temp[6]={"00.00V"},i;
int show_num;
show_num = num * 100; //保留两位小数temp[0] = show_num /1000 +'0';
temp[1] = show_num /100%10 +'0';
temp[3] = show_num /10%10 +'0';
temp[4] = show_num %10 +'0';
for(i=0;i<6;i++)
{
lcd_sendcmd(add + i);
lcd_senddat(temp[i]);
}
}
5.3 ADS1115启动程序
/**********ADS1115驱动程序头文件*******/ #include <reg52.h>//定义头文件
#define uchar unsigned char
#define uint unsigned int
#define u8 unsigned char
#define u16 unsigned int
#define ulong unsigned long
void delay_1115(uint ms);
void AD_Start(void);
void AD_Stop(void);
void Send_byte(uchar byte);
uint Read_byte(void);
void AD_Config(uchar channel);
void Point(void);
u16 Read_result(void);
float AD_last(uchar channel_ad);
/**********ADS1115 AD1 驱动程序*******/ #include <reg52.h>//定义头文件
#include "ads1115.h"
sbit AD1115_SCL=P0^0;
sbit AD1115_SDA=P0^1;
#define SCL_H AD1115_SCL = 1
#define SCL_L AD1115_SCL = 0
#define SDA_H AD1115_SDA = 1
#define SDA_L AD1115_SDA = 0
uchar Initdata[4];
u16 result=0;
void delay_1115(uint ms)
{
u16 a;
while(ms--)
{
a=120;
while(a--);
}
}
/**************************
函数名称:void AD_Start(void)
函数功能:ADS1115开始通信信号返回值:无
**************************/ void AD_Start(void)
{
SDA_L;
delay_1115(2);
SCL_H;
delay_1115(1);
SDA_H;
delay_1115(2);
SDA_L;
SCL_L;
delay_1115(2);
}
/**************************
函数名称:void AD_Stop(void)
函数功能:ADS1115结束通信信号返回值:无
**************************/ void AD_Stop(void)
{
SDA_L;
SCL_H;
SDA_H;
}
/**************************
函数名称:void Send_byte(uchar byte)
函数功能:ADS1115单字节传输
返回值:无
**************************/
void Send_byte(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
if((byte<<i)&0x80) //从高位开始传
SDA_H;
else SDA_L;
SCL_H;
delay_1115(1);
SCL_L;
}
SDA_H;
SCL_H;
delay_1115(1);
SCL_L;
// delay_ms(1);
}
/**************************
函数名称:void Read_byte(void)
函数功能:ADS1115 read a byte
返回值:temp
uint Read_byte(void)
{
uchar temp=0,flag;
uchar i;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL_L;
delay_1115(1);
SCL_H;
delay_1115(1);
flag = P0;
if( flag & 0x02) //数据位为1
temp|=0x01;
delay_1115(1);
}
SCL_L; // ACK 结束时序
delay_1115(1);
SDA_L;
SCL_H;
delay_1115(1);
SCL_L;
SDA_H;
return temp;
}
函数名称:void AD_Config(uchar channel)
函数功能:ADS1115 channel choose
返回值:无
**************************/
void AD_Config(uchar channel)
{
uchar channel_code=0;
uchar i;
switch(channel)
{
case 0:channel_code=0xc2;break; //通道0配置寄存器的高8位
case 1:channel_code=0xd2;break; //通道1
case 2:channel_code=0xe2;break; //通道2
case 3:channel_code=0xf2;break; //通道3
default: break;
}
Initdata[0]=0x90;// address and write command 地址为0x90
Initdata[1]=0x01;// points to Config register
Initdata[2]=channel_code; // congfig the high byte ,choose the channel Initdata[3]=0xe3; //speed:860sps ,
SCL_H;
AD_Start();
for(i=0;i<4;i++)
{
Send_byte(Initdata[i]);
delay_1115(1);
}
AD_Stop();
}
/**************************
函数名称:void Point(void)
函数功能:ADS1115 write to pointer register 返回值:无
**************************/
void Point(void) //配置pointer register
{
SCL_H;
AD_Start();
Send_byte(0x90);
delay_1115(1);
Send_byte(0x00);
delay_1115(1);
AD_Stop();
delay_1115(1);
}
/**************************
函数名称:uchar Read_result(void)
函数功能:read ADS1115's conversation result 返回值:result
**************************/
u16 Read_result(void)
{
uchar result_L=0,result_H=0;
SCL_H;
AD_Start();
delay_1115(1);
Send_byte(0x91);
delay_1115(1);
delay_1115(1);
result_H=Read_byte();
delay_1115(1);
result_L=Read_byte();
delay_1115(1);
AD_Stop();
result=result_H*256+result_L; //即高位结果向左移8位与低8位构成一个字return result;
}
/**************************
函数名称:uchar AD_last(void)
函数功能:get the last result
返回值:last
**************************/
float AD_last(uchar channel_ad)
{
float last2=0;
u16 last1=0;
AD_Config(channel_ad);//选择通道
delay_1115(5);
Point();
delay_1115(5);
last1=Read_result(); //正值最大为0x7fff,选取FS为4.096
last2=4.096*(last1/32768.0);
return last2;
}
6性能分析
6.1实物测试图
图8 系统实物图
图9 输入1Vpp信号测量图图10 输入5Vpp信号测量图图11输入10Vpp信号测量图图12 输入15Vpp信号测量图
图8为整套系统实物图,主要由电源模块、峰值有效值转换模块、A/D电压检测模块以及单片机控制模块组成。
图9至图12为实测的数据,分别对应峰峰值为1V、5V、10V、15V时,本系统所检测的有效值通过LCD1602显示。
6.2测量数据分析
由表2数据可知,对于50HZ幅值在0~15Vpp的正弦交流信号,本系统能有效测量其有效值,测量显示的分辨率为0.01V,误差随输入信号幅值的不同略有变化,总体控制在0.02V内,在有些输入电压值上误差为零,平均绝对误差在0.01V左右。
综上所述,本系统能够满足题目对测量范围,分辨率以及误差的要求。
若记录多次测量的结果并通过拟合的方法可得出一套更加毕竟真实值的公式,再通过编程对测量的结果进行软件补偿,可使误差范围更加小。
7总结与体会
本次课程设计至此已经接近尾声,一周的时间虽然很短暂,但在这一个星期的设计过程中收获颇丰。
整个课程设计过程中首先对《单片机原理与应用》这门课程有了更深的了解,因为课程设计本身要求将以前所学的理论知识运用到实际的电路设计当中去,在电路的设计过程中,无形中便加深了对A/D转换芯片的了解及运用能力,对课本以及以前学过的知识有了一个更好的总结与理解;以前的单片机实验只是针对某一个小的功能设计,而此次课程设计对我的总体电路和程序的设计的要求更严格,需要通过翻阅复习以前学过的知识确立了实验总体设计方案,然后逐步细化进行各模块的设计。
在这次课程设计中,我学会了怎样去根据课题的要求去设计电路和调试电路。
实验中暴露出我在理论学习中所存在的问题,有些理论知识还处于懵懂状态通过课程设计加深了我对所学知识的理解。
从中我发现自己并不能很好的去使用我所学到的知识。
在以后学习中我要加强对使用电路的设计和选用能力,锻炼自己的动手实践能力。
这周下来,我对电路故障的排查能力有了很大的提高,在整个设计过程中我懂得了许多东西,也培养了独立思考和设计的能力,树立了对知识应用的信心,相信会对今后的学习工作和生活有非常大的帮助,并且提高了自己的动手实践操作能力,使自己充分体会到了在设计过程中的成功喜悦。
通过此次课程设计,我对设计所用到的软件有了更加深刻地了解,这对我们以后的工作和学习的帮助都很有用处。
参考文献
[1]李晓林.单片机原理与接口技术(第二版).北京.电子工业出版社.2011
[2]谢自美.电子线路设计实验测试(第三版).武汉.华中科技大学出版社.2006
[3]高峰.单片微机应用系统设计及实用技术.北京.机械工业出版社.2004
[4]霍孟友.单片机原理与应用.北京.机械工业出版社.2004
[5]吴友宇.模拟电子技术基础.北京.清华大学出版社.2009。