自动增益控制(AGC)放大器实现方案

自动增益控制(AGC)放大器实现方案
自动增益控制(AGC)放大器实现方案

自动增益控制(AGC)放大器实现方案一、系统框图

二、硬件部分

系统总电路图

1、电源分压

题目要求使用5V单电源供电,此处使用10k欧姆电阻串联分压得到2.5V电压,并且通过电压射随器,稳定电压。

串联分压部分

2、程控放大器部分

增益可控放大器

(1)电路连接如图。J1接单片机的I/O口作为控制信号输入。

(2)DAC7811此处作为程控电阻使用,与TLC085共同起到增益可控放大作用。

DAC作为程控电阻器的原理:

DAC7811的核心是一个R-2R网络,当两个输出端分别接放大器输入端和地时,由于运

放的“虚地”,可以看做两条输出线都接地,因此可以算出电阻网络总电阻为R。则流经的

总电流I total=V REF

R

12个选通开关由MSP430的SPI协议控制Code=211a11+210a10+?+20a0

I out1=1

2

I?a11+

1

22

I?a10+?+

1

212

I?a0=

211a11+210a10+?+20a0

212

I=

Code

4096

I

R out1=V REF

I out1

=

V REF

Code

4096

I

=R

4096

Code

若R FB=R

V out=?V IN R4096

Code=?V

IN

4096

因此通过单片机输出不同的控制字code的值就可以实现控制增益的目的。

(3)由于运放的输出被抬高了2.5V,因此输出需要经过电容耦合滤除直流分量。

3、PWM波低通滤波部分

PWM波低通滤波

电路构成简单RC低通滤波器,将输出的PWM波转换为直流电压供外部检测用。输出电压的大小与PWM波的占空比成近似线性关系。

实际电路图:

二、软件部分

程序代码:

#include

#include

#define uchar unsigned char

#define uint unsigned int

uchar a,T0_time;

uint temp,adval,adval_t,vref_t,dac_code,D;

float vref_s;

sbit adwr=P3^6;

sbit adrd=P3^7;

sbit sync=P0^0;

sbit sclk=P0^1;

sbit sdin=P0^2;

sbit pwm=P2^0;

//定时器初始化函数

void T0_init()

{

TMOD=0x11;

TH0=(65536-45872)/256;

TL0=(65536-45872)%256;

EA=1;

ET0=1;

TR0=1;

}

//微妙级延时

void delayus(uint us)

{

uint i;

while(us--)

{

for(i=8;i>0;i--)

;

}

}

//毫秒延时函数

void delayms(uint xms) {

uint i,j;

for(i=xms;i>0;i--)

for(j=110;j>0;j--);

}

//AD启动函数

void start_ad()

{

adwr=1;

_nop_();

adwr=0;

_nop_();

adwr=1;

}

//AD读取函数

uchar get_ad()

{

P1=0xff;

adrd=1;

_nop_();

adrd=0;

_nop_();

adval=P1;

adrd=1;

return adval;

}

//CODE处理函数

void d_vout()

{

if(adval>vref_t)

dac_code++;

else

dac_code--;

D=4096/dac_code/10;//占空比}

//DAC控制函数

void dac_spi(uint dac_code)

{

uchar n;

sync=0;

sclk=1;

for(n=0;n<16;n++)

{

sclk=1;

dac_code=dac_code<<1;

sdin=CY;

sclk=0;

}

sdin=1;

sync=1;

sclk=0;

delayus(10);

}

//主函数

void main()

{

uchar ad_n;

T0_init();

vref_s=0.5;

dac_code=0x0029;

pwm=0;

vref_t=(int)(vref_s/5.0*256.0);

D=10;

while(1)

{

pwm=~pwm; //PWM波产生部分

if(pwm==0)

a=10-D;

else

a=D;

while(a>0)

{

for(ad_n=0;ad_n<20;ad_n++)//AD转换、检测部分

{

start_ad();

delayms(10);

temp=get_ad();

if(temp>=adval_t)

adval_t=temp;

}

dac_spi(dac_code); //输出code值给DAC7811

delayus(5);

a--;

}

}

}

//定时器0中断函数

void T0_time_interrupt() interrupt 1

{

TH0=(65536-45872)/256;

TL0=(65536-45872)%256;

T0_time++;

if(T0_time>=5)

{

T0_time=0; /*每100ms*/

adval=adval_t; /*取出幅值*/

d_vout(); /*进行处理*/

adval_t=0;

}

}

程序设计思路:

——Adval_t为检测电压的暂存值;adval为取得的幅值,将其与设定值相比较——程序设计为取输出电压的幅值进行处理。函数的检测部分,在多个周期的多个点处进行抽样,得到比前一次抽样大的值则给adval_t赋新值,直到中断100ms中断产生则将最后取得的最大值赋给adval进行处理,数据处理的函数为d_vout()

——得到输出电压幅值后,将adval与设定电压幅值相比较(vref_t为转化后的值,与adval直接比较),若adval>vref_t,说明输出电压幅值应该减小,增益应该减小,相应dac_code应该增大——dac_code++;反之,dac_code--。同时通过增益计算占空比。

——每100ms进行的数据处理得到的dac_code,由dac_spi函数输出给DAC7811控制作出相应变化,从而完成一次控制。

——如此循环,直到输出电压与设定电压相符。

相关主题
相关文档
最新文档