完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 gk320830 于 2015-3-7 11:58 编辑 微弱信号检测装置 四川理工学院 刘鹏飞、梁天德、曾学明 摘要: 本设计以ti的Launch Pad为核心板,采用锁相放大技术设计并制作了一套微弱信号检测装置,用以检测在强噪声背景下已知频率微弱正弦波信号的幅度值,并在液晶屏上数字显示出所测信号相应的幅度值。实验结果显示其抗干扰能力强,测量精度高。 关键词:强噪声;微弱信号;锁相放大;Launch Pad Abstract: This design is based on the Launch Pad of TI core board, using a lock-in amplifier technique designed and produced a weak signal detection device, to measure the known frequency sine wave signal amplitude values of the weak in the high noise background, and shows the measured signal amplitude of the corresponding value in the liquid crystal screen. Test results showed that it has high accuracy and strong anti-jamming capability. Keywords: weak signal detection; lock-in-amplifier; Launch Pad 1、引言随着现代科学技术的发展,在科研与生产过程中人们越来越需要从复杂高强度的噪声中检测出有用的微弱信号,因此对微弱信号的检测成为当前科研的热点。微弱信号并不意味着信号幅度小,而是指被噪声淹没的信号,“微弱”也仅是相对于噪声而言的。只有在有效抑制噪声的条件下有选择的放大微弱信号的幅度,才能提取出有用信号。微弱信号检测技术的应用相当广泛,在生物医学、光学、电学、材料科学等相关领域显得愈发重要。 2、方案论证针对微弱信号的检测的方法有很多,比如滤波法、取样积分器、锁相放大器等。下面就针对这几种方法做一简要说明。 方案一:滤波法。 在大部分的检测仪器中都要用到滤波方法对模拟信号进行一定的处理,例如隔离直流分量,改善信号波形,防止离散化时的波形混叠,克服噪声的不利影响,提高信噪比等。常用的噪声滤波器有:带通、带阻、高通、低通等。但是滤波方法检测信号不能用于信号频谱与噪声频谱重叠的情况,有其局限性。虽然可以对滤波器的通频带进行调节,但其噪声抑制能力有限,同时其准确性与稳定性将大打折扣。 图2-1 常用的滤波器示意图 方案二:取样积分器 取样积分法是利用周期性信号的重复特性,在每个周期内对信号的一部分取样一次,然后经过积分器算出平均值,于是各个周期内取样平均信号的总体便呈现出待测信号的真实波形。由于信号的取样是在多个周期内重复进行的,而噪声在多次重复的统计平均值为零,所以可大大提高信噪比,再现被噪声淹没的波形。 其系统原理图如图2-1所示。 图2-2 取样积分原理图 一个取样积分器的核心组件式是取样门和积分器,通常采用取样脉冲控制RC积分器来实现,使在取样时间内被取样的波形做同步积累,并将累积的结果保持到下一次取样。 取样积分器通常有定点式和扫描式两种工作模式。定点式是测量周期信号的某一瞬态平均值,经过m次取样平均后,其幅值信噪比改善为;扫描式取样积分器利用取样脉冲在信号波形上延时取样,可用于恢复与记录被测信号的波形,由于其采样过程受到门脉冲宽度的限制,只有在门宽范围内才能被取样。 方案三:锁相放大器 锁相放大器也称为锁定放大器(Lock-In-Amplifier,LIA)。它主要作为一个极窄的带通滤波器的作用,而非一般的滤波器。它的原理是基于信号与噪声之间相关特性之间的差异。锁相放大器即是利用互相关原理设计的一种同步相关检测仪,利用参考信号与被测信号的互相关特性,提取出与参考信号同相位和同频率的被测信号。锁定放大器可在比被测信号强100dB的噪声干扰中检测出有用信号。其原理框图如图2-3。 图2-3 锁相放大原理框图 锁相放大器的核心部件是鉴相器,它实现了被测信号与参考信号的互相关运算。它把输入信号与参考信号进行比较,当两个信号相位完全相同时,即相位差为0时,经低通滤波后,输出信号的直流分量达到最大,其正比于输入信号中某一特定频率(参考输入频率)的信号幅值。 锁相放大器具有很多优点:信号通过调制后交流放大,可以避免噪声的不利影响;利用相敏检波器实现对调制信号的解调,同时检测频率和相位,噪声同频又同相的概率很小;利用低通滤波器来抑制噪声,低通滤波器的频带可以做得很窄,并且其频带宽度不受调制频率的影响,稳定性也大大提高。但是值得注意的是适合于锁相放大器的检测信号应该是单频的,或者传导频谱所占频带是较窄的。 综合考虑,尤其根据是手头现有器件的情况,我们选择了利用锁相放大器作为本次的检测方案,并达到了预期的效果。 3、理论分析与计算设输入信号为: 根据傅里叶变换,r(t)可用三角函数的形式表示为: r(t)与x(t)相乘后的结果为: 上式第一项为差频项,第二项为和频项。在通过低通滤波器(LPF)后,所有的和频项与差频项都被滤除。最后滤波器的输出为: 上式说明被测信号经过相敏检波器(PSD)和低通滤波器(LPF)后,输出正比于被测信号的幅度,同时正比于参考信号与被测信号的相位差的余弦函数,此时,输出最大,从而实现鉴相与鉴幅。同时,有上式若测得输出电压可以反推得到输入电压的幅值: PSD信号的输出信号由于被测信号与参考信号之间的相位差而产生很大的变化。受此影响,经过低通滤波器后的输出电压也会变化很大。如图3-1所示: 图3-1 相位差的影响 通过图3-1,我们可以看到只有在相位差为时才能很好的检测被测信号的大小。通常,我们在进行测量时需要通过相移网络把参考信号与被测信号之间的相位差调到再输入到PSD。 4、总体方案设计 本设计系统框图如图4-1所示。系统通过把正弦信号与噪声源通过加法器混合,通过电阻分压网络使噪声衰减到一定程度,模拟淹没在噪声中的有用信号,再通过前置放大电路对信号进行预放大,再通过带通滤波器选择设计所需的通频带,然后通过以AD630为核心器件的锁相放大器,输出电压经过低通滤波器之后得到一个直流电压输出,最后通过MSP430进行AD采样、数据处理后送液晶显示。在整个电路中放置了A~E共5个测试点作为调试用。 4-1 系统框图 5、硬件设计整个系统的电路顶层设计如图5-1所示:包含了电源模块、信号产生电路、前置放大与带通滤波、锁相放大模块、低通滤波器、单片机处理模块这些部分。其中每个模块的电源引脚部分都加入了去耦电容,PCB对电源线也进行了相应的覆铜处理,降低高频干扰。其整体硬件实物图见附录A。 图5-1 系统电路顶层设计 5.1信号产生电路 本电路模块旨在产生一个能够模拟实际中淹没在噪声中的微弱信号。包含加法器与纯电阻分压网络两部分。在实际电路中采用函数信号发生器产生频率为500Hz ~ 2kHz振幅为的200mV ~ 2V正弦信号Vs。同时使用提供的音频信号作为噪声源Vn。首先通过电压跟随器,再经过加法器实现信号的混合,芯片使用AD827来拓宽其频带到≥1 MHz带宽,可调节音量使正弦信号完全淹没在噪声中。经过混合后的信号再通过一个纯电阻分压电路把信号衰减大约100倍,得到输入信号Vi。电路中取R5=R7=1k,R6=R8=100。其电路原理图如图5-2所示,并在适当位置预留了测试端口。 图5-2 信号产生电路 5.2前置放大电路 该电路用于对信号进行预放大处理,使其输入到后级锁相放大器的信号有个适当的幅度。其电路如图5-3所示。采用TI公司的OPA2227这款低噪声、高精度的运放(后改用AD827)。第一级放大倍数为11倍,第二级放大倍数为10倍,所以总共放大约110倍。同时在输入端接入R10=2M,保证输入阻抗Ri≥1 MW的要求。其电路连接如下图所示。 图5-3 前置放大电路 5.3 带通滤波电路 为满足设计要求,设计了一个带宽为500Hz ~ 2K Hz的带通滤波器,滤除所需频带外的噪声,降低了噪声对信号的干扰。设计选用了二阶低通滤波器与二阶高通滤波器构成二阶带通滤波网络,由TI的滤波器设计软件FilterPro可以设计得到带通滤波器,其中R16=8.2k,R17=15k,C11=2nF,C12=1nF,R18=10k,R19=24k。运放使用TI的OPA2227,其电路如图5-4所示。 图5-4 带通滤波电路 5.4 移相网络 该移相网络用于对参考信号进行移相,其原理是RC相移,通过跳线选择不同的接口,调整可变电阻来实现不同的相移。通过使用一片OPA2227实现对参考信号进行的相移。其中上方为0~900的相移,下方的模块实现90~1800相移。必须在下方的移相模块中加入饱和电阻,否则频率过低时容易出现输出信号饱和。其电路设计如图5-5所示。 图5-5 相移网络 5.5 锁相放大电路 锁相放大电路采用AD630芯片作为核心,其电路如图5-6所示。AD630是一款高精度的平衡调制器,具有出色的精度与温度稳定性,非常低的通道串扰,高的共模抑制比和增益调节,同时还可以在外部加入反馈来实现所需增益与开关反馈布局,它可以从100dB噪声中恢复信号,频带宽度达到2MHz。其信号处理应用包括:平衡调制与解调、同步检波、相位检测、正交检波、相敏检测、锁定放大以及方波乘法等。实际上锁相放大器与调制解调有些类似,只不过频率更低。使用本芯片可以减少鉴相器与噪声方面的许多考虑,大大减小开发难度与开发周期。 图5-6 锁相放大电路 注意这里的电路连接具有2倍的增益。 5.6 低通滤波电路 本滤波电路采用TI的LF353运放设计,当锁相放大电路输出的信号经过低通滤波器之后可得到一个直流信号,其幅值与输入信号中某一特定频率(参考输入信号的频率)的信号幅值成正比,即。其电路如图5-7所示。 图5-7 低通滤波电路 5.7 LaunchPad电路连接 本设计以TI公司的MSP-EXP430G2 LaunchPad作为数据处理模块,其基本电路连接如5-8所示。 图5-8 LaunchPad 电路连接图 MSP-EXP430G2 LaunchPad 具有很多优良特性: • USB 调试与编程接口无需驱动即可安装使用,且具备高达 9600 波特率的 UART 串行通信速度 • 支持所有采用 PDIP14 或 PDIP20 封装的 MSP430G2xx 和 MSP430F20xx 器件 • 分别连接至绿光和红光 LED 的两个通用数字 I/O 引脚可提供视觉反馈 • 两个按钮可实现用户反馈和器件复位 • 器件引脚方便地用于调试目的,也可用作添加定制的扩展板的插座 • 高质量的 20 引脚 DIP 插座,可轻松简便地插入目标器件或将其移除 6、软件设计 本设计以TI提供的MSP-EXP430G2 LaunchPad为核心,用MSP430G2553单片机自带的片上外设AD10对数据进行AD转换,并做相应的处理然后送液晶显示。其软件流程图如图6-1。详细的软件代码见附录B 图6-1 软件设计流程图 7、系统测试与结果分析7.1 测试仪器 DS1102E型100MHz 1GSa/s双通道数字示波器,TFG6030 DDS函数信号发生器,数字万用表。 7.2 测试方案 基本功能测试:固定1KHz 改变输入信号的峰峰值在200mV~2V之间,记录液晶显示数据,计算误差大小。 拓展功能测试:调节使输入信号频率在500Hz~2kHz范围内,峰峰值在20mV~2V范围内,观看液晶显示数据,计算误差大小。 7.3 测试结果 噪声幅度: 加法器带宽:BW=0Hz~6.4MHz 纯电阻网络衰减倍数: 输入阻抗Ri2M1M 输入输出电压幅度测量结果: 表7-1 输入输出电压测量
7.4 结果分析 经过测量,该装置达到了并且还有很多地方超过了设计所需要求。但是仍然有很多提升的空间,例如可以通过使用外部的高速运放来提高采样的分辨率,提高测量精度;可以设计双相位锁定放大器来提高对任意频率的测量;可以通过软件算法来减小数据的波动;可以通过PCB布线布局,加屏蔽罩等措施提高装置的高干扰能力等等 8、总结 本设计以AD630为核心器件的锁相放大器对淹没在噪声中的微弱信号进行检测,输出的电压经MSP-EXP430G2 LaunchPad的处理,再通过液晶显示出来。经过系统测试,能够完成对微弱信号的检测,所有指标都已经达到或者超过了设计要求。 附录A 硬件实物图附录B 软件代码main.c #include "msp430g2553.h" #include "ADC10.h" #include "LCD.h" #include "HalInit.h" #define Filter_N 64 float Filter(unsigned int pData[]); //---------------------------------------------- void main(void) { WDTCTL = WDTPW + WDTHOLD; SysInit(); P2DIR |= BIT3 + BIT4; __low_power_mode_0(); } //---------------------------------------------- #pragma vector = TIMER0_A0_VECTOR __interrupt void TA0_ISR(void) { unsigned int Data; float TempData; static unsigned int CvtCnt =0,value[Filter_N]; CvtCnt++; if(CvtCnt <= Filter_N) { ADC10Read(&Data,1); value[CvtCnt-1] = Data; } else { P2OUT ^= BIT4; CvtCnt = 0; TempData = value[0]; TempData = Filter(value); TempData = 1500*TempData/1023;//转换成采样电压数据 TempData *=0.785398;//数据处理 LCD_Disp((unsigned int)TempData); } } //---------------------------------------------- float Filter(unsigned int pData[]) { unsigned int Cnt; unsigned long Sum=0; for(Cnt = 1;Cnt <= Filter_N;Cnt++) { Sum += pData[Cnt - 1]; } return (float)(Sum/Filter_N); } //---------------------------------------------- HalInit.c #include "LCD.h" #include #include "HalInit.h" #include "ADC10.h" //---------------------------------------------- void SysInit(void) { ClkInit(); LCD_init(); ADC10Init(1,0,0); LCD_Gui(); TimerA0Init(); IE1 |= WDTIE; _EINT(); } //---------------------------------------------- void TimerA0Init(void) { TA0CTL = TASSEL_1 + TACLR; TA0CCTL0 = CCIE; TA0CCR0 = 339; TA0CTL |= MC_1; } //---------------------------------------------- void ClkInit(void) { if (CALBC1_12MHZ ==0xFF || CALDCO_12MHZ == 0xFF) { // If calibration constants erased P1DIR |= BIT6; // do not load, trap CPU!! P1OUT |= BIT6; while(1); } BCSCTL1 = CALBC1_12MHZ; // Set DCO to 8MHz DCOCTL = CALDCO_12MHZ; } //---------------------------------------------- void LCD_Gui(void) { LCD_draw_lineX(0 , 83 , 0); LCD_draw_lineY(0 , 0 , 47); LCD_draw_lineY(83 , 0 , 47); LCD_show_char(8,3,'m'); LCD_show_char(9,3,'v'); LCD_write_stringxy(2,1,"Peak value:"); LCD_Disp(0); } //---------------------------------------------- ADC.c #include "msp430g2553.h" #include "ADC10.h" //---------------------------------------------- void ADC10Init(unsigned char SelectRef,unsigned char ConvtMode,unsigned char InputChannel ) { …… } //---------------------------------------------- void ADC10Start(void) { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start } //---------------------------------------------- unsigned int ADC10Read(unsigned int *pData,unsigned int DatNum) { unsigned int i; if((ADC10CTL1 & CONSEQ1) ==0)//单次转换 { for(i = 0;i < DatNum;i++) { ADC10Start(); __bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit while(ADC10CTL1 & ADC10BUSY); P2OUT ^= BIT3; *pData++ = ADC10MEM; ADC10CTL0 &= ~(ENC); } } else//序列转换 { ADC10DTC1 = DatNum;//传输数据个数 ADC10SA = (unsigned short)pData; ADC10Start(); __bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit ADC10CTL0 &= ~ENC; } return 1; } //---------------------------------------------- #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR(void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) } //---------------------------------------------- void LCD_PortInit() { P1DIR |= BIT1 + BIT2 + BIT3 + BIT4 + BIT5; P2DIR |= BIT0 + BIT1 + BIT2 + BIT3; NOKIA5110_VCC_ON; NOKIA5110_GND_ON; } //---------------------------------------------- LCD.c #include "LCD.h" …… /************************************* use SPI send byte **************************************/ void LCD_sendbyte(INT8U dat,INT8U command) { INT8U i; NOKIA5110_CE_L; Delay_us(1); if(command==0) { NOKIA5110_DC_L;//传送命令 Delay_us(1); } else { NOKIA5110_DC_H; //传送数据 Delay_us(1); } for(i=0;i<8;i++) { if(dat&0x80) { NOKIA5110_DIN_H; Delay_us(1); } else { NOKIA5110_DIN_L; Delay_us(1); } NOKIA5110_CLK_L; dat=dat<<1; NOKIA5110_CLK_H; Delay_us(1); } NOKIA5110_CE_H; Delay_us(1); } /******************************************** LCD_set_xy *********************************************/ void LCD_set_xy(INT8U x,INT8U y) { LCD_sendbyte(0x80|x,0);//x-0 to 83 LCD_sendbyte(0x40|y,0);//y-0 to 5 } /******************************************* LCD clear ********************************************/ void LCD_clear() { INT8U i,j; LCD_sendbyte(N5110_DE_2,0);//设定显示模式,正常显示 LCD_sendbyte(RAM_X_ADDR_START,0);//设置RAM起始地址 for(j=0;j<6;j++) { for(i=0;i<84;i++) { LCD_sendbyte(0,1); } } } /******************************************* LCD初始化 ********************************************/ void LCD_init() { INT8U i; LCD_PortInit(); NOKIA5110_RST_L;//产生一个让LCD复位的低电平脉冲 // Delay_Nms(5); for(i=0;i<50;i++) { _NOP(); _NOP(); _NOP(); } NOKIA5110_RST_H; NOKIA5110_LED_ON; LCD_sendbyte(0x21,0);//使用扩展命令设置LCD模式chip is active & horizontal addressing (H=1) LCD_sendbyte(0xc8,0);////设置电压VLCD = 3.06 + 0.06*Vop, LCD_sendbyte(0x06,0);//VLCD温度系数2 LCD_sendbyte(0x13,0);//设置偏置系统(BSx) 1:48 LCD_sendbyte(0x20,0);//工作模式, 水平寻址, 常规指令(H=0) LCD_sendbyte(N5110_DE_2,0);////设定显示模式,正常显示display in normal mode LCD_sendbyte(RAM_Y_ADDR_START,0);//起始页地址0 LCD_sendbyte(RAM_X_ADDR_START,0);//起始列地址0 LCD_clear(); //NOKIA5110_LED_OFF; } /********************************************* display a asciifont6*8 *********************************************/ void LCD_write_char(INT8U c) { INT8U line; c-=32;//ASCII前32个不可显示 for(line=0;line<6;line++) LCD_sendbyte(ASCII[c][line],1); } /********************************************** **名称:LCD_show_char(INT8U x,INT8U y,INT8U c) **功能:在任意位置输出一个8*16的ASCII字符 **说明:x:0-9 y:0-2 c:字符的首地址 **备注:每行最多只能显示10个字符(n*8<=84) **********************************************/ void LCD_show_char(INT8U x,INT8U y,INT8U c) { INT8U i,j; c-=32;//地址 x*=8;//字宽 y*=1;//四行显示 for(i=0;i<2;i++) { LCD_set_xy(x + 2,y+i);//设置地址 for(j=0;j<8;j++) LCD_sendbyte(nAsciiDot[c][j+8*i],1); } } /********************************************* 英文字符串显示函数 **********************************************/ void LCD_write_stringxy(INT8U x,INT8U y,INT8U *p) { LCD_set_xy(x,y); while(*p) { LCD_write_char(*p); p++; } } /********************************************* 英文字符串显示函数 **********************************************/ void LCD_write_string(INT8U *p) { while(*p) { LCD_write_char(*p); p++; } } /********************************************** **名称:show_string(INT8U x,INT8U y,INT8U *str) **功能:在任意位置输出一串8*16的ASCII字符 **说明:x:0-9 y:0-2 *str:字符串的首地址 **备注:每行最多只能显示10个字符(n*8<=84) **********************************************/ void LCD_show_string(INT8U x,INT8U y,INT8U *str) { while(*str!=' |