信号放大检测电路设计报告11

2009224152538

电子设计大赛设计书

微弱信号检测电路设计

通信12级小分队

队员:周广权201203010331  

赵雪靖201203010327 

郑明威201203010132



信号放大检测电路设计报告

参赛队伍:通信12级小分队

周广权  赵雪靖  郑明威

摘要:

本装置主要由加法器,纯电阻分压网络,微弱信号检测电路,显示电路四部分组成,本设计利用函数发生器产生的正弦波和给定的标准噪声相加,作为滤波电路的输入参考信号,其中加法器模块我们用NE5532P芯片来实现加法作用,电路分压采用纯电阻分压网络进行分压使其衰减系数不低于100,为了增加它的输入阻抗,我们在滤波电路之前设计了一个电压跟随电路来实现,并在之后用同相比例运算电路来实现放大作用。我们的滤波电路有一个二阶的巴特沃斯带通滤波电路构成,最后通过51单片机的的A/D模块和显示模块实现显示信号幅度值的功能。

一.流程图部分

(一)

微弱信号检测装置示意图:


(二)

原理框图:

说明: 

由信号发生器发生的正弦波和已给的标准噪声构成的两路信号经相加器进行相加运算后整合成一路信号,然后对信号进行分压,在对信号进行微弱信号检测,其中包括滤波部分、放大部分、电压跟随部分。最后由51单片机进行采样输出幅度值 

二.方案论证

(一)加法器模块方案:

用老师提供的NE5532P实现加法器模块,对提供的两个信号由信号发生器产生的正弦波和以给定的标准噪声进行相加,NE5532P具有低失真,低噪音等特点,其经过不断模拟输出测试发现,满足题目带宽大于500KHz的要求(同时发现OP07CP不符合要求)。

加法器模块原理图:

电路理论原理如下:、

(二)纯电阻分压网络: 

分压模块要求纯电阻分压网络的衰减系数不低于100,电路采用1k与100k电阻进行串联进行分压

(三)微弱信号检测方案:

电路三部分:

1、         电压跟随电路

   为了满足微弱信号检测电路的输入阻抗Ri≥1 MW。我们设计了电压跟随电路,他的输入阻抗高,而输出阻抗低。一般来说,输入阻抗可以达到几兆欧姆,而输出阻抗低,通常只有几欧姆,甚至更低。

2、         放大电路

   题目要求当输入正弦波信号VS 的频率为1 kHz、幅度峰峰值在200mV ~ 2V范围内时,检测并显示正弦波信号的幅度值,要求误差不超过5%。

所以我们用同相比例运算电路构成一个放大器,并把电位器设为RF,以便调节放大倍数。

电路为电压并联负反馈放大电路由电路原理虚短和虚断可得

Uo=R7/R5*Ui,所以我们的放大增益在1到200之间。

3,、滤波电路

我们采用的是二阶巴特沃斯滤波电路,根据f=1/(2*PI*R*C),把f设在1k欧姆

三.测试方案及测试结果分析

   利用信号发生器,产生一个1kHZ的正弦波,幅度峰峰值在200mV ~ 2V范围内变换;同时,根据老师要求,利用信号发生器,把噪声设成10k的波形,VN的均方根电压值固定为1V±0.1V。

为便于各个模块的测试,所有测试端点(A~E)已成跳线连接方式。各个点测试波形如下:

A点:

B点:

C点:

D点:

E点:

(四)AD误差测量及结果

四.总结

经过两天三夜的电路设计、焊接调试、程序设计联调,最终完成了整个规定的设计过程。从最终的结果看,达到了预期的各项基本要求,主要包括 :加法器的输出VC =VS+VN,带宽可达远远大于要求的500kHz;纯电阻分压网络的衰减系数不低于100,微弱信号检测电路的输入阻抗Ri≥1 M?,当51单片机检测并显示正弦波信号的幅度值是时,由于显示板的原因,仅当输入200mv,误差稍微大于5%范围,其他时候均小于5%;输入正弦波信号VS 的频率为1 kHz、幅度峰峰值在200mV ~ 2V范围内等。通过这几天的设计竞赛,我们不但增强了实践能力和合作精神,而且懂得了理论联系实际的重要性,在不断的调试中吸取经验,这对我们以后的学习生活不无裨益,当然我们的设计中还存在着一些缺陷,有待于进一步提高, 在此恳请各位老师批评指正。

