[APM32F0]

DMA_ADC多通道采集数据如何获取?

[复制链接]
984|17
手机看帖
扫描二维码
随时随地手机跟帖
skylinyk|  楼主 | 2022-7-26 23:27 | 显示全部楼层 |阅读模式
官网例程都是单通道,有没有大神有做过多通道的可以指教一下,目前想用ADC8--PB0,ADC9--PB1两个ADC进行双通道采样,例如在DMA-ADC例程内如何设置?
/*!
* @file        main.c
*
* @brief       Main program body
*
* @version     V1.0.1
*
* @date        2021-07-01
*
* @attention
*
*  Copyright (C) 2020-2022 Geehy Semiconductor
*
*  You may not use this file except in compliance with the
*  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
*
*  The program is only for reference, which is distributed in the hope
*  that it will be usefull and instructional for customers to develop
*  their software. Unless required by applicable law or agreed to in
*  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
*  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
*  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
*  and limitations under the License.
*/

#include "Board.h"
#include "stdio.h"
#include "apm32f0xx_gpio.h"
#include "apm32f0xx_misc.h"
#include "apm32f0xx_dma.h"
#include "apm32f0xx_adc.h"

/** printf function configs to USART2*/
#define DEBUG_USART  USART1

/** define Tramismit Buf Size*/
#define BufSize 0x100

/** Delay */
void Delay(void);
/** ADC Init */
void APM_MINI_ADC_Init(void);
/** DMA Init */
void APM_MINI_DMA_Init(uint32_t* Buf);

/*!
* @brief       Main program
*
* @param       None
*
* @retval      None
*
* @note
*/
int main(void)
{
     /** DMA value from ADC*/
    uint32_t DMA_ConvertedValue = 0;
     /** ADC convert to volatage*/
    float    ADC_ConvertedValue = 0;

    APM_MINI_LEDInit(LED2);
    APM_MINI_LEDInit(LED3);
    APM_MINI_COMInit(COM1);

    APM_MINI_ADC_Init();
    APM_MINI_DMA_Init(&DMA_ConvertedValue);

    /** start conversion*/
    while(!ADC_ReadStatusFlag(ADC_FLAG_ADRDY));
    ADC_StartConversion();

    for(;;)
    {
         /** convert value*/
        ADC_ConvertedValue = (float)DMA_ConvertedValue/4096*3.3;
        printf("\r\n  AD value = 0x%04X \r\n", DMA_ConvertedValue);
        printf("\r\n  AD value = %f V \r\n"  ,ADC_ConvertedValue);
        Delay();
    }
}

/*!
* @brief       DMA_ADC Init
*
* @param       None
*
* @retval      None
*
* @note
*/
void APM_MINI_ADC_Init()
{
    GPIO_Config_T gpioConfig;
    ADC_Config_T  adcConfig;

    /** RCM Enable*/
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
    /** GPIO Configuration */
    gpioConfig.pin = GPIO_PIN_0;
    gpioConfig.mode = GPIO_MODE_AN;
    gpioConfig.pupd = GPIO_PUPD_PU;
    GPIO_Config(GPIOB, &gpioConfig);
    /** ADC Configuration */
    ADC_Reset();
    ADC_ConfigStructInit(&adcConfig);
    /** Set resolution*/
    adcConfig.resolution = ADC_RESOLUTION_12B;
    /** Set dataAlign*/
    adcConfig.dataAlign = ADC_DATA_ALIGN_RIGHT;
    /** Set scanDir*/
    adcConfig.scanDir = ADC_SCAN_DIR_UPWARD;
    /** Set convMode continous*/
    adcConfig.convMode = ADC_CONVERSION_CONTINUOUS;
    /** Set extTrigConv*/
    adcConfig.extTrigConv = ADC_EXT_TRIG_CONV_TRG0;
    /** Set TrigEdge*/
    adcConfig.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;

    ADC_Config(&adcConfig);

    ADC_ConfigChannel(ADC_CHANNEL_8, ADC_SAMPLE_TIME_239_5 );

    /** Calibration*/
    ADC_ReadCalibrationFactor();

    ADC_EnableDMA();
    /** Enable ADC*/
    ADC_Enable();
}

