打印
[技术问答]

定时器触发ADC采样+DMA多路传输

[复制链接]
3037|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ZJY1|  楼主 | 2024-6-25 17:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用官方库样例ADC可以得到数据但是DMA传不出数据   代码如下
dma.c
#include "dma.h"

#define ADC_UNIT                        (CM_ADC1)  //ADC1基地址(起始地址)

#define ADC_DR_START                    ((uint32_t)&ADC_UNIT->DR0)  //DMA数据源地址
#define PTTM_VAL_IDX                    (11U)  //DMA缓存区大小为11 表示11个通道,即11个模拟量

#define DMA_UNIT                        (CM_DMA1)    //DMA1基地址
#define DMA_PERIPH_CLK                  (FCG0_PERIPH_DMA1)  //DMA1使能时钟
#define DMA_CH                          (DMA_CH0)    //通道0地址
#define DMA_AOS_TRIG_SEL                (AOS_DMA1_0)   //外设电路之间的联动(AOS自动运行系统)

#define DMA_TRANS_CNT                   (0U)     //设置DMA传输次数,0表示传输无限次(传输次数要大于0)
#define DMA_BLOCK_SIZE                  (ADC_CH14 - ADC_CH0 + 1U)    //设置DMA数据块大小
#define DMA_DATA_WIDTH                  (DMA_DATAWIDTH_16BIT)    //设置数据宽度,也决定了源地址和目的地址增加或者减少多少
#define DMA_SRC_ADDR                     ADC_DR_START     //DMA数据源地址
#define DMA_DEST_ADDR                   ((uint32_t)(&m_au16AdcValue[0U]))    //DMA数据目的地址

#define DMA_TRIG_EVT                    (EVT_SRC_ADC1_EOCA)    //选择AOS触发源 ADC1序列A转换完成事件

#define DMA_INT_TYPE                    (DMA_INT_BTC_CH0)    //选择DMA中断类型为:数据块传输完成中断
#define DMA_INT_SRC                     (INT_SRC_DMA1_BTC0)    //选择DMA中断类型为:数据块传输完成
#define DMA_INT_IRQn                    (INT028_IRQn)     //DMA中断序号为028
#define DMA_INT_PRIO                    (DDL_IRQ_PRIO_00)    //DMA中断优先级为00(根据自己需要设定)
#define DMA_INT_FLAG                    (DMA_FLAG_BTC_CH0)    //DMA数据块传输完成中断标志位

/* ADC reference voltage. The voltage of pin VREFH. */
#define ADC_VREF                        (3.3F)    //ADC参考电压3.3V

/* ADC accuracy(according to the resolution of ADC). */
#define ADC_ACCURACY                    (1UL << 12U)    //设置ADC分辨率为12位,2^12次方=4096

#define ADC_CAL_VOL(adcVal)             (uint16_t)((((float32_t)(adcVal) * ADC_VREF) / ((float32_t)ADC_ACCURACY)) )    //计算ADC采样电压 ADC_CAL_VOL = adcVal*3.3/4096


static uint16_t m_au16AdcValue[DMA_BLOCK_SIZE];     //DMA接受数据缓存区定义