附件1

完整电路图

附件2

单片机程序

//-----------------------函数声明,变量定义------------------------

#include <reg51.h>

#include <intrins.h>

sbit SDA=P2^0;                   // 将p1.2口模拟数据口

sbit SCL=P2^1;                   // 将p1.7口模拟时钟口

sbit DS1302 =P2^4;

sbit DU = P2^0;

sbit WE = P2^1;

#define uchar unsigned char

#define uint  unsigned int

#define disdata  P0              //显示数据码输出口

sbit LCD_RS = P1^0;            

sbit LCD_RW = P1^1;

sbit LCD_EN = P2^5;

uint data dis[4]={0x00,0x00,0x00,0x00};

                          //定义3个显示数据单元和1个数据存储单元

uchar code dis4[] = {"1- .  V  -------"};

uchar code dis5[] = {"-------  -------"};

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

                       

bit   bdata SystemError;                //从机错误标志位

/*********************** PCF8591专用变量定义 ***********************/

#define  PCF8591_WRITE     0x90

#define  PCF8591_READ      0x91

#define  NUM  4             //接收和发送缓存区的深度

uchar idata receivebuf[NUM];    //数据接收缓冲区

void cmg88()//关数码管,点阵函数

{

DU=1; 

P0=0X00;

DU=0;

}

/*******************************************************************/

/*                                                                 */

/*  延时函数                                                       */

/*                                                                 */

/*******************************************************************/

void delay(int ms)

{

    while(ms--)

       {

      uchar i;

         for(i=0;i<250;i++) 

          {

           _nop_();                       

              _nop_();

              _nop_();

              _nop_();

          }

       }

}           

/*******************************************************************/

/*                                                                 */

/*检查LCD忙状态                                                    */

/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */

/*                                                                 */

/*******************************************************************/

bit lcd_busy()

 {                         

    bit result;

    LCD_RS = 0;

    LCD_RW = 1;

    LCD_EN = 1;

    delayNOP();

    result = (bit)(P0&0x80);

    LCD_EN = 0;

    return(result);

 }

/*******************************************************************/

/*                                                                 */

/*写指令数据到LCD                                                  */

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */

/*                                                                 */

/*******************************************************************/

void lcd_wcmd(uchar cmd)

{                         

   while(lcd_busy());

    LCD_RS = 0;

    LCD_RW = 0;

    LCD_EN = 0;

    _nop_();

    _nop_();

    P0 = cmd;

    delayNOP();

    LCD_EN = 1;

    delayNOP();

    LCD_EN = 0; 

}

/*******************************************************************/

/*                                                                 */

/*写显示数据到LCD                                                  */

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */

/*                                                                 */

/*******************************************************************/

void lcd_wdat(uchar dat)

{                         

   while(lcd_busy());

    LCD_RS = 1;

    LCD_RW = 0;

    LCD_EN = 0;

    P0 = dat;

    delayNOP();

    LCD_EN = 1;

    delayNOP();

    LCD_EN = 0;

}

/*******************************************************************/

/*                                                                 */

/*  LCD初始化设定                                                  */

/*                                                                 */

/*******************************************************************/

void lcd_init()

{

    delay(15);                  

    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据

    delay(5);

    lcd_wcmd(0x38);        

    delay(5);

    lcd_wcmd(0x38);        

    delay(5);

    lcd_wcmd(0x0c);      //显示开,关光标

    delay(5);

    lcd_wcmd(0x06);      //移动光标

    delay(5);

    lcd_wcmd(0x01);      //清除LCD的显示内容

    delay(5);

}

/*******************************************************************/

/*                                                                 */

/*  设定显示位置                                                   */

/*                                                                 */

/*******************************************************************/

void lcd_pos(uchar pos)

{                         

  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量

}

/******************************************************************/

/*                                                                */

/* 数据处理与显示                                                 */

/* 将采集到的数据进行16进制转换为ASCLL码。                        */

