打印
[活动]

【APM32F107VC MINIBOARD开发板测评】2.ADC与DAC

[复制链接]
511|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xld0932|  楼主 | 2023-2-19 17:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xld0932 于 2023-2-19 17:27 编辑

在极海的官网上,还没有发布APM32F107VC芯片的数据手册和用户手册,所以就先参考官方的SDK软件包的示例功能来对APM32F107和这MINI Board进行熟悉了……在官方最新的APM32F10x_SDK_V1.8软件包中ADC实现了模拟看门狗、连续采样模式、DMA方式、双ADC单元采样、以及多通道扫描采样这几个示例功能,在DAC中实现了噪声波形和DAC输出电压,ADC再进行采样的功能……我们对照DAC_ADC的功能进行熟悉和测试……

首先是配置ADC:将PA0配置为ADC功能的模拟采样端口引脚、然后对ADC1的功能参数进行初始化配置,因为只使用了一个ADC采样通道,所以配置为独立通道采样,使能连续采样模式,这样在开始ADC采样后,就会不停的去循环采样这一个通道的ADC数值了;不使用ADC触发采样的功能,采样的ADC结果使用右对齐的方式……然后将ADC通道的采样时间配置为ADC_SAMPLETIME_239CYCLES5,并使能ADC采样完成/结束的中断功能,最后使能并开始ADC采样,参考代码如下:
/*!
  * [url=home.php?mod=space&uid=247401]@brief[/url]       ADC Init
  *
  * @param       None
  *
  * @retval      None
  *
  */
void ADC_Init(void)
{
    ADC_Config_T  ADC_ConfigStruct;
    GPIO_Config_T GPIO_ConfigStruct;

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);

    GPIO_ConfigStructInit(&GPIO_ConfigStruct);
    GPIO_ConfigStruct.pin   = GPIO_PIN_0;
    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
    GPIO_ConfigStruct.mode  = GPIO_MODE_ANALOG;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);

    ADC_Reset(ADC1);

    ADC_ConfigStructInit(&ADC_ConfigStruct);
    ADC_ConfigStruct.mode               = ADC_MODE_INDEPENDENT;
    ADC_ConfigStruct.scanConvMode       = DISABLE;
    ADC_ConfigStruct.continuosConvMode  = ENABLE;
    ADC_ConfigStruct.externalTrigConv   = ADC_EXT_TRIG_CONV_None;
    ADC_ConfigStruct.dataAlign          = ADC_DATA_ALIGN_RIGHT;
    ADC_ConfigStruct.nbrOfChannel       = 1;
    ADC_Config(ADC1, &ADC_ConfigStruct);

    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_239CYCLES5);

    ADC_EnableInterrupt(ADC1, ADC_INT_EOC);

    NVIC_EnableIRQRequest(ADC1_2_IRQn, 1, 1);

    ADC_Enable(ADC1);

    ADC_EnableSoftwareStartConv(ADC1);
}

其次是配置DAC:将PA4配置为DAC功能的模拟输出端口引脚,然后对DAC的功能参数进行初始化配置,不使用触发的方式和自生成的波形、配置输出BUFFER使能及DAC_LFSR_MASK_BIT11_1的功能位,最后使能DAC,参考代码如下……
/*!
  * [url=home.php?mod=space&uid=247401]@brief[/url]       DAC Init
  *
  * @param       None
  *
  * @retval      None
  *
  */
void DAC_Init(void)
{
    DAC_Config_T  DAC_ConfigStruct;
    GPIO_Config_T GPIO_ConfigStruct;

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);

    GPIO_ConfigStructInit(&GPIO_ConfigStruct);
    GPIO_ConfigStruct.pin   = GPIO_PIN_4;
    GPIO_ConfigStruct.mode  = GPIO_MODE_ANALOG;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);

    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_DAC);

    DAC_ConfigStructInit(&DAC_ConfigStruct);
    DAC_ConfigStruct.trigger             = DAC_TRIGGER_NONE;
    DAC_ConfigStruct.outputBuffer        = DAC_OUTPUT_BUFFER_ENBALE;
    DAC_ConfigStruct.waveGeneration      = DAC_WAVE_GENERATION_NONE;
    DAC_ConfigStruct.maskAmplitudeSelect = DAC_LFSR_MASK_BIT11_1;
    DAC_Config(DAC_CHANNEL_1, &DAC_ConfigStruct);

    DAC_Enable(DAC_CHANNEL_1);
}

最后我们看一下在ADC通道采样完成中断函数中的处理:通过DAC_ConfigChannel1Data函数配置DAC通道引脚输出不同电压值,为下次的ADC采样作准备;然后ADC读取上次ADC转换完成的转换结果,将其换算成对应的电压值,将其通过串口把结果打印出来……根据换算的电压值对其电压所处的范围进行判断,然后通过LED显示其对应的状态……最后清除此次的ADC中断标志位,ADC将继续下一循的采样处理,参考代码数下:
/*!
  * [url=home.php?mod=space&uid=247401]@brief[/url]     This function handles ADC interrupt Handler
  *
  * @param     None
  *
  * @retval    None
  *
  * @note
  */
void ADC1_2_IRQHandler(void)
{
    uint16_t ADC_Data = 0;
    uint16_t Voltage  = 0;

    DAC_ConfigChannel1Data(DAC_ALIGN_12BIT_R, DAC_Data);

    DAC_Data = (DAC_Data + 0x7F) % 0x0FFF;

    if (ADC_ReadStatusFlag(ADC1, ADC_FLAG_EOC))
    {
        ADC_Data = ADC_ReadConversionValue(ADC1);

        Voltage = (ADC_Data * 3300) / 4095;

        printf("\r\nVoltage : %d mV\r\n", Voltage);

        if (Voltage > 2000)            /* Voltage greater than 2000mv */
        {
            LED_Enable(2, ENABLE);
            LED_Enable(3, DISABLE);
        }
        else if (Voltage < 800)        /* Voltage less than 800mv */
        {
            LED_Enable(2, DISABLE);
            LED_Enable(3, ENABLE);
        }
        else                           /* 800mv <= Voltage <= 2000 */
        {
            LED_Enable(2, ENABLE);
            LED_Enable(3, ENABLE);
        }

        for(uint32_t i = 0; i < 0xFFFFF; i++)
        {
        }

        ADC_ClearStatusFlag(ADC1, ADC_FLAG_EOC);
    }
}

测试时我们将编译无误的程序下载到开发板,然后将PA0的ADC采样引脚与PA4的DAC输出引脚通过排线进行短接在一起,这样才能够正常测试其功能,通过LED灯的显示状态查看运行结果……
软件工程源代码:
Project_ADC_DAC.zip (483.83 KB)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:上海灵动微电子股份有限公司资深现场应用工程师
简介:诚信·承诺·创新·合作

70

主题

3001

帖子

31

粉丝