void DMA_init(void){   //DMA配置

        FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE);    //使能DMA外围时钟
    DMA_DeInit(DMA_UNIT, DMA_CH);    //复位DMA1通道0
        //DMA基本配置
    stc_dma_init_t stcDmaInit;
    DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn       = DMA_INT_DISABLE;    //开启DMA中断
    stcDmaInit.u32SrcAddr     = DMA_SRC_ADDR;    //DMA源地址
    stcDmaInit.u32DestAddr    = DMA_DEST_ADDR;    //DMA目的地址
    stcDmaInit.u32DataWidth   = DMA_DATA_WIDTH;    //DMA传输数据宽度 16位
    stcDmaInit.u32BlockSize   = DMA_BLOCK_SIZE;    //DMA数据块大小 15
    stcDmaInit.u32TransCount  = DMA_TRANS_CNT;    //DMA传输计数
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;    //DMA源地址增量方式 递增
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;    //DMA目的地址增量方式 递增
    DMA_Init(DMA_UNIT, DMA_CH, &stcDmaInit);
       
    DMA_Cmd(DMA_UNIT, ENABLE);
    DMA_ChCmd(DMA_UNIT, DMA_CH, ENABLE);
       
          //DMA重复模式配置
    stc_dma_repeat_init_t stcDmaRptInit;
        DMA_RepeatStructInit(&stcDmaRptInit);
    stcDmaRptInit.u32Mode      = DMA_RPT_BOTH;    //DMA重复模式 DMA源和目标重复启用
    stcDmaRptInit.u32SrcCount  = DMA_BLOCK_SIZE;    //DMA源重复大小=DMA数据块大小(15)
    stcDmaRptInit.u32DestCount = DMA_BLOCK_SIZE;    //DMA目的重复大小=DMA数据块大小(15)
    DMA_RepeatInit(DMA_UNIT, DMA_CH, &stcDmaRptInit);
   
        ADC_GetStatus(ADC_UNIT, ADC_FLAG_EOCA);
    /* Enable AOS clock */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    /* Set DMA trigger source 设置DMA触发源*/   
    AOS_SetTriggerEventSrc(DMA_AOS_TRIG_SEL, DMA_TRIG_EVT);    //ADC转换完成->DMA传输数据
    /* DMA IRQ configuration. */    //DMA中断处理函数
    DmaIrqConfig();
       
       
}

/**
* @brief  DMA interrupt configuration.
* @param  None
* @retval None
*/
static void DmaIrqConfig(void)    //        DMA中断函数配置
{
    stc_irq_signin_config_t stcIrqSignConfig;

    stcIrqSignConfig.enIntSrc    = DMA_INT_SRC;
    stcIrqSignConfig.enIRQn      = DMA_INT_IRQn;
    stcIrqSignConfig.pfnCallback = &DMA_IrqCallback;

    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);

    /* NVIC setting */    //中断控制设置
    NVIC_ClearPendingIRQ(DMA_INT_IRQn);
    NVIC_SetPriority(DMA_INT_IRQn, DMA_INT_PRIO);
    NVIC_EnableIRQ(DMA_INT_IRQn);
}

/**
* @brief  DMA IRQ handler.
* @param  None
* @retval None
*/
static void DMA_IrqCallback(void)    //DMA中断回调函数
{
        if(SET == DMA_GetTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG)){
           DMA_Cmd(DMA_UNIT, DISABLE);
       DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
           DMA_Cmd(DMA_UNIT, ENABLE);
                }
}

使用特权

评论回复
沙发
ZJY1|  楼主 | 2024-6-25 18:02 | 只看该作者
用的是HC32F460

使用特权

评论回复
板凳
mbutterfly| | 2024-6-26 14:31 | 只看该作者
之前遇到STM的DMA初始化放到后面,就不能用。

使用特权

评论回复
地板
亚瑟| | 2024-6-28 18:30 | 只看该作者
为什么放后面就不行了啊?

使用特权

评论回复
5
发货后已经wi| | 2024-8-28 18:57 | 只看该作者
选择DMA中断类型为:数据块传输完成中断

使用特权

评论回复
6
ZJY1|  楼主 | 2024-9-6 14:54 | 只看该作者

已经解决 代码如下
#include "timer4.h"

#define TMR4_UNIT                       (CM_TMR4_1)
#define TMR4_PERIPH_CLK                 (FCG2_PERIPH_TMR4_1)
#define TMR4_EVT_CH                     (TMR4_EVT_CH_UH)    //TMR4事件通道




