EFM32片内外设--DAC之Alt output

来源:互联网 发布:unity3d软件下载 编辑:程序博客网 时间:2024/06/01 08:26

如果大家有看EFM32的datasheet里面有关DAC输出通道时,是否有时候看的不是很明白? DAC0_OUT0,DAC0_OUT0ALT? 这些是什么概念,以及如何将DAC配置到相应的GPIO口上?这个问题也曾困扰过我,后来弄清楚之后,却一直没来得及写一篇说明。现在就补上吧,希望还不算晚。

首先,需要说明的是,只有内部带OPA功能的EFM32型号,才会遇到DAC Alt Output的问题。型号包括TG(部分),LG,GG,WG等。其他型号的DAC输出,以G840为例,就只有DAC0_OUT0,DAC0_OUT1引脚。

其次,要配置为DAC0_OUT0ALT等引脚输出,需要额外配置OPA的寄存器。

以下我们分三种情况,来分别描述寄存器如何设置。第一种情况,在DAC的DAC0_OUT0引脚上输出一个模拟电压。这是最常用的情况。第二种情况是在DAC0_OUT0ALT引脚上输出一个模拟电压。第三种情况就是同时在DAC0_OUT0和DAC0_OUT0ALT输出模拟电压。这样就能覆盖所有的应用情况了。好了,Let‘s go。 开工吧。

