EFM32外设模块—OPAMP V1.10

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
1. 适用范围................................................................................. 错误!未定义书签。

2. 原理概述................................................................................. 错误!未定义书签。

3. 开发环境................................................................................. 错误!未定义书签。

4. 技术实现................................................................................. 错误!未定义书签。

5. 参考资料................................................................................. 错误!未定义书签。

6. 免责声明................................................................................. 错误!未定义书签。

1. 概述
运算放大器(Operational Amplifier,简称OPAMP)是EFM32系列微控制器片上模拟外设,经过恰当地选取外部元件,它能够实现各种模拟运算,如放大、加、减、微分和积分等。

EFM32芯片内拥有三个运算放大器(Gecko系列芯片内部没有运算放大器),分别为OPA0、OPA1和OPA2。

其中OPA0和OPA1是DAC模块的一部分,OPA2为独立的运算放大器。

OPAMP模块框图如图1.1所示。

图1.1 OPAMP模块框图
这三个运算放大器可以相互配合并通过搭配合适的外部电路和内部反馈满足复杂的应用需求。

每个运算放大器内部都包含一个阶梯电阻网络,这个阶梯电阻网络可以被配置成不同的比例以满足不同增益倍数的需求。

当运算放大器被配置为电压跟随器时,该电阻网络将被旁路。

EFM32内部的运算放大器的失调电压可以通过校准得到较低的失调电压(每LSB调节1.6mV)。

其特性有:
z支持轨到轨输入和轨到轨输出;
z内部带有阶梯电阻反馈网络;
z利用内部阶梯电阻网络可以实现可编程增益;
z多个可选的输出引脚;
z可以直接输出到ADC。

注:OPAMP0和OPAMP1属于DAC的一部分,当DAC使能时这两个运算放大器被用作了DAC的输出缓冲,因此当使用相应的DAC通道时,该通道对应的OPAMP需要被禁能。

2. FAQ
1. EFM32的OPAMP是轨到轨输出,为什么将OPA0和OPA1配置为双运放差分放大器时,输出的差分电压不能等于电源电压?
A:OPAMP在配置为双运放差分放大器时不能只关注差分输出幅度,还要考虑到每个OPAMP单独输出的幅度,如图2.1所示。

在该配置模式下电压的输出是相对的,例如V2输入2V电压,V1输入0V电压,R2等于R1,那么VDIFF理论输出为2V,但是实际上此时VDIFF输出无法达到2V,因为此时OPA1输出电压为(V2-V1)R2/R1+V2,其理论输出为4V,已高于电源电压,因此无法正常工作。

图2.1 双运放差分放大器电路
2. OPAMP0和OPAMP1可以与DAC一起使用吗?
A:不能,EFM32系列微控制器片上拥有三个运算放大器(Gecko系列芯片内部没有运算放大器),分别为OPA0、OPA1和OPA2。

但是只有OPA2是独立运算放大器,而OPA0和OPA1是DAC电路的一部分,所以OPA0和OPA1不能与DAC同时使用。

若使能OPA0和OPA1则DAC无法输出;禁能OPA0和OPA1,DAC恢复输出。

3. 如果想让DAC在辅助输出引脚也有电压输出,应该如何配置?
A:先配置DAC输出通道对应的OPAMP,开启辅助输出引脚,然后禁能OPAMP。

例如,如果DAC0的通道0想要辅助输出引脚输出DAC0的转换电压,可以在OPAMP0的配置中将辅助输出引脚使能,然后再禁能OPAMP0即可。

4. 将OPAMP组合成三运放差分放大器时可选的放大倍数为多少?
A:当将三个OPAMP组合成差分放大器时,差分放大器的增益是由OPA0和OPA1的组合增益所决定的,由于三运放差分电路的电阻网络对应的桥臂要对应成比例,所以只三种有效的差分增益可供使用,它们分别为1/3、1和3,此时OPA0 RESSEL和OPA2 RESSEL 的组合分别为0和4、1和1、4和0。