void TMR4_init(void)
{

        FCG_Fcg2PeriphClockCmd(TMR4_PERIPH_CLK,ENABLE);    //使能TME4_1外围时钟

        /************************* Configure TMR4 counter *************************/       
    stc_tmr4_init_t stcTmr4Init;
        TMR4_StructInit(&stcTmr4Init);
    stcTmr4Init.u16ClockSrc = TMR4_CLK_SRC_INTERNCLK;    //TMR4计数器时钟源 PCLK1=100M
        stcTmr4Init.u16ClockDiv =  TMR4_CLK_DIV1024;   //TMR4计数器时钟分频 1024分频
        stcTmr4Init.u16CountMode = TMR4_MD_SAWTOOTH;    //TMR4计数模式 锯齿波模式
        stcTmr4Init.u16PeriodValue = 24;     //PCLK1=100M 100000000/1024/2000/2=24  2000HZ采样频率 0.5ms
        TMR4_Init(TMR4_UNIT, &stcTmr4Init);

    /************************* Configure TMR4 event ***************************/
        stc_tmr4_evt_init_t stcTmr4EventInit;
    TMR4_EVT_StructInit(&stcTmr4EventInit);
    stcTmr4EventInit.u16CompareValue = 24/2U;    //50%占空比
        stcTmr4EventInit.u16MatchCond = TMR4_EVT_MATCH_CNT_UP;    //向上计数
        stcTmr4EventInit.u16Mode = TMR4_EVT_MD_CMP;    //MR4_EVT比较模式
        stcTmr4EventInit.u16OutputEvent = TMR4_EVT_OUTPUT_EVT0;    //TMR4输出事件为TMR4事件输出特殊事件0
    TMR4_EVT_Init(TMR4_UNIT, TMR4_EVT_CH, &stcTmr4EventInit);
               
    /* Start TMR4 count. */
    TMR4_Start(TMR4_UNIT);

}


#include "adc.h"
#include "gpio.h"
#include "clock.h"
#include "timer4.h"

#define ADC_CLK_SEL                     (ADC_CLK_MPLL)
#define ADC_CLK                         (CLK_PERIPHCLK_PLLQ)

/* ADC unit instance for this example. */
#define ADC_UNIT                        (CM_ADC1)  //ADC1基地址(起始地址)
#define ADC_PERIPH_CLK                  (FCG3_PERIPH_ADC1)   //ADC1使能时钟

/* Selects ADC channels that needed. */
#define ADC_CHA                         (ADC_CH0)      //选择ADC_CH0通道
#define ADC_CHA_PORT                    (GPIO_PORT_A)  //对应PA0口
#define ADC_CHA_PIN                     (GPIO_PIN_00)

#define ADC_CHB                         (ADC_CH1)      //选择ADC_CH1通道
#define ADC_CHB_PORT                    (GPIO_PORT_A)  //对应PA1口
#define ADC_CHB_PIN                     (GPIO_PIN_01)  

#define ADC_CHC                         (ADC_CH2)      //选择ADC_CH2通道
#define ADC_CHC_PORT                    (GPIO_PORT_A)  //对应PA2口
#define ADC_CHC_PIN                     (GPIO_PIN_02)

#define ADC_CHD                         (ADC_CH3)      //选择ADC_CH3通道
#define ADC_CHD_PORT                    (GPIO_PORT_A)  //对应PA3口
#define ADC_CHD_PIN                     (GPIO_PIN_03)

#define ADC_CHE                         (ADC_CH4)      //选择ADC_CH4通道
#define ADC_CHE_PORT                    (GPIO_PORT_A)  //对应PA4口
#define ADC_CHE_PIN                     (GPIO_PIN_04)

#define ADC_CHF                         (ADC_CH5)      //选择ADC_CH5通道
#define ADC_CHF_PORT                    (GPIO_PORT_A)  //对应PA5口
#define ADC_CHF_PIN                     (GPIO_PIN_05)

#define ADC_CHG                         (ADC_CH6)      //选择ADC_CH6通道
#define ADC_CHG_PORT                    (GPIO_PORT_A)  //对应PA6口
#define ADC_CHG_PIN                     (GPIO_PIN_06)

#define ADC_CHH                         (ADC_CH7)      //选择ADC_CH7通道
#define ADC_CHH_PORT                    (GPIO_PORT_A)  //对应PA7口
#define ADC_CHH_PIN                     (GPIO_PIN_07)

#define ADC_CHI                         (ADC_CH8)      //选择ADC_CH8通道
#define ADC_CHI_PORT                    (GPIO_PORT_B)  //对应PB0口
#define ADC_CHI_PIN                     (GPIO_PIN_00)

#define ADC_CHJ                         (ADC_CH9)      //选择ADC_CH9通道
#define ADC_CHJ_PORT                    (GPIO_PORT_B)  //对应PB1口
#define ADC_CHJ_PIN                     (GPIO_PIN_01)

#define ADC_CHK                         (ADC_CH10)      //选择ADC_CH10通道
#define ADC_CHK_PORT                    (GPIO_PORT_C)  //对应PC4口
#define ADC_CHK_PIN                     (GPIO_PIN_04)

