自动增益可变放大器.docx
《自动增益可变放大器.docx》由会员分享,可在线阅读,更多相关《自动增益可变放大器.docx(14页珍藏版)》请在冰豆网上搜索。
自动增益可变放大器
电子设计综合实验项目报告
项目名称:
自动增益可变放大器
小组成员:
林伊、武正浩
学号:
20111112、20111201
目录
项目要求3
基本要求:
3
实现思路4
放大器:
4
DAC7811:
7
AGC电压:
7
源代码:
8
项目要求
题目:
自动增益可变放大器
要求:
用给定的MCU:
msp430g2553,制作一个有自动增益控制(AGC)的放大器
图表1
基本要求:
用给定运放TLC085制作一放大器
a)增益大于:
40dB
b)带宽大于:
1KHz~60KHz
c)放大器增益可控范围:
(输入信号频率为10KHz)大于35dB
d)可观察AGC电压(要求输出模拟直流电压,此电压应随放大器的输出同步变化,只看变化规律,不要求值的大小)
e)放大器需采用单电源工作(仅+5V供电,不允许用DC-DC等)实现带宽和增益上述指标
实现思路
放大器:
本项目提供一个D/A模块DAC7811芯片来实现,要想用运放实现放大无非两种基本电路,正向和反向比例放大电路,实现自动增益,肯定是对外围电路进行改变,怎样改变,一定是用这个DAC7811芯片,我一开始的想法是当输入信号变小,为了导致输出信号不变,可以在输入信号那补充一个电压或电流,但是事实上这样的实现并不容易,而且效果不好,见下图:
Figure1
上述方式不仅使波形变了,还不符合题目的自动增益可控,所以经过与老师同学商量,我对DAC7811进行了深度的了解,DAC7811的构造如下:
Figure2
我们通过SYNC、SCLK、SDIN这三个接口来与InputShiftRegister进行交互,把我们需要的操作码以及控制字输入到ControlLogic里,并把最终值调入DACRegister中,实现控制12-BitR-2RDAC。
其中上部分的组成如下图:
Figure3
改变DB11~DB0的值可以改变整个电阻网络,这样就能实现例如反向比例放大电路修改电阻一般的效果来改变放大的倍数,可以按下图连接:
Figure4
Figure5
这样就实现了修改电阻网络就修改了放大倍数,由于12BIT的可控电阻网络,写入4096,等效电阻为4096,其R值等于RFB,当写入的CODE值小于4096,等效电阻变小,由反向比例电路公式可得如下公式:
DAC7811:
这一切都有了之后就是如何向DAC7811里头写值,也就是它的时序是如何,通过阅读数据手册,可以得知,首先把SYNC拉高再拉低,相当于把Input寄存器清空复位,接着DAC会计数来自SCLK引脚的时钟信号,当计数到16个时钟后拉高SYNC,值则存入,SDIN与SCLK配合把值存入。
AGC电压:
采集正弦信号的峰值,所以涉及A/D转换部分,由于输入信号频率在1KHz~60KHz,由于采样定理,采样频率必须为被采样信号的两倍,虽然实际中最好为十倍,我们最后还是采用了两倍。
Msp430g2553此款芯片A/D采集过程若要稳定起码需要30个时钟,我的A/D模块选用时钟源smclk,其频率为8MHz,则8MHz除去30约为267KHz,其大于60KHz的两倍,能够实现采集,因为ADC采集0~3600mv的电压,把其映射到0~100%占空比方波,方波经过一个低通滤波则能输出一个平缓的,平均值与占空比相关的AGC电压。
源代码:
#include
//60khz用aclk不分频taccr0328
//因为p2.4要作为pwm输出
//所以控制DAC7811选用P2.0P2.1P2.2
//SYNCSCLKSDIN
#defineSYNC_UPP2OUT|=BIT0
#defineSYNC_LOWP2OUT&=~(BIT0)
#defineSCLK_UPP2OUT|=BIT1
#defineSCLK_LOWP2OUT&=~(BIT1)
#defineSDIN_UPP2OUT|=BIT2
#defineSDIN_LOWP2OUT&=~(BIT2)
#definenum10
/***全局变量***/
unsignedintADCMEM=0;//所有需要用到模拟量的都去读它
unsignedintADCMEMMAX[num]={0};
unsignedintADCMEMTEMP=1200;
unsignedintcode=0x28;
unsignedcharflag=0;
unsignedintflag1=0;//最终确定延时在程序中延时5S,其最后的最高值为以后固定不变的值
/**************/
voidinitSYS(void)//16msmclkmclk32.768kaclkP1.3按键输入
{
WDTCTL=WDTPW+WDTHOLD;
BCSCTL1=CALBC1_16MHZ;//Setrange
DCOCTL=CALDCO_16MHZ;
P1DIR&=~BIT3;//按键输入
P1OUT|=BIT3;
P1REN|=BIT3;
}
voidinitDAC7811(void)//P2.0~P2.2输出
{
P2DIR|=BIT0+BIT1+BIT2;//P2.0~2输出
}
voidDAC7811(intcmd,intcode)//cmd高4位code低12位
{
SYNC_UP;
//__delay_cycles(16000);//延时200ms
SCLK_UP;
SYNC_LOW;
//__delay_cycles(16000);
for(inti=0;i<4;i++)
{
//__delay_cycles(8000);
SCLK_UP;
//__delay_cycles(8000);
if((cmd>>(3-i))&0x01)
{
SDIN_UP;
}
else
{
SDIN_LOW;
}
SCLK_LOW;
}
for(inti=0;i<12;i++)
{
//__delay_cycles(8000);
SCLK_UP;
//__delay_cycles(8000);
if((code>>(11-i))&0x01)
{
SDIN_UP;
}
else
{
SDIN_LOW;
}
SCLK_LOW;
}
//__delay_cycles(8000);
//SCLK_UP;
//__delay_cycles(8000);
SYNC_UP;
}
voidinitADC(void)//smclk/216adcclockvcc~gndp1.1输入单通道重复采样p1.0做测试输出
{
ADC10CTL0=ADC10ON+ADC10IE+ADC10SHT_2+SREF_0+MSC;//ADC10ON,interruptenabled,16个adc_cloclk,vccandgnd,CHONGFU
ADC10CTL1=INCH_1+ADC10DIV_1+ADC10SSEL_3+CONSEQ_2;//inputA1,2分频,smclk,单通道重复采样
ADC10AE0|=0x02;//通道A1
P1DIR&=~0x02;//p1.1输入
P1DIR|=0x01;//p1.0输出
ADC10CTL0|=ENC+ADC10SC;//不要循环打开
//__bis_SR_register(GIE);//开启总中断
}
//ADC10interruptserviceroutine
#pragmavector=ADC10_VECTOR
__interruptvoidADC10_ISR(void)
{
ADCMEM=(unsignedint)(ADC10MEM*3.519);
if(ADCMEM<1650)//adc10mem
{
P1OUT&=~0x01;//turnoff//接灯
}
else
{
P1OUT|=0x01;//turnon
}
//检测输入控制dac,最好用置标志位的方法
if(ADCMEM>ADCMEMMAX[flag])
{
ADCMEMMAX[flag]=ADCMEM;
}
}
voidinitTIMER(void)//up_32768p2.4使能中断
{
//PWM
TA1CTL=TASSEL_2+MC_1+TAIE+ID_3;
TA1CCTL2=OUTMOD_7;
TA1CCR0=3280;//频率将近100Hz
TA1CCR2=1280;//纵向
P2DIR|=BIT4;
P2SEL|=BIT4;
_EINT();
}
//TimerA1interruptserviceroutine
#pragmavector=TIMER1_A1_VECTOR
__interruptvoidTimer_A1(void)
{
switch(TA1IV)
{
case4:
break;
case10:
if(ADCMEM>3280)
{
TA1CCR2=3280;
}
else
{
TA1CCR2=ADCMEM;
}
if(!
(P1IN&BIT3))//按下
{
DAC7811(1,0x28);
}
else
{
if(flag1<500)
{
flag1++;
DAC7811(1,code);
}
else
{
if(flag>(num-1))
{
for(inti=1;i{
ADCMEMMAX[0]+=ADCMEMMAX[i];
}
ADCMEMMAX[0]=ADCMEMMAX[0]/num;
if(ADCMEMMAX[0]{
code--;
DAC7811(1,code);
}
elseif(ADCMEMMAX[0]>ADCMEMTEMP)
{
code++;
DAC7811(1,code);
}
else
{
;
}
flag=0;
for(inti=0;i{
ADCMEMMAX[i]=0;
}
}
else
{
flag++;
}
}
}
break;
}
}
voidmain(void)
{
initSYS();
initDAC7811();
initADC();
initTIMER();
while
(1)
{
;
}
}