3. 实验指导
3.1 实验目的
掌握EnergyMicro Tiny Gecko系列微控制器EFM32TG840F32的OPAMP配置的方法。

3.2 实验设备
z硬件:PC机一台和EFM32TG-STK3300开发板一套;
z软件:IAR(或Keil)集成开发环境。

3.3 实验内容
本实验例程共有三个,将分别演示如何使用EFM32片上OPAMP构成同相比例放大器、
双运放差分放大器和三运放差分放大器。

例程OPAMP Collection1实现对信号的简单放大,利用OPAMP构成同相放大器,配置
放大倍数为3倍。

将输入信号放大3倍后输出到ADC通道0进行ADC采集,最后将采集
到的电压值通过LCD显示。

例程OPAMP Collection2实现信号的差模部分放大并输出,利用OPAMP1和OPAMP2
构成双运放差分放大电路,配置放大倍数为3倍。

利用ADC的差分输入功能采集电压值并
通过LCD显示。

例程OPAMP Collection3实现三个运放进行级联形成三运放差分放大器,相对于例程OPAMP Collection2来说,提高了电压的输入范围。

3.4 试验步骤
1)连接开发板USB端口到电脑的USB端口,打开MCU电源;
2)打开Keil(或IAR)工程,重新编译并下载程序到开发板;
3)复位MCU,观察液晶屏所显示的电压值。

3.5 实验参考程序
3.5.1 例程OPAMP Collection1
系统上电后首先对LCD进行初始化,显示基本界面,然后对OPAMP进行初始化。

OPAMP的初始化函数如程序清单3.1所示。

程序清单3.1 实验1 OPAMP初始化函数
void opampInit (void)
{
CMU_ClockEnable(cmuClock_DAC0, true); /* 使能DAC模块时钟*/
/*
* 配置OPAMP结构体
*/
OPAMP_Init_TypeDef tOpConfiguration0 = {
.negSel = opaNegSelResTap, /* 反相输入接阶梯电阻网络 */
.posSel = opaPosSelPosPad, /* 同相输入接外部引脚*/ .outMode = opaOutModeAll, /* 主和辅助输出都使能*/
.resSel = opaResSelR2eq2R1, /* 阶梯电阻网络比例R2=2R1 */
.resInMux = opaResInMuxVss, /* 阶梯电阻网络输入连接VSS */
.outPen = DAC_OPA0MUX_OUTPEN_OUT4, /* 使能可选输出OUT4以便AD采集 */
.bias = _DAC_BIASPROG_BIASPROG_DEFAULT,
/* 使用默认的偏置电流配置*/ .halfBias = 0, /* 不使用减半偏置电流配置 */
.lpfPosPadDisable = false, /* 同相输入引脚无低通滤波 */
.lpfNegPadDisable = false, /* 反相输入引脚无低通滤波 */
.nextOut = false, /* 禁能输出到下个OPAMP */
.npEn = false, /* 不连接反相输入引脚*/ .ppEn = true, /* 连接同相输入引脚*/
.shortInputs = false, /* 不短路输入运放引脚*/ .hcmDisable = false, /* 开启轨到轨输入特性*/ .defaultOffset = true, /* 使用出厂失调电压校准值 */
.offset = 0 /* 使用出厂校准值,该位无意义 */ };
/*
* 使能并配置OPAMP
*/
OPAMP_Enable(DAC0, OPA0, &tOpConfiguration0);
}
在该初始化函数中,首先开启DAC模块时钟(OPAMP是DAC的一部分,时钟与DAC
模块一致)。

然后将OPAMP0的反相输入端连接到阶梯电阻网络,同相输入端接外部引脚。

因为要用到OPAMP的输出连接到ADC通道0,因此输出模式选择主输出和辅助输出都使能。

阶梯电阻的比例配置为R2=2R1,这样就可以得到3倍的放大增益。

