STM32CubeMX使用之DMA方式使用ADCADC使用遇到的问题

Posted 何事误红尘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32CubeMX使用之DMA方式使用ADCADC使用遇到的问题相关的知识,希望对你有一定的参考价值。

目录

一、概述

本文记录下ADC的使用过程,主要是后续使用,能有个参考。同样,以后遇到的ADC问题,也都收录在本文后面。
芯片: STM32G0B1RCT6

二、Pinout&Configuration

2.1 选择端口



2.2 开启DMA中断

三、测试ADC

测试代码可参考demo工程,同样是DMA方式:

主要步骤为:

  1. 定义采集值缓存
  2. 开启ADC校准
  3. 开启DMA功能*。
  4. 主循环内重复开启ADC转换并打印采集结果:
  5. 发现打印结果如下,每次只转换了一个通道:

    开启ADC后1S还不够采集完成吗?
  6. 回到demo中查看,是在回调函数中设置标志,然后在主循环中判断标志才进行打印。

    修改后果然正常了:

    这样看来每次开启ADC,只转换了一个通道。CubeMX设置有些问题。使能了scan扫描模式,应该会转换完所有通道吧?回头再看下。

注意:HAL_ADC_Start_DMA后,不要使用立即调用HAL_ADC_Start。

2021-12-9补充:

  1. 前面混合使用了HAL_ADC_Start_DMA和HAL_ADC_Start,是有些问题的。可以只使用HAL_ADC_Start_DMA,但要注意,不能重复调用,每次转换完要先使用HAL_ADC_Stop_DMA关闭。

  2. 修改cube设置

    转换完所有通道后关闭ADC。

四、遇到的问题

4.1 采集到其他通道的值

使用N32G031C8开发板,采集channel1和channel8两路ADC。发现只给channel1输入2V电压,channel8采集值也随之改变。两次采集之间也增加了500ms延时,是什么原因呢?
暂时没有细究。开发板只是把IO直接引出来方便测试,并没有包含外围分压电路。在channel8也输入一路电压,可以看到channel1和channel8都能够正常采集了。

继续4.1的问题

硬件做好后测试,采集channel1、channel8、channel7三路电压,发现仍然存在问题:

正常情况下,只有ADU路是有电压的,但有时ADU会采集到0,或者HW_VER路采集到ADU的电压值。测试了多通道采集和连续转换,发现都不是问题的原因。开发板例程的ADC采集了浪路,参考设置是一样的,仍然有问题。最终发现,增加一个ADC_GetData函数,就可以了。

static uint16_t ADC_GetData(uint8_t ADC_Channel)

    uint16_t dat;
    
    ADC_ConfigRegularChannel(ADC1, ADC_Channel, 1, ADC_SAMP_TIME_56CYCLES5);
    /* Start ADC Software Conversion */
    ADC_EnableSoftwareStartConv(ADC1, ENABLE);
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ENDC)==0)
    
    ADC_ClearFlag(ADC1, ADC_FLAG_ENDC);
    ADC_ClearFlag(ADC1, ADC_FLAG_STR);
    dat = ADC_GetDat(ADC1);
    
    return dat;



#if USE_ADC1
static int32_t n32_adc1_read(uint8_t channel)

    int32_t read_value = 0;
    uint16_t dat;
    
//    ADC_ConfigRegularChannel(ADC1, channel, 1, ADC_SAMP_TIME_56CYCLES5);
//    /* Start ADC Software Conversion */
//    ADC_EnableSoftwareStartConv(ADC1, ENABLE);
//    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ENDC)==0)
//    
//    ADC_ClearFlag(ADC1, ADC_FLAG_ENDC);
//    ADC_ClearFlag(ADC1, ADC_FLAG_STR);
//    
    read_value = ADC_GetDat(ADC1);
//    dat = ADC_GetDat(ADC1);
//    read_value = dat;
    
    read_value = ADC_GetData(channel);

    return read_value;

#endif

为什么单独封装一个函数,效果就不一样了呢?暂时没搞明白

4.2 STM32 ADC没有输入电压时,采集结果不为0

单独写为一篇:添加链接描述

以上是关于STM32CubeMX使用之DMA方式使用ADCADC使用遇到的问题的主要内容,如果未能解决你的问题,请参考以下文章

STM32CubeMX使用之DMA使用SPI

STM32CubeMX使用之DMA使用SPI

STM32F103VET6基于STM32CubeMX 配置非DMA方式获取内部温度

STM32F103VET6基于STM32CubeMX创建串口中断+ DMA 不定长数据接收

STM32CubeMX使用之ADC

STM32F103VET6基于STM32CubeMX 配置DMA方式获取内部温度