//uint16_t m_u16AdcVal[11] = {0};

/* ADC sequence to be used. */
#define ADC_SEQ                         (ADC_SEQ_A)  //使用ADC1的序列A

/* Hard trigger of the specified sequence. */
#define ADC_SEQ_HARDTRIG                (ADC_HARDTRIG_EVT0)  //硬件触发标志位-------TMR4触发 2k采样率

/* ADC trigger event source */
#define ADC_TRIG_SEL                    (AOS_ADC1_0)
#define ADC_EVT_SRC                     (EVT_SRC_TMR4_1_SCMP0)  

void adc_init(void)
{
        GPIO_init();
        TMR4_init();
       
    AdcClockConfig();  
        AdcInitConfig();
        AdcTriggerConfig();
//        ADC_IrqCallback();
       
        ADC_Start(ADC_UNIT);
}

static void AdcClockConfig(void)
{
    Clock_init();
        CLK_SetPeriClockSrc(ADC_CLK);
}

static void AdcInitConfig(void)
{
        FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
       
    stc_adc_init_t stcAdcInit;
    (void)ADC_StructInit(&stcAdcInit);
        stcAdcInit.u16ScanMode = ADC_MD_SEQA_CONT;    //ADC1序列A序列A连续扫描
        stcAdcInit.u16Resolution = ADC_RESOLUTION_12BIT;    //ADC分辨率为12位
    stcAdcInit.u16DataAlign = ADC_DATAALIGN_RIGHT;     //转换数据右对齐
    (void)ADC_Init(ADC_UNIT, &stcAdcInit);
          
        //ADC通道引脚重映射
        ADC_ResetChMapping(ADC_UNIT);
        ADC_ChRemap(ADC_UNIT, ADC_CH10, ADC1_PIN_PC4);     //将PC4重映射为ADC通道10(原为通道14)
       
        //使能ADC通道
    ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHA, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHB, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHC, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHD, ENABLE);
    ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHE, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHF, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHG, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHH, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHI, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHJ, ENABLE);
        ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHK, ENABLE);       

    //设置采样时间
    ADC_SetSampleTime(ADC_UNIT, ADC_CHA, 240U);
    ADC_SetSampleTime(ADC_UNIT, ADC_CHB, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHC, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHD, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHE, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHF, 240U);
    ADC_SetSampleTime(ADC_UNIT, ADC_CHG, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHH, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHI, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHJ, 240U);
        ADC_SetSampleTime(ADC_UNIT, ADC_CHK, 240U);

        //设置扫描平均计算
        ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT32);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHA, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHB, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHC, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHD, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHE, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHF, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHG, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHH, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHI, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHJ, ENABLE);
        ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHK, ENABLE);       

}

    //ADC触发源设置
static void AdcTriggerConfig(void)
{
        FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);     //使能AOS外围时钟
        ADC_TriggerConfig(ADC_UNIT, ADC_SEQ, ADC_HARDTRIG_EVT0);    //ADC触发设置 内部事件0触发
       
    AOS_SetTriggerEventSrc(ADC_TRIG_SEL, ADC_EVT_SRC);    //ADC1_0的触发源为Timer4_1_SCMP0
        ADC_TriggerCmd(ADC_UNIT, ADC_SEQ, ENABLE);
}


#include "dma.h"

#define ADC_UNIT                        (CM_ADC1)  //ADC1基地址(起始地址)

#define ADC_DR_START                    ((uint32_t)&ADC_UNIT->DR0)  //DMA数据源地址


#define DMA_UNIT                        (CM_DMA1)    //DMA1基地址
#define DMA_PERIPH_CLK                  (FCG0_PERIPH_DMA1)  //DMA1使能时钟
#define DMA_CH                          (DMA_CH0)    //通道0地址
#define DMA_AOS_TRIG_SEL                (AOS_DMA1_0)   //外设电路之间的联动(AOS自动运行系统)