/*                                                                */

/******************************************************************/

show_value(uchar ad_data)

{  

    dis[2]=ad_data/51;   //AD值转换为3为BCD码,最大为5.00V。

    dis[2]=dis[2]+0x30;  //转换为ACSII码

    dis[3]=ad_data%51;   //余数暂存

    dis[3]=dis[3]*10;    //计算小数第一位

    dis[1]=dis[3]/51;

    dis[1]=dis[1]+0x30;  //转换为ACSII码

    dis[3]=dis[3]%51;

    dis[3]=dis[3]*10;    //计算小数第二位

    dis[0]=dis[3]/51;                                                                             //

    dis[0]=dis[0]+0x30;  //转换为ACSII码          

}

//-------------------------------------------------------------------

// 函数名称: iic_start()

// 函数功能: 启动I2C总线子程序

//-------------------------------------------------------------------

void iic_start(void)

{ //时钟保持高,数据线从高到低一次跳变,I2C通信开始

       SDA = 1;    

       SCL = 1;

       delayNOP();      // 延时5us

   SDA = 0;

       delayNOP();

    SCL = 0;

}

//-------------------------------------------------------------------

// 函数名称: iic_stop()

// 函数功能: 停止I2C总线数据传送子程序

//-------------------------------------------------------------------

void iic_stop(void)

       SDA = 0;             //时钟保持高,数据线从低到高一次跳变,I2C通信停止

       SCL = 1;

       delayNOP();

       SDA = 1;

       delayNOP();

    SCL = 0;

}

//------------------------------------------------------------------

// 函数名称: iicInit_()

// 函数功能: 初始化I2C总线子程序

//------------------------------------------------------------------

 void iicInit(void)

   {

   SCL = 0;

   iic_stop();     

   } 

//-------------------------------------------------------------------

// 函数名称: slave_ACK

// 函数功能: 从机发送应答位子程序

//-------------------------------------------------------------------

void slave_ACK(void)

{

       SDA = 0; 

       SCL = 1;

       delayNOP();

       SCL = 0;

}

//-------------------------------------------------------------------

// 函数名称: slave_NOACK

// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束

//-------------------------------------------------------------------

void slave_NOACK(void)

{

       SDA = 1;

       SCL = 1;

       delayNOP();

       SDA = 0;

    SCL = 0; 

}

//-------------------------------------------------------------------

// 函数名称: check_ACK

// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束

//-------------------------------------------------------------------

void check_ACK(void)

{        

    SDA = 1;        // 将SDA设置成输入,必须先向端口写1

       SCL = 1;

       F0 = 0;

       delayNOP();  

       if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0

    F0 = 1;

   SCL = 0;

}

//-------------------------------------------------------------------

// 函数名称: IICSendByte

// 入口参数: ch

// 函数功能: 发送一个字节

//-------------------------------------------------------------------

void IICSendByte(uchar ch)

{

     unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位

       while(n--)

       {

       if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1

          {

                    SDA = 1;    // 传送位1

                     SCL = 1;

                  delayNOP();

              //     SDA = 0;     

                     SCL = 0;

          }

              else

              { 

                     SDA = 0;    // 否则传送位0

                     SCL = 1;

                     delayNOP();

                   SCL = 0;

              }

              ch = ch<<1;    // 数据左移一位

       }

}

//-------------------------------------------------------------------

// 函数名称: IICreceiveByte

// 返回接收的数据

// 函数功能: 接收一字节子程序

//-------------------------------------------------------------------

uchar IICreceiveByte(void)

{

       uchar idata n=8;     // 从SDA线上读取一上数据字节,共八位

       uchar tdata=0;

       while(n--)

       {

          SDA = 1;

          SCL = 1;

          tdata =tdata<<1;             //左移一位

          if(SDA == 1)

                tdata = tdata|0x01;   // 若接收到的位为1,则数据的最后一位置1

              else

                tdata = tdata&0xfe;   // 否则数据的最后一位置0

          SCL = 0;

        }

        return(tdata);

}

//-------------------------------------------------------------------

// 函数名称: DAC_PCF8591

// 入口参数: slave_add从机地址,n要发送的数据个数

