写在前面:这是这次参加电子设计大赛我写的设计报告,但是我本人现在对硬件不是很熟悉,所以很对原理叙述不是很到位啊,不过整个作品用到知识点和原理都基本说清楚了。
简易数字式电阻、电容和电感测量仪设计报告
摘要:本系统利用TI公司的16位超低功耗单片机MSP430F149和ICL8038精密函数发生器实现对电阻、电容和电感参数的测量。本系统以自制电源作为LRC数字电桥和各个主要控制芯片的输入电源,并采用ICL8038芯片产生高精度的正弦波信号流经待测的电阻、电容或者电感和标准电阻的串联电路,通过测量电阻、电容或者电感和标准电阻各自的电压,利用电压比例计算的方法推算出电阻值、电容值或者电感值。利用MSP430F149单片机控制测量和计算结果,运用自校准电路提高测量精度,同时用差压法,消除了电源波动对结果的影响。测量结果采用12864液晶模块实时显示。实验测试结果表明,本系统性能稳定,测量精度高。
关键词:LRC数字电桥、电压比例法、液晶模块、MSP430F149、电阻电容电感测量
目 录
一、设计内容及功能... 1
1.1设计内容... 1
1.2 具体要求... 2
1.3系统功能... 2
二、系统方案设计与选择... 2
三、系统设计... 3
3.1系统总体设计... 3
3.2系统模块设计... 4
四、理论分析与计算... 5
五、系统硬件设计... 5
5.1 电源电路... 5
5.2 LRC测量电路... 6
5.3 整流滤波电路... 6
六、系统软件设计... 8
6.1 控制测量程序模块... 8
6.2 按键处理程序模块... 8
6.3电阻电感电容计算程序... 9
6.4液晶显示程序模块... 10
七、系统测试... 10
7.1 测试原理... 10
7.2 测试方法... 10
7.3 测试仪器... 10
7.4 测试结果... 10
7.5 测试分析... 11
八、系统总结... 12
附件一、本系统的主要程序... 12
一、设计内容及功能
1.1设计内容
设计并制作一台简易数字式电阻、电容和电感参数测量仪,由测量对象、测量仪、LCD显示和自制电源组成,系统模块划分如下图所示:
1.2具体要求
1.测量范围
(1)基本测量范围:电阻100Ω~1MΩ;电容100pF~10000pF;电感100μH~10mH。
(2)发挥测量范围:电阻10Ω~10MΩ;电容50pF~10μF;电感50μH~1H。
2.测量精度
(1)基本测量精度:电阻±5%;电容±10%;电感±5%。
(2)发挥测量精度:电阻±2%;电容±8%;电感±8%。
3.利用128*64液晶显示器,显示测量数值、类型和单位。
4.自制电源
5.使用按键来设置测量的种类和单位
1.3系统功能
1.基本完成以上具体要求
2.使用三个按键分别控制R、C、L的测试
3.采用液晶显示器显示测量结果
二、系统方案设计与选择
电阻、电容、电感测试仪的设计目前有多种方案可以实现,例如、使用可编程逻辑控制器(PLC)、振荡电路与单片机结合或CPLD与EDA相结合等等来实现。在设计前本文对各种方案进行了比较:
方案一.基于模拟电路的测量仪
利用模拟电路,电阻可用比例运算器法和积分运算器法,电容可用恒流法和比较法,电感可用时间常数发和同步分离法等,虽然避免了编程的麻烦,但电路复杂,所用器件较多,灵活性差,测量精度低,现在已较少使用。
方案二.可编程逻辑控制器(PLC)
此方案采用PLC对硬件进行控制,应用较为广泛。它能够非常方便地集成到工业控制系统中。其速度快,体积小,可靠性和精度都较好,在设计中可采用PLC对硬件进行控制,但是用PLC实现价格相对昂贵,因而成本过高。
方案三.采用CPLD或FPGA实现
此方案则采用广泛应用的VHDL硬件电路描述语言,实现电阻,电容,电感测试仪的设计,利用MAXPLUSII集成开发环境进行综合、仿真,并下载到CPLD或FPGA可编程逻辑器件中,完成系统的控制作用。但相对而言设计规模大,系统结构复杂。
方案四.利用LRC数字电桥与单片机结合
利用LRC数字电桥将电阻、电容和电感参数转化为电压模拟信号,此模拟量由高精度AD转换芯片转换为数字量。这样由单片机处理数字量,能够满足测量精度高、易于实现自动化测量等设计需要,而且单片机构成的应用系统有较大的可靠性、系统扩展、系统配置灵活,容易构成各种规模的系统。
通过对上述方案的比较,利用LRC数字电桥与单片机结合实现电阻、电容、电感测试仪更为简便可行,节约成本。所以,本文选定以单片机为核心来实现对电阻、电容和电感测量的设计。
三、系统设计
3.1系统总体设计
本系统包括硬件设计和软件设计两部分内容。
硬件设计主要分为七部分:第一部分采用AMS1117芯片制作的电源,输出稳定的3.3V电压。第二部分为ICL8038芯片产生正弦波。第三部分用RC和RL电路实现LRC数字电桥的功能。第四部分是对正弦波进行精密滤波的功能。第五部分利用MSP430F149单片机自带的AD实现模拟信号转换为数字信号的功能。第六部分为MSP430F149单片机接收转换后的数字信号并做相应的处理,根据按键状态控制测量的类型和单位。第七部分为测量结果显示部分,采用的是128*64液晶显示器。
系统硬件总体框图如下:
图1系统硬件总体框图
软件由4部分组成:(1)控制测量程序,单片机控制测量程序不仅担负着量程的识别与转换,而且还负责数据的修正和传输;因此主控制器的工作状态直接决定着整个测量系统能否正常工作,所以控制测量程序对整个测量来说至关重要;(2)按键处理程序,根据按键的状态做相应的功能设置;(3)电阻电感电容计算程序,单片机根据A/D转换得到的电压值计算出电阻、电感或者电容值;(4)液晶模块显示程序。本系统的程序框图如图2所示。
图2程序框图
3.2系统模块设计
3.2.1电源模块
输入的外部电源首先经过桥式整流、滤波电路滤波,再经过AMS1117芯片稳压成3.3V的直流电压,向MSP430F149主控制器供电。
3.2.2信号产生模块
标准正弦波是保证测量仪的重要条件,特别是在测量电抗元件电容和电感时,正弦波的失真将产生难以修正的错误,直接影响测量精度,因此在该测量仪中为保证测量精度,采用了ICL8038芯片产生正弦波。ICL8038精密函数发生器是采用肖特基势垒二极管等先进工艺制作成的单片集成电路芯片,电源电压范围宽、稳定度高、易用等优点,外部只需接入很少的元件即可工作,可产生多种频率正弦波,其函数波形的频率受内部或外部电压控制。
3.2.3整流滤波模块
整流滤波模块采用LM324的集成运放和LC电路对LRC测试模块产生的信号进行整流滤波,因为测试模块产生的信号是正弦波,而AD采样没办法采集负信号,所以要通过整流滤波给后面的AD采样。因为整流滤波是高阻输入,但也不是无穷大,所以在做测试模块时,分压电阻最好小于100K。
3.2.4AD采样模块
本模块利用MSP430F149单片机自带的AD转换功能把整流滤波后的模拟信号转换为单片机能够处理的数字信号,并传送给处理器。
3.2.5主控制模块
本模块采用低功耗的MSP430F149微处理器控制AD装换,并对转换结果数据进行接收和处理;通过按键控制测量的类型和单位。
3.2.6显示模块
通过LCD驱动程序对MSP430F149处理后的结果数据进行稳定显示,在测试期间显示能够保持稳定状态,当离开测试能够迅速归零。
四、理论分析与计算
本系统主要的功能就是电阻、电容和电感的测量,因此对电阻、电容和电感测量的原理做详细的分析。
电阻高精度测量较好的方法之一是采用与标准电阻相比较的方法。其主要原理:是在待测电阻与标准电阻的串联电路中加一电流,这样和上将得到电压和,则测量电阻为:
在设计中,我们采用了与测量电阻相同的测量方法——电压相除法来测量电容和电感。由于电容和电感属电抗元件,因此不能采用直流来产生测量信号,而只能采用交流信号。在角频率为的交流信号的作用下,电容和电感获得的电压分别为:
为待测电容和电感。这样一来,标准元件的选择就有许多种方法。但为了提高测量精度和降低成本,该测量仪采用了标准电阻,且与电阻测量公用一套标准电阻。所以有:
经过计算可得:
其中的模值。由公式(5)、(6)式可见,为保证测量精度,必须保证电阻的精度和的高稳定值。为此,我们在该设计中采用了高精度的ICL8038芯片产生正弦波,同时输出缓冲器采用了运算放大器。为保证波形精度采用了闭环深度负反馈方式。此外,本设计中还采用了运算放大器补偿实现无失真AC-DC的转换,以确保测量精度。
五、系统硬件设计
5.1电源电路
MSP430F149微处理器需要3.3V电压供电,但是外部输入的电压通常不是3.3V的电压源,所以需要设计电路把外部输入电压转换为稳定的3.3V电压,如图3所示,采用的是AMS1117芯片,可以输出3.3V电压,然后经过滤波输出稳定的3.3V供给MSP430F149。
图3稳压3.3V产生电路
5.2LRC测量电路
如图4所示,LRC各元件的测量是通过基本的RR电路,RL电路和RC电路来进行的。当探针的两端接电阻元件时,此电路就组成的是基本的RR电路;当探针的两端接电容元件时,此电路就组成的是基本的RC电路;当探针的两端接电感元件时,此电路就组成的是基本的RL电路。输入的正弦波可以接频率为100HZ、1KZ和10KHZ。
图4LRC测量电路
5.3整流滤波电路
此电路采用LM324的集成运放和LC电路对LRC测试模块产生的信号进行整流滤波。因为测试电路产生的信号是正弦波,而AD采样没办法采集负信号,所以要通过电路整流滤波给后面的AD采样,电路图如图5所示。
图5整流滤波电路
整流滤波前的波形图如下图6所示。
图6整流滤波前的波形图
整流滤波后的波形图如下图7所示。
图7整流滤波后的波形图
六、系统软件设计
6.1控制测量程序模块
单片机控制测量程序不仅担负着量程的识别与转换,而且还负责数据的修正和传输;因此主控制器的工作状态直接决定着整个测量系统能否正常工作,所以控制测量程序对整个测量来说至关重要。控制测量流程图如图8所示。
图8控制测量程序流程图
6.2按键处理程序模块
按键处理程序的主要功能是设置测量的类型和测量的档位,当有按键被按下时就执行相应的按键功能,流程如图9所示。
图9按键处理程序流程图
6.3电阻电感电容计算程序
单片机根据A/D转换得到的电压值计算出电阻、电感或者电容值,该程序流程图如图10所示。
图10电阻电感电容计算程序流程图
6.4液晶显示程序模块
该程序模块只有一个功能,就是对测量结果清晰正确的显示出来,并能够保持稳定。程序流程图如图11所示。
图11液晶显示程序模块流程图
七、系统测试
7.1测试原理:在系统设计中,以MSP430F149单片机为核心的电阻、电容、电感测试仪,将电阻,电容,电感,使用对应的振荡电路转化为电压实现各个参数的测量。其中100HZ/1MHZ/10MHZ的正弦波是采用ICL8038芯片产生的,将模拟电压信号送入AD采样,通过AD把模拟信号转换为数字信号,再把数字信号送入MSP430F149单片机处理。以IAREmbeddedWorkbench为仿真平台,使用C语言编写了系统应用软件;包括主控制模块、显示模块、电阻测试模块、电容测试模块和电感测试模块。
7.2测试方法:在测试时将被测参数通过本系统测量出来的示值与参数的标称值进行对比,得到本系统的测量精度。
7.3测试仪器:示波器,万用表。
7.4测试结果:通过按键操作,实现测量类型和量程的选择,根据测量结果对设计进一步进行校正和对实现功能的可靠性的确认。
测试结果如下:
1.电阻测试数据如表1所示。
表1电阻测试数据
标称值 (Ω) |
系统测量 (Ω) |
相对误差 (%) |
20.0 |
20.01 |
0.05 |
200.0 |
199.77 |
0.115 |
6000.0 |
5993.75 |
0.104 |
50000.0 |
49926.63 |
0.147 |
301000.0 |
252990.00 |
15.950 |
2.电容测试数据如表2所示。
表2电容测试数据
读取示值 (pF) |
标称值 (pF) |
相对误差值 (%) |
104 |
100 |
4.0 |
34.1 |
33 |
3.3 |
9.2 |
10 |
8.0 |
3.电感测试数据如表3所示。
表3电感测试数据
读取示值 (mH) |
标称值 (mH) |
相对误差值 (%) |
219.47 |
218.29 |
0.54 |
16.68 |
16.55 |
0.78 |
0.862 |
0.854 |
0.93 |
7.5测试分析:
根据以上的测试结果表明,本系统完成了文章开始所提出设计内容和功能。本测量仪的测量范围较宽,并且达到了很好的精度,相对误差小于1%。
在实际测量中,由于测试环境,测试仪器,测试方法等都对测试值有一定的影响,都会导致测量结果或多或少地偏离被测量的真值。为了减小本设计中误差的大小,主要利用修正的方法来减小本测试仪的测量误差。所谓修正的方法就是在测量前或测量过程中,求取某类系统误差的修正值。在测量的数据处理过程中选取合适的修正值很关键,修正值的获得有三种途径。第一种途径是从相关资料中查取;第二种途径是通过理论推导求取;第三种途径是通过实验求取。
本测试修正值选取主要通过实验求取,对影响测量读数的各种影响因素,如温度、湿度、电源电压等变化引起的系统误差。通过对相同被测参数的多次测量结果和不同被测参数的多次测量选取平均值,最后确定被测参数公式的常数K值,从而达到减小本设计系统误差的目的。由于振荡电路外围器件由电容电阻分立元件搭接而成,所以由振荡电路产生的被测参数对应的频率有一定的误差,所以只能通过多次实验测量,选取合适的修正值来尽可能的减少本测试系统的误差。
八、系统总结
本系统采用单片机和LRC数字电桥结合的方式实现了一个简易数字式电阻、电容和电感测量仪,到达了系统基本要求。本仪器利用单片机技术实现了电感电容测量的智能化设计,而且系统性能稳定,测量精度较高,相对误差小于1%,操作简单,具有较强的实用性。
当然本系统还存在着许多需要改进的地方,比如还可以继续提高测量的精度和加大测量的范围。因为是采用单片机实现的,利用其可以编程的特性,使测量的值结合一些数据处理方式使测量更加接近真实值。
本系统也还有许多可以扩展的功能,可以增加语音功能,每次测量值稳定的时候就通过语音报告出来;也可以增加在线测量的功能,这样就更能够测量出元件工作时的正常值,而不仅仅是静态时的值。
1.LCD显示
/********************************************************************* 函数名称:DispStr 功 能:让液晶从某个位置起连续显示一个字符串 参 数:unsigned char *s s--指向字符串存放位置的指针 返回值 :无 *********************************************************************/ void DisStr(unsigned char *s) { while(*s>0) //是否是结束字符 { LcdWriteData(*s); //写字符 s++; _NOP(); } } /********************************************************************* 函数名称:LcdReset 功 能:对1602液晶模块进行复位操作 参 数:无 返回值 :无 *********************************************************************/ void LcdReset(void) { CtrlDir |= 0x70; //控制线端口设为输出状态 DataDir = 0xFF; //数据端口设为输出状态 Delay5ms(); LcdWriteCommand(0x30, 1); //规定的复位操作 Delay5ms(); LcdWriteCommand(0x30, 1); Delay5ms(); LcdWriteCommand(0x0c, 1); Delay5ms(); LcdWriteCommand(0x01, 1); //显示清屏 Delay5ms(); LcdWriteCommand(0x06, 1); //写字符时整体不移动 } /********************************************************************* 函数名称:LcdWriteCommand 功 能:向液晶模块写入命令 参 数:cmd--命令, chk--是否判忙的标志,1:判忙,0:不判 返回值 :无 *********************************************************************/ void LcdWriteCommand(uchar cmd,uchar chk) { if (chk) WaitForEnable(); // 检测忙信号? _NOP(); CLR_RS; CLR_RW; //写命令 _NOP(); DataPort = cmd; //产生使能脉冲信号 _NOP(); _NOP(); SET_EN; //将命令字写入数据端口 _NOP(); _NOP(); CLR_EN; } /********************************************************************* 函数名称:LcdWriteData 功 能:向液晶显示的当前地址写入显示数据 参 数:data--显示字符数据 返回值 :无 *********************************************************************/ void LcdWriteData( uchar data ) { WaitForEnable(); //等待液晶不忙 _NOP(); SET_RS; CLR_RW; //写数据 _NOP(); DataPort = data; //产生使能脉冲信号 _NOP(); SET_EN; //将显示数据写入数据端口 _NOP(); _NOP(); CLR_EN; } /********************************************************************* 函数名称:WaitForEnable 功 能:等待1602液晶完成内部操作 参 数:无 返回值 :无 *********************************************************************/ void WaitForEnable(void) { uchar lcdtemp = 0; DataDir &= 0x00; //将P5口切换为输入状态 CLR_RS; //指令 SET_RW; //读读忙状态 _NOP(); SET_EN; //使能信号 _NOP(); _NOP(); do //判忙 { SET_EN; _NOP(); lcdtemp = DataIn; CLR_EN; } while(lcdtemp & Busy); CLR_EN; DataDir |= 0xFF; //将P4口切换为输出状态 }
2.主函数程序
/************************主函数****************************/ void main(void) { WDTCTL = WDTPW+WDTHOLD; //关闭看门狗 LcdReset(); //12864位液晶初始化 P6SEL |= 0x06; // 使能ADC通道 1,2 ADC12CTL0 = ADC12ON+SHT0_8+MSC; // 打开ADC,设置采样时间 ADC12CTL1 = SHP+CONSEQ_3; // 使用采样定时器 ADC12MCTL1 = INCH_1; //通道1选择 ADC12MCTL2 = INCH_2+EOS; //通道2选择,并设为结束通道 ADC12IE = 0x06; // 使能ADC中断 ADC12CTL0 |= ENC; // 使能转换 _EINT(); //全局使能 ADC12CTL0 |= ADC12SC; // 开始转换 LPM0; //进入CPU低功耗模式 } /******************************************* 函数名称:ADC12ISR 功 能:ADC中断服务函数,在这里用多次平均的 计算P6.0口的模拟电压数值 参 数:无 返回值 :无 ********************************************/ #pragma vector=ADC_VECTOR __interrupt void ADC12ISR (void) { countNum++; int temp; ADC12CTL0 &=~ADC12SC; // 停止采样转换 if(ADC12IFG & 0x02) { temp = ADC12MEM1; max_result1 = temp>max_result1?temp:max_result1; ADC12IFG &= ~0X02; } if(ADC12IFG & 0x04) { temp = ADC12MEM2; max_result2 = temp>max_result2?temp:max_result2; ADC12IFG &= ~0X04; } /***********************************************************************/ /* 采样输出电压峰峰值 */ /***********************************************************************/ volt_result1 = max_result1*2.0/4096.0*3.3; sprintf(volt_buff,"电压1:%.6fV",volt_result1); LcdWriteCommand(0X80,1); DisStr(volt_buff); //显示输出电压单位 /***********************************************************************/ /* 采样输入电压峰峰值 */ /***********************************************************************/ volt_result2 = max_result2*2.0/4096.0*3.3; sprintf(volt_buff,"电压2:%.6fV",volt_result2); LcdWriteCommand(0X90,1); DisStr(volt_buff); //显示输入电压单位 /***********************************************************************/ /* 用公式计算电感 */ /***********************************************************************/ /* 电感公式 midTemp = sqrt(volt_result2*volt_result2-volt_result1*volt_result1); midTemp = volt_result2*Rref/midTemp; midTemp = midTemp - Rref*Rref; midTemp = sqrt(midTemp); Ctrial = midTemp/2*PI*f0; */ /*电容公式 midTemp = 2*PI*f0*Rref*volt_result1; Ctrial = volt_result2/midTemp; */ /* midTemp = volt_result2/volt_result1-1; Ctrial = midTemp/(2*PI*f0*Rref); */ midTemp = volt_result2*volt_result2; midTemp = midTemp/(midTemp-volt_result1*volt_result1); midTemp --; midTemp = sqrt(midTemp); midTemp = 2*PI*f0*Rref*midTemp; Ctrial = 1/midTemp; sprintf(R_Buff,"电容:%.4ef",Ctrial); LcdWriteCommand(0X88,1); DisStr(R_Buff); //采样1000次,重新采样 if(countNum==1000) { countNum = 0; max_result1 = 0; max_result2 = 0; } ADC12CTL0 |= ADC12SC; // 开始采样 }