为了提高运算放大
器的输入范围,开启轨到轨的输入特性。

失调电压校准使用出厂自带的校准值。

在ADC的配置中,需要注意的是采集通道的选择,因为OPAMP0只能输出到ADC的
通道0,因此需要将ADC的采集通道配置为通道0,初始化函数如程序清单3.2所示。

程序清单3.2 实验1 ADC初始化函数
void adcInit (void)
{
CMU_ClockEnable(cmuClock_ADC0, true); /* 使能ADC模块时钟*/
ADC_Init_TypeDef tAdcInit = {
.ovsRateSel = adcOvsRateSel2, /* ADC过采样配置 */
.lpfMode = adcLPFilterBypass, /* 旁路输入滤波RC电路*/
.warmUpMode = adcWarmupNormal, /* 正常预热模式 */ .timebase = ADC_TimebaseCalc(0), /* 基时间配置*/
.prescale = ADC_PrescaleCalc(7000000, 0), /* ADC时钟分频配置 */ .tailgate = false /* 不使能Tailgate */ };
ADC_InitSingle_TypeDef tSingleInit = {
*/ .prsSel = adcPRSSELCh0, /* 选择PRS通道0
.acqTime = adcAcqTime16, /* 配置采集时间为16周期 */ .reference = adcRefVDD, /* 使用VDD参考电压*/ .resolution = adcRes12Bit, /* 使用12位分辨率 */ .input = adcSingleInpCh0, /* 输入选择通道0 */ .diff = false, /* 不采用差分采集模式*/
.prsEnable = false, /* 禁能PRS输入 */
.leftAdjust = false, /* 使用右对准*/
.rep = false /* 不使用连续转换 */ };
ADC_Init(ADC0, &tAdcInit);
初始化ADC单次转换*/
/*
ADC_InitSingle(ADC0,
&tSingleInit);
}
3.5.2 例程OPAMP Collection2
在该例程中,OPAMP的初始化函数如程序清单3.3所示。

程序清单3.3 实验2 OPAMP初始化函数
void opampInit (void)
{
CMU_ClockEnable(cmuClock_DAC0, true); /* 使能DAC模块时钟*/
/*
* 配置OPAMP结构体
*/
OPAMP_Init_TypeDef tOpConfiguration1 = {
.negSel = opaNegSelUnityGain, /* 反相输入配置为跟随器*/ .posSel = opaPosSelPosPad, /* 同相输入接外部引脚*/ .outMode = opaOutModeAlt, /* 辅助输出使能*/ .resSel = opaResSelDefault, /* 不使用阶梯电阻网络*/ .resInMux = opaResInMuxDisable, /* 阶梯电阻网络输入禁能*/ .outPen = 0, /* 不使能可选输出OUT */ .bias = _DAC_BIASPROG_BIASPROG_DEFAULT,
/* 使用默认的偏置电流配置 */ .halfBias = 0, /* 不使用减半偏置电流配置 */
.lpfPosPadDisable = false, /* 同相输入引脚无低通滤波 */
.lpfNegPadDisable = false, /* 反相输入引脚无低通滤波 */
.nextOut = true, /* 输出到下个OPAMP */ .npEn = false, /* 不连接反相输入引脚*/ .ppEn = true, /* 连接同相输入引脚*/
.shortInputs = false, /* 不短路输入运放引脚*/ .hcmDisable = false, /* 开启轨到轨输入特性*/
.defaultOffset = true, /* 使用出厂失调电压校准值 */
.offset = 0 /* 使用出厂校准值,该位无意义 */ };
OPAMP_Init_TypeDef tOpConfiguration2 = {
.negSel = opaNegSelResTap, /* 反相输入接阶梯电阻网络 */
.posSel = opaPosSelPosPad, /* 同相输入接外部引脚*/ .outMode = opaOutModeMain, /* 主输出使能*/
.resSel = opaResSelR2eq3R1, /* 阶梯电阻网络比例R2=3R1 */
.resInMux = opaResInMuxOpaIn, /* 阶梯电阻网络输入连接前一个OP */
.outPen = DAC_OPA0MUX_OUTPEN_OUT1, /* 使能可选输出OUT1以便AD采集 */
.bias = _DAC_BIASPROG_BIASPROG_DEFAULT,
/* 使用默认的偏置电流配置*/ .halfBias = 0, /* 不使用减半偏置电流配置 */
.lpfPosPadDisable = false, /* 同相输入引脚无低通滤波 */
.lpfNegPadDisable = false, /* 反相输入引脚无低通滤波 */
.nextOut = false, /* 禁能输出到下个OPAMP */
.npEn = false, /* 不连接反相输入引脚*/ .ppEn = true, /* 连接同相输入引脚*/
.shortInputs = false, /* 不短路输入运放引脚*/ .hcmDisable = false, /* 开启轨到轨输入特性*/ .defaultOffset = true, /* 使用出厂失调电压校准值 */
.offset = 0 /* 使用出厂校准值,该位无意义 */ };
/*
* 使能并配置OPAMP1,OPAMP2
*/
OPAMP_Enable(DAC0, OPA1, &tOpConfiguration1);
OPAMP_Enable(DAC0, OPA2, &tOpConfiguration2);
}
在OPAMP初始化函数中,首先开启DAC模块时钟,将OPAMP1的反相输入端配置为
电压跟随器,同相输入端接外部引脚,因为要用到输出到OPAMP2的阶梯电阻网络,因此
要使能输出到下一个OPAMP。

