位移测量装置设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
位移测量装置
杨明朱玉周磊
摘要:系统以LSD-TEST430F2274单片机为核心控制器件,控制电机转动和ADS7886实时采集数据、数据显示。
电机转动通过螺杆带动铁淦氧磁棒精确移动,从而改变线性变压器的输出电压。
在信号产生部分,采用专用函数发生器芯片MAX038产生100KHZ的正弦波信号,经过宽带低失真全微分运算放大器THS4503转换为两路幅值相等相位相反的信号,通过差分变压器中铁心位置的改变使得输出信号的幅值改变,再经过放大、整流滤波,经数据采集模块采集,送入单片机进行处理,最后通过液晶显示测量数据。
关键词:位移测量MAX038 THS4503 数据显示
一、方案选择与论证
由题意可知,整个系统主要分为激励电路和测量电路两个部分。
激励电路包含正弦信号产生和差分输出两个模块;测量电路由线性可变差动变压器、放大和整流滤波、数据处理、位移量显示四个模块组成。
系统框图如图1所示。
图1 位移测量装置系统框图
1.正弦信号产生电路的选择
方案一:采用MAX038芯片制作正弦信号产生电路。
MAX038是美国马克西姆公司开发的新一代函数发生器芯片,它克服了以前函数发生器集成芯片的缺点,提高了技术指标,频率更高,精度更好,占空比可调,波形失真小,且外围电路简单,容易制作。
方案二:采用DDS芯片制作正弦信号产生电路。
DDS技术具有相对带宽宽、频率转换时间短、频率分辨率高等优点,输出相位连续,频率、相位和幅度均可实现程控。
但其成本较高,且题目只对输出波形频率及失真度有相应要求,用MAX038完全可以满足题意要求。
经过上述分析,这里采用方案一。
2.放大、整流滤波电路的选择 (1)放大电路的选择
采用低噪音高速精密运算放大器OP37作为放大模块。
(2)整流滤波电路的选择
采用IN4148二极管和一个100uF 的电容组成整流滤波电路,该电路虽然结构简单,但却能很好的满足要求,减少了焊接和接线的复杂程度。
3.电机驱动模块的选择
方案一:采用专用芯片L298N 作为电机驱动芯片。
L298N 是一个具有高电压大电流的全桥驱动芯片,它相应频率高,还具有控制使能端。
用该芯片作为电机驱动,操作方便,稳定性好,性能优良。
方案二:对于直流电机用分立元件构成驱动电路。
由分立元件三极管构成电机驱动电路,结构简单,价格低廉,在实际应用中应用广泛。
但是这种电路工作性能不够稳定。
基于上述方案的比较,我们选用方案一。
4.电机驱动磁棒移动装置
采用顶杆与螺帽来驱动磁棒移动。
该装置的示意图如图2所示。
该方案利用直流电机的正反转来控制螺帽在顶杆上滑动并带动套筒向上或向下运动,从而使磁铁棒上下移动,通过改变磁通来达到改变电压的目的。
该电路控制精确度高,只要掌握好对电机的控制,就能很好的完成题目要求。
5.总体方案
经过仔细比较论证,最终方案确定如下:采用LSD-TEST430F2274单片机为核心控制器件,采用MAX038产生正弦波信号,差分输出用THS4503,采用OP37作为放大电路,整流滤波用1N4148二极管与一个100uF 的电容组合而成,用一片ADS7886和一个模拟开关组成电压采集模块,人机交流模块采用键盘和12864液晶。
二、设计实现与理论分析计算
1.激励电路分析与设计
(1)正弦波信号产生模块
在正弦波产生模块,我们用MAX038芯片设计了一个正弦波信号发生器,其电路图如图3所示。
图2 电机驱动磁棒移动装置
信号产生级的核心器件为MAX038,它的输出波形由波形设定端A0、A1控制,将这两个端口全部接高电平,这样它的输出就只有正弦波一种波形。
MAX038的输出频率F0由Iin , FADJ 端电压和主振荡器COSC 的外接电容器CF 三者共同决定。
外接电容器用一个1nF 的电容,则输出频率可达到10KHZ-1MHZ 范围内任一值。
通过调节电位器RP1和RP2就可以得到题目所需的100KHZ 的信
号,RP1为粗调,RP2为细调。
为简化电路,将DADJ 端接地,使波形的占空比固定为50%.
(2)差分输出电路
按照题目意思,我们采用THS4503设计差分输出电路。
电路图如图4。
THS4503是TI 公司的一款高性能的全微分放大器芯片,14脚运行时为40MHZ 的通频带,完全能满足题目要求。
2.测量电路分析、设计与计算
差分输出的信号经线性可变差动变压器的L1通过磁棒耦合到L2、L3,经过放大、整流滤波后,由信号采集模块采集并送入单片机进行处理。
单片机控制电机的正反转来使磁棒上下移动,从而使L2、L3 两路信号的电压相对于0点(两路信号的电压幅值相等相位相反)时的幅值产生相应的偏差。
由于得到的电压差值很小,所以需要采用OP37放大器对输出电压放大后再对信
号进行处理。
而要得到d 值,则要将交
流变成直流,在此我们采用半波整流。
整流之后,采用一个100uF 的电解电容滤除杂波。
线性可变差动变压器中磁铁与线圈对输出电压幅值的控制:通过试验及相关经验,我们选择变压器的L1 、L2、L3分别绕直径为0.13mm 的漆包线100圈。
其具体步骤为:用塑料管作为线圈的骨架,将漆包线分为两层紧密不重叠的绕在塑料管上,第一层分为L2和L3 ,在L2与L3的交界点引出两根接地线(中心轴头),第二层为L1且必须注意L 2和L 3的绕制位置应严格对称于
L1的中心位置。
电机驱动磁铁部分采用顶杆与螺帽来驱动磁棒移动,利用单片机控制电机的正反转来控制螺帽在顶杆上滑动
图3 MAX038正弦信号产生电路
图4 THS4503差分输出电路
并带动套筒向上或向下运动。
磁棒与顶杆通过绝缘材料相连,由磁铁在线圈中移动时磁通量的变化来控制耦合能量的大小,从而也就控制了输出电压的幅值。
在具体测量前,先通过实验在绝缘板上标出一个零点,零点位置必须满足L2、L3两端的对地电压幅值相等相位相反。
(1)放大、整流滤波电路
这部分放大电路我们采用OP37芯片,电路图如图5。
由电路图可知,OP37的放大倍数可以通过调节电位器来改变。
整流滤波电路很简单,由一个1N4148二极管和一个100uF 的电容构成。
(2)数据采集模块
单片机通过对A 、B 两点电压信号的处理即可得出位移量,因此在A 、B 两点后面应接一个模数转换的模块,考虑到接两片ADS7886不仅电路复杂,而且占用单片机端口过多,我们采用一片ADS7886加一个
模拟开关来代替两片ADS7886,电
路图如图6。
3.数据处理原理分析
信号经过放大、整流滤波后,我们采用ADS7886和模拟开关CD4051组成的数据采集模块进行电压采样,并将采样得到的数据传输到单片机进行处理。
为了能够显示位移量,我们先测试大量磁棒移动与
L1、L2两端电压变化的数据,然后通过MATLAB 软件中最小二乘法得到两段拟合曲线(如图7),分析该曲线,我们可以从中可以得到一个算法,然后在单片机中用软件实现该算法就能很好处理数据,从而实现实时显示位移量。
图7第一段曲线
图6 数据采集电路
图8第二段曲线
通过上面曲线得到的算法可以让精度保证在2mm以内,数据如下:
第一段误差:Columns 1 through 13
-1.5141 -0.8555 -0.6216 0.1504 0.4807 0.4409 0.6821 1.0365 0.8920 0.7310 0.1045 0.3188 -0.2564
Columns 14 through 25
-0.7835 -0.3784 -0.6542 -0.4569 -0.3752 0.0935 0.7920 0.2206 -0.9665 0.0863 -0.8489 1.6817
第二段误差:table =
-0.2427 0.1725 0.2447 -0.0383 -0.2787 -0.0836 0.2217 -0.4231 0.7845 -0.6778 -0.3390
三、系统软件设计及流程图
整个系统软件控制的地方并不多,主要是控制电机运行来改变磁棒的位置,
控制模拟开关和A/D转换采样数据。
系统软件流程图如图9。
四、系统测试
1.测试仪器
万用表,示波器,带刻度的磁棒。
2.测试方法
将整个系统组装好,开启电源,用示波器在C点测试输出波形,看正弦波是
否失真。
在A、B两点分别用万用表测量两点输出电压。
用单片机控制电机的转速,使得磁棒按一定精度移动,记录液晶显示的数据,并记下磁棒上刻度显示的
实际位移。
通过键盘,在测量范围内任意输入一个值,通过单片机控制电机转速,
使磁棒移动到相应的位置,记录输入数据和磁棒刻度显示的实际值。
3.测试数据分析和结论
(1)差动变压器输出信号失真度的测试(测试点为C点)
测试结果分析:
通过以上数据可以看出,整个系统实现了基本部分和发挥部分的要求,数据还存在一定的误差,误差产生的原因主要有以下几个方面:耦合线圈的绕制不够精细;测量时仪器精度的误差;外界干扰等。
本系统实现了单片机精确控制电机旋转带动磁棒移动,从而改变变压器副边电压的功能,还实现了单片机对数据的精确处理测量位移的功能。
本设计创新之处在于通过MATLAB中最小二乘法分析数据,并从中找出相关规律,便于实现软件算法对数据的精确控制。
然而在制作工艺方面如耦合线圈的绕制方面还存在不足。
如果时间允许,我们将会进一步完善整个系统。
附 录
1.元件清单
2.整体电路图
3.主函数程序
#include "msp430x22x4.h" #include "ADS7886.h" #include "JM12864.h" #include "ADS7886.c" #include "JM12864.c" #include "key.c" #include "key.h" #define ABDIR P3DIR #define ABOUT P3OUT #define AB BIT3
#define setA P3OUT|=BIT3
#define setB P3OUT&=~BIT3
//----------------------------------
int go();
void back();
void stop();
unsigned int A();
unsigned int B();
void CLK_INIT( void );
unsigned int AD_Data_ACompositor( void ); unsigned int AD_Data_BCompositor( void );
void LCD_Display_Delay( unsigned int dtime ); unsigned int AD_DATA_A[7] = {0};
unsigned int AD_DATA_B[7] = {0};
unsigned int d_DATA[7] = {0};
unsigned int DATA[7] = {0};
unsigned char displayA[5] = {0,'.',0,0}; unsigned char displayB[5] = {0,'.',0,0}; unsigned char display_data[7]={0,'.',0,0,0,0}; unsigned char display_Ddata[5] = {0,0,'.',0,0}; unsigned char set_Data[3] = {0,0};
int Adata,Bdata,Data,averaged,averageD; unsigned int ad_count = 0;
float averageA,averageB;
float ddata,vdata;
float k,l;
float data,Ddata;
unsigned int d();
unsigned int D();
unsigned int dCompositor( void );
unsigned int DCompositor( void );
unsigned int dSampling();
unsigned int DSampling();
//----------------------------------
int main( void )
{
P2DIR |=BIT4 + BIT5;
P2OUT &=~0X30;
P3DIR|=BIT3;
unsigned int i,w;
unsigned int y;
WDTCTL = WDTPW + WDTHOLD;
ADS7886_DIR |= ADS7886_CS + ADS7886_SCLK; CLK_INIT();
LCD_Init();
for(i=0;i<100;i++)
{
LCD_Clear();
LCD_Writestring(2, 1, "位移测量装置");
LCD_Display_Delay(500);
}
while(1)
{
y=value();
w=y;
for(;w>0;w--)
{go();}
k=A();
l=B();
if(k>l)
{ d(); }
if(k<=l)
{
vdata=(l-k)/(k+l);
averaged=(10000*vdata);
display_data[0]=averaged/10000;
display_data[2]=(averaged%10000)/1000; display_data[3]=(averaged%1000)/100; display_data[4]=(averaged%100)/10;
display_data[5]=averaged%10;
display_data[0]+=0x30;
display_data[2]+=0x30;
display_data[3]+=0x30;
display_data[4]+=0x30;
display_data[5]+=0x30;
LCD_Writestring(3, 0, "d=- ");
LCD_Writestring(3, 2, display_data); LCD_Writestring(3, 7, " ");
}
Data=averageA+ averageB;
display_Ddata[0]=0;
display_Ddata[1]=0;
display_Ddata[3]=0;
display_Ddata[4]=0;
display_Ddata[0]+=0x30;
display_Ddata[1]+=0x30;
display_Ddata[3]+=0x30;
display_Ddata[4]+=0x30;
set_Data[0]=y/10;
set_Data[1]=y%10;
set_Data[0]+=0x30;
set_Data[1]+=0x30;
LCD_Writestring(2, 0, "A=");
LCD_Writestring(2, 1, displayA);
LCD_Writestring(2, 3, "V,");
LCD_Writestring(2, 4, "B=");
LCD_Writestring(2, 5, displayB);
LCD_Writestring(2, 7, "V");
LCD_Display_Delay(500);
LCD_Writestring(1, 0, "请输入位移:"); LCD_Writestring(1, 6, set_Data);
LCD_Writestring(1, 7, "mm");
LCD_Writestring(4, 0, "位移量");
LCD_Writestring(4, 4, display_Ddata); LCD_Writestring(4, 7, "mm ");
LCD_Display_Delay(500);
}
}
//-------------------------------------
void CLK_INIT( void )
{
unsigned int n;
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALBC1_16MHZ;
do
{
IFG1 &=~OFIFG;
for(n=5000;n>0;
n--);
} while(OFIFG&IFG1);
}
//------------------------------------
unsigned int AD_Data_ACompositor( void )
{
unsigned int maxA;
unsigned int minA;
unsigned int SumA=0;
unsigned int i;
maxA = AD_DATA_A[0];
for(i=0;i<7;i++){
if(AD_DATA_A[i]>maxA)
maxA = AD_DATA_A[i]; //取出最大值
}
minA = AD_DATA_A[0];
for(i=0;i<7;i++){
if(AD_DATA_A[i]<minA)
minA = AD_DATA_A[i]; //取出最小值
}
for(i=0;i<7;i++)
SumA += AD_DATA_A[i]; //累计值
SumA = SumA - maxA-minA; //排除最大最小值 return(SumA);
}
unsigned int AD_Data_BCompositor( void )
unsigned int maxB;
unsigned int minB;
unsigned int SumB=0;
unsigned int i;
maxB = AD_DATA_B[0];
for(i=0;i<7;i++){
if(AD_DATA_B[i]>maxB)
maxB = AD_DATA_B[i]; //取出最大值
}
minB = AD_DATA_B[0];
for(i=0;i<7;i++){
if(AD_DATA_B[i]<minB)
minB = AD_DATA_B[i]; //取出最小值
}
for(i=0;i<7;i++)
SumB += AD_DATA_B[i]; //累计值
SumB = SumB - maxB-minB; //排除最大最小值 return(SumB);
}
//---------------------------------------------------------- void LCD_Display_Delay( unsigned int dtime )
{
unsigned int i,j;
for(i=0;i<dtime;i++)
for(j=0;j<100;j++);
}
int go()
{
unsigned int i;
for(i=0;i<100;i++)
{ P2OUT|=BIT4;
LCD_Display_Delay(500);
keyout &=~ BIT4;
LCD_Display_Delay(500);
}
return(0);
}
void back()
{
unsigned int i;
for(i=0;i<10;i++)
{
P2OUT |=BIT5;
LCD_Display_Delay(500);
P2OUT &=~ BIT5;
LCD_Display_Delay(500);
}
}
void stop()
{
unsigned int i;
for(i=0;i<10;i++)
{ P2OUT&=0xcf;
LCD_Display_Delay(500);
}
}
unsigned int A()
{
unsigned int n;
for(n=0;n<50;n++)
{
P3OUT&=~BIT3;
AD_DATA_A[ad_count] = AD_SamplingA();
ad_count += 1;
if( ad_count ==7)
{
ad_count = 0;
Adata =AD_Data_ACompositor();
averageA = Adata/5;
averageA = averageA*3830/0xfff-260;
displayA[0] = (unsigned int)averageA/1000;
displayA[2] = (((unsigned int)averageA%1000)/100);
displayA[3] = (((unsigned int)averageA%1000)%100/10); displayA[0] += 0x30;
displayA[2] += 0x30;
displayA[3] += 0x30;
}
}
return( averageA);
}
unsigned int B()
{
unsigned int r;
for(r=0;r<50;r++)
{
P3OUT|=BIT3;
AD_DATA_B[ad_count] = AD_SamplingB();
ad_count += 1;
if( ad_count ==7)
{
ad_count = 0;
Bdata = AD_Data_BCompositor();
averageB = Bdata/5;
averageB =(averageB)*3830/0xfff-200;
displayB[0] = (unsigned int)averageB/1000;
displayB[2] = (((unsigned int)averageB%1000)/100);
displayB[3] = (((unsigned int)averageB%1000)%100/10); displayB[0] += 0x30;
displayB[2] += 0x30;
displayB[3] += 0x30;
}
P3OUT&=~BIT3;
}
return( averageB);
}
unsigned int dCompositor( void )
{
unsigned int maxA;
unsigned int minA;
unsigned int SumA=0;
unsigned int i;
maxA=d_DATA[0];
for(i=0;i<7;i++){
if( d_DATA[i]>maxA)
maxA=d_DATA[i]; //取出最大值
}
minA= d_DATA[0];
for(i=0;i<7;i++){
if( d_DATA[i]<minA)
minA =d_DATA[i]; //取出最小值
}
for(i=0;i<7;i++)
SumA += d_DATA[i]; //累计值
SumA= SumA - maxA-minA; //排除最大最小值 return(SumA);
}
unsigned int dSampling()
{
k=A();
l=B();
ddata=(k-l)/(k+l);
return(ddata);
}
unsigned int d()
{
d_DATA[ad_count] = dSampling();
ad_count += 1;
if( ad_count ==7)
{
ad_count = 0;
vdata =dCompositor();
vdata = vdata/5;
averaged=(10000*ddata);
display_data[0]=averaged/10000;
display_data[2]=(averaged%10000)/1000;
display_data[3]=(averaged%1000)/100;
display_data[4]=(averaged%100)/10;
display_data[5]=averaged%10;
display_data[0]+=0x30;
display_data[2]+=0x30;
display_data[3]+=0x30;
display_data[4]+=0x30;
display_data[5]+=0x30;
LCD_Writestring(3, 0, "d=");
LCD_Writestring(3, 1, display_data);
LCD_Writestring(3, 6, " ");
}
return(averaged);
}。