// 函数功能: 发送n位数据子程序

//-------------------------------------------------------------------

void DAC_PCF8591(uchar controlbyte,uchar w_data)

{   

      

       iic_start();                    // 启动I2C

       delayNOP();

       IICSendByte(PCF8591_WRITE);     // 发送地址位

       check_ACK();                    // 检查应答位

    if(F0 == 1)

        {

              SystemError = 1;

              return;                     // 若非应答,置错误标志位

     }

    IICSendByte(controlbyte&0x77); //Control byte

       check_ACK();                    //检查应答位

    if(F0 == 1)

        {

              SystemError = 1;

              return;                    // 若非应答,置错误标志位

        }

    IICSendByte(w_data);           //data byte

       check_ACK();                  // 检查应答位

    if(F0 == 1)

        {

              SystemError = 1;

          return;   // 若非应答表明器件错误或已坏,置错误标志位SystemError

        }

       iic_stop();         // 全部发完则停止

       delayNOP();

       delayNOP();

       delayNOP();

       delayNOP();

}

//-------------------------------------------------------------------

// 函数名称: ADC_PCF8591

// 入口参数: controlbyte控制字

// 函数功能: 连续读入4路通道的A/D转换结果到receivebuf

//-------------------------------------------------------------------

void ADC_PCF8591(uchar controlbyte)

{

    uchar idata receive_da,i=0;

       iic_start();

       IICSendByte(PCF8591_WRITE); //控制字

       check_ACK();

       if(F0 == 1)

       {

              SystemError = 1;

              return;

       }

       IICSendByte(controlbyte);      //控制字

       check_ACK();

       if(F0 == 1)

       {

              SystemError = 1;

              return;

       }

    iic_start();                //重新发送开始命令

   IICSendByte(PCF8591_READ);  //控制字

       check_ACK();

       if(F0 == 1)

       {

              SystemError = 1;

              return;

       }

        

    IICreceiveByte();   //空读一次,调整读顺序

    slave_ACK();        //收到一个字节后发送一个应答位

       while(i<4)

       { 

         receive_da=IICreceiveByte();

         receivebuf[i++]=receive_da;

         slave_ACK();       //收到一个字节后发送一个应答位

       }

       slave_NOACK();       //收到最后一个字节后发送一个非应答位

       iic_stop();

}

//-------------------------------------------------------------------

// 函数名称: main

// 函数功能: 主程序

//-------------------------------------------------------------------

main()

{

    uchar i,l,max;

       max=0x00;

    delay(10);                 //延时

       cmg88();//关数码管,点阵函数

       DS1302 =0;

    lcd_init();                //初始化LCD            

       

    lcd_pos(0);                //设置显示位置为第一行的第1个字符

     i = 0;

    while(dis4[i] != '\0')

     {                         //显示字符

       lcd_wdat(dis4[i]);

       i++;

     }

    lcd_pos(0x40);             //设置显示位置为第二行第1个字符

     i = 0;

    while(dis5[i] != '\0')

     {

       lcd_wdat(dis5[i]);      //显示字符

       i++;

     }

      

  while(1)

  {

       iicInit();               //I2C总线初始化

    ADC_PCF8591(0x04);

       if(SystemError == 1)    //有错误,重新来

         {

            iicInit();                        //I2C总线初始化

           ADC_PCF8591(0x04);

          }

          if(receivebuf[0]>max)

          max=receivebuf[0];  

      

       for(l=0;l<4;l++)  

        {

         show_value(max); //显示通道0      

           lcd_pos(0x02);            

        lcd_wdat(dis[2]);        //整数位显示

        lcd_pos(0x04);            

        lcd_wdat(dis[1]);        //第一位小数显示

        lcd_pos(0x05);            

        lcd_wdat(dis[0]);        //第二位小数显示

         iicInit();                        //I2C总线初始化 

      DAC_PCF8591(0x40,receivebuf[0]); //D/A输出

          if(SystemError == 1)    //有错误,重新来

           {

             iicInit();                             //I2C总线初始化

               DAC_PCF8591(0x40,receivebuf[0]); //D/A输出

           }           

      //delay(50);                       //延时

        }

   }

}

相关推荐