硬件平台:TG STK,MCU:TG840. 通过查询TG840的Datasheet可以得知,DAC0_OUT0是PB11(#0),DAC0_OUT0ALT是PD0(#4).

软件:参考后面的代码。

首先,我们先实现第一种情况,在DAC的DAC0_OUT0引脚上输出一个模拟电压,主要是将DAC的输出模式配置为Output to pin only。即OUTMODE = 1。参考代码如下:

#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_dac.h"


/* Function prototypes */
void DAC_setup(void);
void DAC_WriteData(DAC_TypeDef *dac, unsigned int value, unsigned int ch);

/**************************************************************************//**
* @brief  Main function
* Setup of dac and calculating output value, enter em1 while dac is working
*****************************************************************************/
int main(void)
{
    /* Initialize chip */
    CHIP_Init();
   
    uint32_t DAC_Value;
   
    /* Initialise the DAC */
    DAC_setup();
   
    /* Enable DAC channel 0, located on pin PB11 */
    DAC_Enable(DAC0, 0, true);
   
    /* Calculate output to 0.5 V. */
    DAC_Value = (uint32_t)((0.8 * 4096) / 1.25);
   
    /* Write the new value to DAC register */
    DAC_WriteData(DAC0, DAC_Value, 0);
   
    while(1);
}


/**************************************************************************//**
* @brief  Setup DAC
* Configures and starts the DAC
*****************************************************************************/
void DAC_setup(void)
{
    /* Use default settings */
    DAC_Init_TypeDef        init        = DAC_INIT_DEFAULT;
    DAC_InitChannel_TypeDef initChannel = DAC_INITCHANNEL_DEFAULT;
   
    /* Enable the DAC clock */
    CMU_ClockEnable(cmuClock_DAC0, true);
   
    /* Calculate the DAC clock prescaler value that will result in a DAC clock
    * close to 500kHz. Second parameter is zero, if the HFPERCLK value is 0, the
    * function will check what the current value actually is. */
    init.prescale = DAC_PrescaleCalc(500000, 0);
   
    /* Set DAC's outmode to output to pin */
    init.outMode = dacOutputPin;
   
    /* Set reference voltage to 1.25V */
    init.reference = dacRef1V25;
   
    /* Initialize the DAC and DAC channel. */
    DAC_Init(DAC0, &init);
   
    DAC_InitChannel(DAC0, &initChannel, 0);
}


/**************************************************************************//**
* @brief  Write DAC conversion value
*****************************************************************************/
void DAC_WriteData(DAC_TypeDef *dac, unsigned int value, unsigned int ch)
{
    /* Write data output value to the correct register. */
    if (!ch)
    {
        dac->CH0DATA = value;
    }
    else
    {
        dac->CH1DATA = value;
    }
}

此时在STK的PB11引脚上应该能测得一个0.8V左右的模拟电压。接下来,我们看看如何将这个电压切换到PD0上去。修改的步骤如下:

1. 将DAC_CTRL寄存器中的OUTMODE配置为ADC。

2. DAC0通道0对应的OPA是OPA0,因此需要操作DACn_OPA0MUX寄存器。并且将该寄存器中的OUTPEN为OUT4。为何选择OUT4,是因为这里的OUT4,相当于选择Location4。可不是因为PD4的端口编号是4,才选择OUT4的哦。^_^

3. 配置DACn_OPA0MUX寄存器中OUTMODE。由于我现在仅想在PD4上输出,因此在这里配置为ALT。

配置部分的代码,请参考如下:

void DAC_setup(void)
{
    /* Use default settings */
    DAC_Init_TypeDef        init        = DAC_INIT_DEFAULT;
    DAC_InitChannel_TypeDef initChannel = DAC_INITCHANNEL_DEFAULT;
   
    /* Enable the DAC clock */
    CMU_ClockEnable(cmuClock_DAC0, true);
   
    /* Calculate the DAC clock prescaler value that will result in a DAC clock
    * close to 500kHz. Second parameter is zero, if the HFPERCLK value is 0, the
    * function will check what the current value actually is. */
    init.prescale = DAC_PrescaleCalc(500000, 0);
   
    /* Set DAC's outmode to output to ADC */
    init.outMode = dacOutputADC;
   
    /* Set reference voltage to 1.25V */
    init.reference = dacRef1V25;
   
    /* Initialize the DAC and DAC channel. */
    DAC_Init(DAC0, &init);
   
    DAC0->OPA0MUX &= ~ (_DAC_OPA0MUX_OUTMODE_MASK | _DAC_OPA0MUX_OUTPEN_MASK);
    DAC0->OPA0MUX |= DAC_OPA0MUX_OUTMODE_ALT | DAC_OPA0MUX_OUTPEN_OUT4;

   
    DAC_InitChannel(DAC0, &initChannel, 0);
}


经过以上的修改,应该可以在PD4上观察到0.8V的模拟电压了,而PB11上的0.8V则消失了。接下来我们看看如何在PD4和PB11上同时输出。需要修改的地方,如下所示:

1. 将DAC_CTRL寄存器中的OUTMODE配置为PINADC。代码如下:

void DAC_setup(void)
{
    /* Use default settings */
    DAC_Init_TypeDef        init        = DAC_INIT_DEFAULT;
    DAC_InitChannel_TypeDef initChannel = DAC_INITCHANNEL_DEFAULT;
   
    /* Enable the DAC clock */
    CMU_ClockEnable(cmuClock_DAC0, true);
   
    /* Calculate the DAC clock prescaler value that will result in a DAC clock
    * close to 500kHz. Second parameter is zero, if the HFPERCLK value is 0, the
    * function will check what the current value actually is. */
    init.prescale = DAC_PrescaleCalc(500000, 0);
   
    /* Set DAC's outmode to output to PINADC */
    init.outMode = dacOutputPinADC;

   
    /* Set reference voltage to 1.25V */
    init.reference = dacRef1V25;
   
    /* Initialize the DAC and DAC channel. */
    DAC_Init(DAC0, &init);
   
    DAC0->OPA0MUX &= ~ (_DAC_OPA0MUX_OUTMODE_MASK | _DAC_OPA0MUX_OUTPEN_MASK);
    DAC0->OPA0MUX |= DAC_OPA0MUX_OUTMODE_ALT | DAC_OPA0MUX_OUTPEN_OUT4;

   
    DAC_InitChannel(DAC0, &initChannel, 0);
}

这里主要是讲明了如何配置,才能达到DAC在Alt引脚上输入的效果。呵呵。刚开始的时候,DAC和OPA的关系有时候确实会让人绕,但是只要理清关系之后,程序思路也就会变得清晰。