#define DMA_TRANS_CNT                   (0U)     //设置DMA传输次数,0表示传输无限次(传输次数要大于0)
#define DMA_BLOCK_SIZE                  (11U)    //设置DMA数据块大小
#define DMA_DATA_WIDTH                  (DMA_DATAWIDTH_16BIT)    //设置数据宽度,也决定了源地址和目的地址增加或者减少多少
#define DMA_SRC_ADDR                     ADC_DR_START     //DMA数据源地址
#define DMA_DEST_ADDR                   ((uint32_t)&ad_value)    //DMA数据目的地址

#define DMA_TRIG_EVT                    (EVT_SRC_ADC1_EOCA)    //选择AOS触发源 ADC1序列A转换完成事件

#define DMA_INT_TYPE                    (DMA_INT_BTC_CH0)    //选择DMA中断类型为:数据块传输完成中断
#define DMA_INT_SRC                     (INT_SRC_DMA1_BTC0)    //选择DMA中断类型为:数据块传输完成
#define DMA_INT_IRQn                    (INT028_IRQn)     //DMA中断序号为028
#define DMA_INT_PRIO                    (DDL_IRQ_PRIO_03)    //DMA中断优先级为03(根据自己需要设定)
#define DMA_INT_FLAG                    (DMA_FLAG_BTC_CH0)    //DMA数据块传输完成中断标志位

uint16_t ad_value[11]={0};    //定义一个数组,用来存放11个ADC通道转换结果,也是DMA的目标地址
uint16_t adc_data[11]={0};      //定义一个数组,用来存放11个ADC通道转换电压值结果

//static __IO en_flag_status_t m_enAcquisition;    //采集标志位

    //DMA配置
void DMA_init(void)   
{   
        FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE);    //使能DMA外围时钟
    DMA_DeInit(DMA_UNIT, DMA_CH);    //复位DMA1通道0
        DMA_Cmd(DMA_UNIT, ENABLE);
        //DMA基本配置
    stc_dma_init_t stcDmaInit;
    DMA_StructInit(&stcDmaInit);
        stcDmaInit.u32IntEn       = DMA_INT_ENABLE;    //开启DMA中断
    stcDmaInit.u32SrcAddr     = DMA_SRC_ADDR;    //DMA源地址
    stcDmaInit.u32DestAddr    = DMA_DEST_ADDR;    //DMA目的地址
    stcDmaInit.u32DataWidth   = DMA_DATA_WIDTH;    //DMA传输数据宽度16位
    stcDmaInit.u32BlockSize   = DMA_BLOCK_SIZE;    //DMA数据块大小
    stcDmaInit.u32TransCount  = DMA_TRANS_CNT;    //DMA传输计数
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;    //DMA源地址增量方式 递增
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;    //DMA目的地址增量方式 递增
    DMA_Init(DMA_UNIT, DMA_CH, &stcDmaInit);
       
    DMA_ChCmd(DMA_UNIT, DMA_CH, ENABLE);
       
        //DMA重复模式配置
    stc_dma_repeat_init_t stcDmaRptInit;
        DMA_RepeatStructInit(&stcDmaRptInit);
    stcDmaRptInit.u32Mode      = DMA_RPT_BOTH;    //DMA重复模式 DMA源和目标重复启用
    stcDmaRptInit.u32SrcCount  = DMA_BLOCK_SIZE;    //DMA源重复大小=DMA数据块大小
    stcDmaRptInit.u32DestCount = DMA_BLOCK_SIZE;    //DMA目的重复大小=DMA数据块大小
    DMA_RepeatInit(DMA_UNIT, DMA_CH, &stcDmaRptInit);
   
    //设置DMA触发源
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    AOS_SetTriggerEventSrc(DMA_AOS_TRIG_SEL, DMA_TRIG_EVT);    //ADC转换完成->DMA传输数据
       
    //DMA中断处理函数
    DmaIrqConfig();
        DMA_IrqCallback();
}

    //DMA中断函数设置
static void DmaIrqConfig(void)   
{
    stc_irq_signin_config_t stcIrqSignConfig;
   
    stcIrqSignConfig.enIntSrc    = DMA_INT_SRC;
    stcIrqSignConfig.enIRQn      = DMA_INT_IRQn;
    stcIrqSignConfig.pfnCallback = &DMA_IrqCallback;

    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);

    //中断控制设置
    NVIC_ClearPendingIRQ(DMA_INT_IRQn);
    NVIC_SetPriority(DMA_INT_IRQn, DMA_INT_PRIO);
    NVIC_EnableIRQ(DMA_INT_IRQn);
}


    //DMA中断回调函数