/*!
* @brief       DMA Init
*
* @param       None
*
* @retval      None
*
* @note
*/
void APM_MINI_DMA_Init(uint32_t* Buf)
{
    /** Enable DMA clock */
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
    /** DMA Configure */
    DMA_Config_T dmaConfig;
    /** size of buffer*/
    dmaConfig.bufferSize = 1;
    /** set memory Data Size*/
    dmaConfig.memoryDataSize = DMA_MEMORY_DATASIZE_HALFWORD;
    /** Set peripheral Data Size*/
    dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATASIZE_HALFWORD;
    /** Enable Memory Address increase*/
    dmaConfig.memoryInc = DMA_MEMORY_INC_DISABLE;
    /** Disable Peripheral Address increase*/
    dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
    /** Reset Circular Mode*/
    dmaConfig.circular = DMA_CIRCULAR_ENABLE;
    /** Disable M2M*/
    dmaConfig.memoryTomemory = DMA_M2M_DISABLE;
    /** set priority*/
    dmaConfig.priority = DMA_PRIORITY_LEVEL_HIGHT;
    /** read from peripheral*/
    dmaConfig.direction = DMA_DIR_PERIPHERAL;
    /** Set memory Address*/
    dmaConfig.memoryAddress = (uint32_t)Buf;
    /** Set Peripheral Address*/
    dmaConfig.peripheralAddress = (uint32_t)&ADC->DATA;

    DMA_Config(DMA1_CHANNEL_1,&dmaConfig);
    /** Clear DMA TF flag*/
    DMA_ClearIntFlag(DMA1_INT_FLAG_TF1);
    /** Enable DMA Interrupt*/
    DMA_EnableInterrupt(DMA1_CHANNEL_1,DMA_INT_TFIE);

    NVIC_EnableIRQRequest(DMA1_CH1_IRQn,2);

    DMA_Enable(DMA1_CHANNEL_1);
}

/*!
* @brief       DMA_Interrupt
*
* @param       None
*
* @retval      None
*
* @NOTE        This function need to put into DMA1_CH1_IRQHandler in apm32f0xx_int.c
*/
void DMA_Isr(void)
{
    if(DMA_ReadStatusFlag(DMA1_FLAG_TF1))
    {
        /** do something*/
        DMA_ClearStatusFlag(DMA1_FLAG_TF1);
    }
}

/*!
* @brief       Delay
*
* @param       None
*
* @retval      None
*
* @note
*/
void Delay(void)
{
    volatile uint32_t delay = 0xFFFFF;

    while(delay--);
}

/*!
* @brief       Redirect C Library function printf to serial port.
*              After Redirection, you can use printf function.
*
* @param       ch:  The characters that need to be send.
*
* @param       *f:  pointer to a FILE that can recording all information
*              needed to control a stream
*
* @retval      The characters that need to be send.
*
* @note
*/
int fputc(int ch, FILE *f)
{
        /** send a byte of data to the serial port */
        USART_TxData(DEBUG_USART,(uint8_t)ch);

        /** wait for the data to be send  */
        while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);

        return (ch);
}


使用特权

评论回复
Fanexs168| | 2022-7-27 10:16 | 显示全部楼层
最新版F0xx SDK里,DMA例程目录那有配套ADC使用的例程。可以再看看

使用特权

评论回复
Fanexs168| | 2022-7-27 11:25 | 显示全部楼层
或者参考下我这个例程配置。多通道ADC+DMA+TMR硬件定时器触发,能用的都用了。
文件放到SDK的ADC例程文件夹下解压缩编译使用

ADC_TMRTrigger_DMA.rar

30.09 KB

使用特权

评论回复
skylinyk|  楼主 | 2022-7-27 19:25 | 显示全部楼层
Fanexs168 发表于 2022-7-27 11:25
或者参考下我这个例程配置。多通道ADC+DMA+TMR硬件定时器触发,能用的都用了。
文件放到SDK的ADC例程文件夹 ...

非常感谢!感激之情无以言表,我下来看看

使用特权

评论回复
lajfda001| | 2022-8-16 10:24 | 显示全部楼层
非常感谢楼主的分享。谢谢。

使用特权

评论回复
lajdfla001| | 2022-8-16 10:27 | 显示全部楼层
感谢二楼的分享,不错的例程。

使用特权

评论回复
udaidfa002| | 2022-8-16 11:05 | 显示全部楼层
感谢分享。不错的资料。。。。

使用特权

评论回复
lzbf| | 2022-8-16 20:16 | 显示全部楼层
直接配置寄存器和数组就行。

使用特权

评论回复
kkzz| | 2022-8-16 20:38 | 显示全部楼层
你需要采集几路数据呢  

使用特权

评论回复
pklong| | 2022-8-17 15:52 | 显示全部楼层
dma直接转换的   

使用特权

评论回复
houjiakai| | 2022-8-20 13:01 | 显示全部楼层
感觉DMA好用很多,ADC不需要考虑问题。   

使用特权

评论回复
linfelix| | 2022-8-20 19:29 | 显示全部楼层
最大的转换速度是多少?   

使用特权

评论回复
saservice| | 2022-8-20 21:01 | 显示全部楼层
DMA_ADC多通道采集会有信号之间的干扰吗   

使用特权

评论回复
robertesth| | 2022-8-21 20:27 | 显示全部楼层
这个有什么问题吗   

使用特权

评论回复
BDW杜兰特| | 2022-9-5 10:15 | 显示全部楼层
Fanexs168 发表于 2022-7-27 11:25
或者参考下我这个例程配置。多通道ADC+DMA+TMR硬件定时器触发,能用的都用了。
文件放到SDK的ADC例程文件夹 ...

感谢楼主分享

使用特权

评论回复
AloneKaven| | 2022-11-4 21:40 | 显示全部楼层
直接配置寄存器和数组就行

使用特权

评论回复
Undshing| | 2023-1-3 16:07 | 显示全部楼层
最大的转换速度是多少?   

使用特权

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

本版积分规则

3

主题

21

帖子

1

粉丝