跪求双重ADC 多通道规则同步下,DMA传送结果到数组问题请教

2019-07-20 12:00发布

本帖最后由 sun0727 于 2017-9-13 03:16 编辑

设想的是这样的

ADC1 作为 MasterADC 控制如下5路, 结果依次付给 数组 的 0-4 的 低16位:

ADC1_IN1 -------> ADCConvertedData[0] 低 16位
ADC1_IN2 -------> ADCConvertedData[1] 低 16位
ADC1_IN3 ------>  ADCConvertedData[2] 低 16位
ADC1_IN4 ------> ADCConvertedData[3] 低 16位
ADC1_IN12-----> ADCConvertedData[4] 低 16位

ADC2 作为 SlaveADC 控制如下3路, 结果依次付给 数组 的 0-2 高16位:

ADC2_IN1-------> ADCConvertedData[0] 高16
ADC2_IN3-------> ADCConvertedData[1] 高16
ADC2_IN4-------> ADCConvertedData[2] 高16

- 但是经过我自己的编写,发现 ADC1 能扫描,但是ADC2结果在数组中的位置并不固定,原因是因为 ADC2下的通道是3个 ,ADC1 的通道是5个 数量不对称 请问程序如何修改

以下是我的部分配置


ADC1 的初始化


[mw_shl_code=c,true]void ADC1_Input_Init(void)
{
        ADC1_Handle.Instance          = ADC1;
        ADC1_Handle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;      /* Synchronous clock mode, input ADC clock divided by 2*/
  ADC1_Handle.Init.Resolution            = ADC_RESOLUTION_12B;            /* 12-bit resolution for converted data */
  ADC1_Handle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;           /* Right-alignment for converted data */
  ADC1_Handle.Init.ScanConvMode          = ADC_SCAN_ENABLE;                       /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  ADC1_Handle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
  ADC1_Handle.Init.LowPowerAutoWait      = DISABLE;                       /* Auto-delayed conversion feature disabled */
  ADC1_Handle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
  ADC1_Handle.Init.NbrOfConversion       = 5;                             /* Parameter discarded because sequencer is disabled */
  ADC1_Handle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */                          /* Parameter discarded because sequencer is disabled */
  ADC1_Handle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
  ADC1_Handle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
  ADC1_Handle.Init.DMAContinuousRequests = ENABLE;                        /* ADC DMA continuous request to match with DMA circular mode */
  ADC1_Handle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
  
        HAL_ADC_Init(&ADC1_Handle);
        
}[/mw_shl_code]

2. 多通道规则同步的配置

[mw_shl_code=c,true]void ADC_Multimode_Config(void)
{
        ADC_Multimode.Mode = ADC_DUALMODE_REGSIMULT;
  ADC_Multimode.DMAAccessMode = ADC_DMAACCESSMODE_12_10_BITS;
  ADC_Multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_4CYCLES;
        
        HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handle, &ADC_Multimode);
}[/mw_shl_code]

3. ADC1 Channel 配置

[mw_shl_code=c,true]void ADC1_Channel_Config(void)
{
  //common config for channel
  
  ADC1_sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;   /* Sampling time (number of clock cycles unit) */
  ADC1_sConfig.SingleDiff   = ADC_SINGLE_ENDED;            /* Single-ended input channel */
  ADC1_sConfig.OffsetNumber = ADC_OFFSET_NONE;             /* No offset subtraction */
  ADC1_sConfig.Offset = 0;

  ADC1_sConfig.Channel      = ADC_CHANNEL_1;                /* Sampled channel number */        
        ADC1_sConfig.Rank         = ADC_REGULAR_RANK_1;          /* Rank of sampled channel number ADCx_CHANNEL */
        HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
        
        ADC1_sConfig.Channel      = ADC_CHANNEL_2;        
        ADC1_sConfig.Rank         = ADC_REGULAR_RANK_2;
        HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
        
        ADC1_sConfig.Channel      = ADC_CHANNEL_3;        
        ADC1_sConfig.Rank         = ADC_REGULAR_RANK_3;
        HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
        
        ADC1_sConfig.Channel      = ADC_CHANNEL_4;        
        ADC1_sConfig.Rank         = ADC_REGULAR_RANK_4;
        HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
        
        ADC1_sConfig.Channel      = ADC_CHANNEL_12;        
        ADC1_sConfig.Rank         = ADC_REGULAR_RANK_5;
        HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
}[/mw_shl_code]