在OPAMP2的配置中,阶梯电阻网络的输入要选择上一个OPAMP的输出。

与例程1中OPAMP1的阶梯电阻网络比例配置不同,其阶梯电阻网络的比
例要配置为R2=3R1才能实现3倍的增益。

ADC的配置中基本和上一个例程相同,不同之处在于本例程中ADC需要配置为差分输入,因此在输入通道选择时需要选择通道0和1,并使能差分采集模式,初始化函数如程序
清单3.4所示。

程序清单3.4 实验2 ADC初始化函数
void adcInit (void)
{
CMU_ClockEnable(cmuClock_ADC0, true); /* 使能ADC模块时钟 */
ADC_Init_TypeDef tAdcInit = {
.ovsRateSel = adcOvsRateSel2, /* ADC过采样配置*/ .lpfMode = adcLPFilterBypass, /* 旁路输入滤波RC电路 */
.warmUpMode = adcWarmupNormal, /* 正常预热模式*/ .timebase = ADC_TimebaseCalc(0), /* 基时间配置*/
.prescale = ADC_PrescaleCalc(7000000, 0), /* ADC时钟分频配置*/ .tailgate = false /* 不使能Tailgate */ };
ADC_InitSingle_TypeDef tSingleInit = {
.prsSel = adcPRSSELCh0, /* 选择PRS通道0 */ .acqTime = adcAcqTime16, /* 配置采集时间为16周期 */
.reference = adcRef2V5, /* 使用2.5V参考电压 */ .resolution = adcRes12Bit, /* 使用12位分辨率*/ .input = adcSingleInpCh0Ch1, /* 输入选择通道0和通道1 */ .diff = true, /* 采用差分采集模式*/ .prsEnable = false, /* 禁能PRS输入*/ .leftAdjust = false, /* 使用右对准*/
.rep = false /* 不使用连续转换*/ };
ADC_Init(ADC0, &tAdcInit);
初始化ADC单次转换 */
/*
ADC_InitSingle(ADC0,
&tSingleInit);
}
在该实验例程中,因为双运放差分电路的输出电压是OPAMP2的输出电压相对OPAMP2的输入电压之差,因此OPAMP2配置中需将输出连接到ADC通道0(PD0),同
时还需要将OPAMP2的输入引脚(PD4)与ADC的通道1(PD1)相连,ADC将采集到差
分电压。

3.5.3 例程OPAMP Collection3
程序在上电后对LCD外设进行初始化,然后配置OPAMP,在配置函数中对三个运算
放大器都需要进行相应配置。

本例程中OPAMP0和OPAMP1配置为跟随器, OPAMP0的
阶梯电阻网络的比例必须与OPAMP2的阶梯电阻网络的比例相反。

ADC配置为单端采集模式,与例程1相同。

OPAMP的初始化函数如程序清单3.5所示。

程序清单3.5 实验3 OPAMP初始化代码
void opampInit (void)
{
CMU_ClockEnable(cmuClock_DAC0, true); /* 使能DAC模块时钟*/
/*
* 配置OPAMP结构体
*/
OPAMP_Init_TypeDef tOpConfiguration0 = {
.negSel = opaNegSelUnityGain, /* 反相输入配置为跟随器*/ .posSel = opaPosSelPosPad, /* 同相输入接外部引脚*/ .outMode = opaOutModeAlt, /* 可选输出使能*/
.resSel = opaResSelR2eq0_33R1, /* 阶梯电阻比例配置为R2=0.33R1 */
.resInMux = opaResInMuxNegPad, /* 阶梯电阻网络接反相输入引脚 */ .outPen = 0, /*不使能可选输出OUT */ .bias = _DAC_BIASPROG_BIASPROG_DEFAULT,
/* 使用默认的偏置电流配置*/ .halfBias = 0, /* 不使用减半偏置电流配置 */
.lpfPosPadDisable = false, /* 同相输入引脚无低通滤波 */
.lpfNegPadDisable = false, /* 反相输入引脚无低通滤波 */
.nextOut = false, /* 禁能输出到下个OPAMP */
.npEn = true, /* 连接反相输入引脚*/
.ppEn = true, /* 连接同相输入引脚*/
.shortInputs = false, /* 不短路输入运放引脚*/ .hcmDisable = false, /* 开启轨到轨输入特性*/ .defaultOffset = true, /* 使用出厂失调电压校准值 */
.offset = 0 /* 使用出厂校准值,该位无意义 */ };
OPAMP_Init_TypeDef tOpConfiguration1 = {
.negSel = opaNegSelUnityGain, /* 反相输入配置为跟随器*/ .posSel = opaPosSelPosPad, /* 同相输入接外部引脚*/ .outMode = opaOutModeAlt, /* 可选输出使能*/ .resSel = opaResSelDefault, /* 不使用阶梯电阻网络*/ .resInMux = opaResInMuxDisable, /* 阶梯电阻网络输入禁能*/ .outPen = 0, /*不使能可选输出OUT */ .bias = _DAC_BIASPROG_BIASPROG_DEFAULT,
/* 使用默认的偏置电流配置*/ .halfBias = 0, /* 不使用减半偏置电流配置 */
.lpfPosPadDisable = false, /* 同相输入引脚无低通滤波 */
.lpfNegPadDisable = false, /* 反相输入引脚无低通滤波 */
.nextOut = true, /* 输出到下个OPAMP */ .npEn = false, /* 不连接反相输入引脚*/ .ppEn = true, /* 连接同相输入引脚*/
.shortInputs = false, /* 不短路输入运放引脚*/ .hcmDisable = false, /* 开启轨到轨输入特性*/ .defaultOffset = true, /* 使用出厂失调电压校准值 */
.offset = 0 /* 使用出厂校准值,该位无意义 */ };
OPAMP_Init_TypeDef tOpConfiguration2 = {
.negSel = opaNegSelResTap, /* 反相输入接阶梯电阻网络 */
.posSel = opaPosSelResTapOpa0, /* 同相输入接OP0的阶梯电阻网络 */
.outMode = opaOutModeMain, /* 主输出使能*/
.resSel = opaResSelR2eq3R1, /* 阶梯电阻网络比例R2=3R1 */
.resInMux = opaResInMuxOpaIn, /* 阶梯电阻网络输入连接前一个OP */
.outPen = DAC_OPA0MUX_OUTPEN_OUT1, /* 使能可选输出OUT1以便AD采集 */
.bias = _DAC_BIASPROG_BIASPROG_DEFAULT,
/* 使用默认的偏置电流配置*/ .halfBias = 0, /* 不使用减半偏置电流配置 */
.lpfPosPadDisable = false, /* 同相输入引脚无低通滤波 */
.lpfNegPadDisable = false, /* 反相输入引脚无低通滤波 */
.nextOut = false, /* 禁能输出到下个OPAMP */
.npEn = false, /* 不连接反相输入引脚*/ .ppEn = false, /* 不连接同相输入引脚*/ .shortInputs = false, /* 不短路输入运放引脚*/ .hcmDisable = false, /* 开启轨到轨输入特性*/ .defaultOffset = true, /* 使用出厂失调电压校准值 */
.offset = 0 /* 使用出厂校准值,该位无意义 */ };
/*
* 使能并配置OPAMP1,OPAMP2
*/
OPAMP_Enable(DAC0, OPA0, &tOpConfiguration0);
OPAMP_Enable(DAC0, OPA1, &tOpConfiguration1);
OPAMP_Enable(DAC0, OPA2, &tOpConfiguration2);
}
在该初始化函数中,OPAMP0和OPAMP1配置为电压跟随器,其中OPAMP0的阶梯电
阻网络需配置为R2=R1 / 3,并且将阶梯电阻网络连接到反相输入引脚。