static void DMA_IrqCallback(void)   
{
        if(SET == DMA_GetTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG)){
           DMA_Cmd(DMA_UNIT, DISABLE);
               
       adc_data[0] = (ad_value[0]*63/100) + (ad_value[0]*75/1001) + 26;         //PA0 ADC0还原后的电压值
                                                                                                                                                                                  
       adc_data[1] = (ad_value[1]*31/20) + (ad_value[1]*75/394) - 3225;         //PA1 ADC1还原后的电压值
                                                                                                                                                                                  
       adc_data[2] = -(ad_value[2]*31/20) - (ad_value[2]*75/394) + 3246;        //PA2 ADC2还原后的电压值
                                                                                                                                                                                  
       adc_data[3] = (ad_value[3]*31/20) + (ad_value[3]*75/394) - 3214;         //PA3 ADC3还原后的电压值
                                                                                                                                                                                  
       adc_data[4] = (ad_value[4]*3.3)/4096;                                    //PA4 ADC4的电压值
                                                                                                                                                                                  
       adc_data[5] = -(ad_value[5]*31/20) - (ad_value[5]*75/394) + 3222;        //PA5 ADC5还原后的电压值
                                                                                                                                                                                  
       adc_data[6] = (ad_value[6]*31/20) + (ad_value[6]*75/394) - 3240;         //PA6 ADC6还原后的电压值
                                                                                                                                                                                  
       adc_data[7] = (ad_value[7]*3.3)/4096;                                    //PA7 ADC7的电压值
                                                                                                                                                                                  
       adc_data[8] = -(ad_value[8]*29/20) - (ad_value[8]*75/391) + 3047;        //PB0 ADC8还原后的电压值
                                                                                                                                                                                  
       adc_data[9] = (ad_value[9]*29/20) + (ad_value[9]*75/391) - 3041;         //PB1 ADC9还原后的电压值
             
           adc_data[10] = (ad_value[10]*3.3)/4096;                                  //PC4 ADC14的电压值
          
       DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
           DMA_Cmd(DMA_UNIT, ENABLE);
                }
}

使用特权

评论回复
7
shenxiaolin| | 2024-9-29 11:15 | 只看该作者
最好穿源代码文件,看起来很方便

使用特权

评论回复
8
gra22ce| | 2024-10-28 20:17 | 只看该作者
在嵌入式系统中,使用定时器触发ADC采样并通过DMA进行多路传输是一种常见的操作。这种方法可以有效地提高数据采集的效率和精度

使用特权

评论回复
9
nuan11nuan| | 2024-10-28 21:20 | 只看该作者
首先,确保系统时钟和外设时钟已经初始化。使能ADC和定时器模块时钟

使用特权

评论回复
10
hight1light| | 2024-10-28 22:30 | 只看该作者
配置ADC以支持多通道采样,并设置触发源为定时器

使用特权

评论回复
11
ewyu| | 2024-10-28 23:46 | 只看该作者
一般需要配置定时器以生成触发ADC采样的信号。

使用特权

评论回复
12
miltk| | 2024-10-29 08:25 | 只看该作者
注意,一定要配置DMA以传输ADC采样数据。启动ADC和DMA,开始采样和数据传输。

使用特权

评论回复
13
tiakon| | 2024-10-29 10:05 | 只看该作者
确保系统时钟和外设时钟已经正确配置。

使用特权

评论回复
14
一切D都好| | 2024-10-29 11:12 | 只看该作者
缓冲区大小,确保DMA缓冲区大小与ADC通道数一致

使用特权

评论回复
15
nqty| | 2024-10-29 12:20 | 只看该作者
触发源,确保ADC的触发源配置为定时器。

使用特权

评论回复
16
twinkhahale| | 2024-10-29 14:01 | 只看该作者
DMA模式,根据需求选择合适的DMA模式(如循环模式)

使用特权

评论回复
17
清芯芯清| | 2024-10-29 16:10 | 只看该作者
就初始化ADC和DMA就行,但是要注意多路ADC采集的时候,DMA要是配置不好,可能回来的数据可能不准确

使用特权

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

本版积分规则

2

主题

4

帖子

0

粉丝