4. ADC2 的初始化 和  Channel 配置
[mw_shl_code=c,true]void ADC2_Input_Init(void)
{
        ADC2_Handle.Instance          = ADC2;
        
        //HAL_ADC_DeInit(& ADC2_Handle);
        //HAL_ADCEx_Calibration_Start(&ADC2_Handle, ADC_SINGLE_ENDED);
        
        ADC2_Handle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;      /* Synchronous clock mode, input ADC clock divided by 2*/
  ADC2_Handle.Init.Resolution            = ADC_RESOLUTION_12B;            /* 12-bit resolution for converted data */
  ADC2_Handle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;           /* Right-alignment for converted data */
  ADC2_Handle.Init.ScanConvMode          = ADC_SCAN_ENABLE;                      /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  ADC2_Handle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
  ADC2_Handle.Init.LowPowerAutoWait      = DISABLE;                       /* Auto-delayed conversion feature disabled */
  ADC2_Handle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
  ADC2_Handle.Init.NbrOfConversion       = 3;                             /* Parameter discarded because sequencer is disabled */
  ADC2_Handle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  ADC2_Handle.Init.NbrOfDiscConversion   = 1;                             /* Parameter discarded because sequencer is disabled */
  //ADC2_Handle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
  //ADC2_Handle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
  ADC2_Handle.Init.DMAContinuousRequests = ENABLE;                        /* ADC DMA continuous request to match with DMA circular mode */
  ADC2_Handle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
  
        HAL_ADC_Init(&ADC2_Handle);
        
}

//--------------------Configure the ADC2 Channel-----------------------------------
void ADC2_Channel_Config(void)
{
  //common config for channel
  ADC2_sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;   /* Sampling time (number of clock cycles unit) */
  ADC2_sConfig.SingleDiff   = ADC_SINGLE_ENDED;            /* Single-ended input channel */
  ADC2_sConfig.OffsetNumber = ADC_OFFSET_NONE;             /* No offset subtraction */
  ADC2_sConfig.Offset = 0;

  ADC2_sConfig.Channel      = ADC_CHANNEL_1;                /* Sampled channel number */        
        ADC2_sConfig.Rank         = ADC_REGULAR_RANK_1;          /* Rank of sampled channel number ADCx_CHANNEL */
        HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC2_sConfig);
        
        ADC2_sConfig.Channel      = ADC_CHANNEL_3;        
        ADC2_sConfig.Rank         = ADC_REGULAR_RANK_2;
        HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC2_sConfig);
        
        ADC2_sConfig.Channel      = ADC_CHANNEL_4;        
        ADC2_sConfig.Rank         = ADC_REGULAR_RANK_3;
        ADC2_sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
        HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC2_sConfig);
        
}[/mw_shl_code]

5. DMA 配置

[mw_shl_code=c,true]DMA_HandleTypeDef  ADC1_DMA_Handle;

void ADC1_DMA_Init(ADC_HandleTypeDef* hadc)
{

ADC1_DMA_Handle.Instance = DMA1_Channel1;
ADC1_DMA_Handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
ADC1_DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE;
ADC1_DMA_Handle.Init.MemInc = DMA_MINC_ENABLE;
ADC1_DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
ADC1_DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
ADC1_DMA_Handle.Init.Mode = DMA_CIRCULAR;
ADC1_DMA_Handle.Init.Priority = DMA_PRIORITY_HIGH;

//HAL_DMA_DeInit(&ADC1_DMA_Handle);
HAL_DMA_Init(&ADC1_DMA_Handle);

__HAL_LINKDMA(hadc,DMA_Handle,ADC1_DMA_Handle);
        
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}
[/mw_shl_code]


6. 函数的调用

[mw_shl_code=c,true]#define ADC_CONVERTED_DATA_BUFFER_SIZE   ((uint32_t)  5)   /* Size of array aADCxConvertedData[] */
uint32_t   aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE];


//------------------------------Start ADC in Dualmode and DMA --------------------------------------
void ADC_DMA_Dualmode_Start(void)
{         
ADC1_Input_Init();
ADC_Multimode_Config();
ADC1_Channel_Config();
         
ADC2_Input_Init();
ADC2_Channel_Config();
//        
//        
HAL_ADC_Start(&ADC2_Handle);
HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handle,(uint32_t *)aADCxConvertedData,ADC_CONVERTED_DATA_BUFFER_SIZE);
        
}[/mw_shl_code]

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
正点原子
1楼-- · 2019-07-20 17:29
论坛搜索找找参考吧
sun0727
2楼-- · 2019-07-20 20:13
本帖最后由 sun0727 于 2017-9-13 03:10 编辑
正点原子 发表于 2017-9-12 23:43
论坛搜索找找参考吧

没找到。。主要我的通道数量非对称的 ,ADC1 采样了5个 ADC1采样3个
jiutianshenjian
3楼-- · 2019-07-21 01:51
 精彩回答 2  元偷偷看……
sun0727
4楼-- · 2019-07-21 02:34
 精彩回答 2  元偷偷看……

一周热门 更多>