使能OPAMP1输出
到OPAMP2,将OPAMP2的同相输入端连接OPAMP0的阶梯电阻网络,反相输入端连接自
身的阶梯电阻网络,并且配置阶梯电阻网络比例为R2=3R1。

其中OPAMP0和OPAMP2的
阶梯电阻网络配置比例必须相反。

ADC的配置与例程1完全相同,这里不再赘述。

通过以上配置,片上的3个运算放大
器就构成了三运放差分放大电路。

3.6 实验结果
1. 实验1 OPAMP Collection1
利用另一块STK3300开发板的DAC输出0.5V电压,将两块开发板共地,然后将DAC
的输出连接到OPAMP0的同相输入引脚(PC4),可以通过LCD看到ADC采集到的电压值
为1.5V。

2. 实验2 OPAMP Collection2
利用另一块STK3300开发板的DAC提供0.3V电压,两个开发板共地后将该电压输出
连接到PD4引脚,同时将OPAMP1的同相输入引脚(PD6)接地,此时LCD上显示0.9V
电压值。

然后将OPAMP1的同相输入引脚PD6也连接到DAC提供的0.3V电压,相当于双
运放差分放大电路输入了0.3V的共模电压,差模电压为0。

此时可以通过LCD可以看到
产品应用笔记 ©2012 Guangzhou ZLG MCU
Technology Co., Ltd.
10 ADC 采集到的电压值为0,共模电压被差分放大电路抑制。

注:ADC 被配置为差分采集模式,参考电压为2.5V ,因此差模放大输出电压不能超过1.25V (即DAC 输出不能超过0.4V ),否则将超过ADC 的量程。

3. 实验3 OPAMP Collection3
利用另一块STK3300开发板的DAC 提供0.5V 的电压。

两个开发板共地后先将OPAMP0的反相输入引脚(PC5)接地,再将DAC 输出电压接到OPAMP0的同相输入引脚(PC4),OPAMP1的同相输入引脚(PD6)接地。

此时LCD 会显示1.5V 电压值。

接着将OPAMP1的同相输入引脚PD6也连接到DAC 提供的0.5V 电压,这样相当于双运放差分放大电路输入了0.5V 的共模电压,差模电压为0。

此时通过LCD 可以看到ADC 采集到的电压值为0。

说明共模电压得到有效的抑制。

相关文档
最新文档