你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

问题:双重 ADC 多通道规则同步下,DMA 传送结果到数组出错

[复制链接]
sun0727 提问时间:2017-9-13 00:23 /
悬赏10ST金币已解决
本帖最后由 sun0727 于 2017-9-13 03:15 编辑

设想的是这样的

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 个 数量不对称 请问程序如何修改

以下是我的部分配置



DMA 配置
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);

}

多通道规则同步的配置



  1. void ADC_Multimode_Config(void)
  2. {
  3.     ADC_Multimode.Mode = ADC_DUALMODE_REGSIMULT;
  4.   ADC_Multimode.DMAAccessMode = ADC_DMAACCESSMODE_12_10_BITS;
  5.   ADC_Multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_4CYCLES;
  6.      
  7.     HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handle, &ADC_Multimode);
  8. }
复制代码
ADC1 的初始化

  1. void ADC1_Input_Init(void)
  2. {
  3.     ADC1_Handle.Instance          = ADC1;
  4.     ADC1_Handle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;      /* Synchronous clock mode, input ADC clock divided by 2*/
  5.   ADC1_Handle.Init.Resolution            = ADC_RESOLUTION_12B;            /* 12-bit resolution for converted data */
  6.   ADC1_Handle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;           /* Right-alignment for converted data */
  7.   ADC1_Handle.Init.ScanConvMode          = ADC_SCAN_ENABLE;                       /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  8.   ADC1_Handle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
  9.   ADC1_Handle.Init.LowPowerAutoWait      = DISABLE;
  10.   ADC1_Handle.Init.ContinuousConvMode    = ENABLE;
  11.   ADC1_Handle.Init.NbrOfConversion       = 5;
  12.   ADC1_Handle.Init.DiscontinuousConvMode = DISABLE;
  13.   ADC1_Handle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /
  14.   ADC1_Handle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /
  15.   ADC1_Handle.Init.DMAContinuousRequests = ENABLE;                        /* ADC DMA continuous request to match with DMA circular mode */
  16.   ADC1_Handle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;
  17.     HAL_ADC_Init(&ADC1_Handle);
  18.      
  19. }
复制代码
ADC1 Channel 配置

  1. void ADC1_Channel_Config(void)
  2. {
  3.   //common config for channel
  4.    
  5.   ADC1_sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;   /* Sampling time (number of clock cycles unit) */
  6.   ADC1_sConfig.SingleDiff   = ADC_SINGLE_ENDED;            /* Single-ended input channel */
  7.   ADC1_sConfig.OffsetNumber = ADC_OFFSET_NONE;             /* No offset subtraction */
  8.   ADC1_sConfig.Offset = 0;

  9.   ADC1_sConfig.Channel      = ADC_CHANNEL_1;                /* Sampled channel number */   
  10.     ADC1_sConfig.Rank         = ADC_REGULAR_RANK_1;          /* Rank of sampled channel number ADCx_CHANNEL */
  11.     HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
  12.      
  13.     ADC1_sConfig.Channel      = ADC_CHANNEL_2;  
  14.     ADC1_sConfig.Rank         = ADC_REGULAR_RANK_2;
  15.     HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
  16.      
  17.     ADC1_sConfig.Channel      = ADC_CHANNEL_3;  
  18.     ADC1_sConfig.Rank         = ADC_REGULAR_RANK_3;
  19.     HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
  20.      
  21.     ADC1_sConfig.Channel      = ADC_CHANNEL_4;  
  22.     ADC1_sConfig.Rank         = ADC_REGULAR_RANK_4;
  23.     HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
  24.      
  25.     ADC1_sConfig.Channel      = ADC_CHANNEL_12;
  26.     ADC1_sConfig.Rank         = ADC_REGULAR_RANK_5;
  27.     HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC1_sConfig);
  28. }
复制代码
ADC2 的初始化 和  Channel 配置
  1. void ADC2_Input_Init(void)
  2. {
  3.     ADC2_Handle.Instance          = ADC2;
  4.      
  5.     //HAL_ADC_DeInit(& ADC2_Handle);
  6.     //HAL_ADCEx_Calibration_Start(&ADC2_Handle, ADC_SINGLE_ENDED);
  7.      
  8.     ADC2_Handle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;      /* Synchronous clock mode, input ADC clock divided by 2*/
  9.   ADC2_Handle.Init.Resolution            = ADC_RESOLUTION_12B;            /* 12-bit resolution for converted data */
  10.   ADC2_Handle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;           /* Right-alignment for converted data */
  11.   ADC2_Handle.Init.ScanConvMode          = ADC_SCAN_ENABLE;                      /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  12.   ADC2_Handle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;           /* EOC flag picked-up to indicate conversion end */
  13.   ADC2_Handle.Init.LowPowerAutoWait      = DISABLE;                       /* Auto-delayed conversion feature disabled */
  14.   ADC2_Handle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode enabled (automatic conversion restart after each conversion) */
  15.   ADC2_Handle.Init.NbrOfConversion       = 3;                             /* Parameter discarded because sequencer is disabled */
  16.   ADC2_Handle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  17.   ADC2_Handle.Init.NbrOfDiscConversion   = 1;                             /* Parameter discarded because sequencer is disabled */
  18.   //ADC2_Handle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
  19.   //ADC2_Handle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
  20.   ADC2_Handle.Init.DMAContinuousRequests = ENABLE;                        /* ADC DMA continuous request to match with DMA circular mode */
  21.   ADC2_Handle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;      /* DR register is overwritten with the last conversion result in case of overrun */
  22.    
  23.     HAL_ADC_Init(&ADC2_Handle);
  24.      
  25. }

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

  34.   ADC2_sConfig.Channel      = ADC_CHANNEL_1;                /* Sampled channel number */   
  35.     ADC2_sConfig.Rank         = ADC_REGULAR_RANK_1;          /* Rank of sampled channel number ADCx_CHANNEL */
  36.     HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC2_sConfig);
  37.      
  38.     ADC2_sConfig.Channel      = ADC_CHANNEL_3;  
  39.     ADC2_sConfig.Rank         = ADC_REGULAR_RANK_2;
  40.     HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC2_sConfig);
  41.      
  42.     ADC2_sConfig.Channel      = ADC_CHANNEL_4;  
  43.     ADC2_sConfig.Rank         = ADC_REGULAR_RANK_3;
  44.     ADC2_sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  45.     HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC2_sConfig);
  46.      
  47. }
复制代码


复制代码
函数的调用

#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);
     
}



最佳答案

查看完整内容

你数据是分:高16位、低16位, 而接收到的数据只有12位, 是不是应该把高16位的数据,右移4位, 并把右移出来的部分,填充到低16位的高4位中呢? 写的有点拗口,希望能明白我在说什么。
收藏 2 评论9 发布时间:2017-9-13 00:23

举报

9个回答
无薪税绵 回答时间:2017-9-13 00:23:09
你数据是分:高16位、低16位,
而接收到的数据只有12位,
是不是应该把高16位的数据,右移4位,
并把右移出来的部分,填充到低16位的高4位中呢?

写的有点拗口,希望能明白我在说什么。

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 4

查看全部评分

sun0727 回答时间:2017-9-13 01:01:59
本帖最后由 sun0727 于 2017-9-13 03:16 编辑

求大神指点这种 数量非对称的 双重 ADC
wenyangzeng 回答时间:2018-1-18 10:09:37
STM32的ADC转换分辨率只有12位,楼主为何要把它拆成2个16位来读取?

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

uwyciw100 回答时间:2018-1-18 11:14:49
前一段时间使用双重同时采样,我的设置中,ADC1和ADC2的转换通道是一样多,我想楼主如果ADC通道有多余,也可以考虑在ADC2中增加几个多余通道。另外,DMA的字长一定要设置成32位。附件是我工程。

handle.zip

下载

3.39 KB, 下载次数: 9, 下载积分: ST金币 -1

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 4

查看全部评分

toofree 回答时间:2018-1-18 15:49:48
弄成同样通道数吧,两路ADC扫描频率相同,采样率相同,只是内存得多开一点。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

zhjb1 回答时间:2018-1-18 16:20:43
看代码好像是采用中断调用DMA,既然如此各个通道带参数独立调用DMA,存储到自己定义的数组中,回调数据时,按照规定读取或输出,这样就没有需要多用存储的要求了。想想是吗?

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

dzzwoaizi 回答时间:2018-1-19 16:11:25
搞FOC的吧
vanaua 回答时间:2020-3-5 15:00:26
楼主你这个问题解决了吗?能不能帮我看一下我的工程,跟你的设置的一样,只不过我的是对称adc转换的,但是在转换时发现各通道的数据都是不对,这该怎么办?是我配置错误了吗?
vanaua 回答时间:2020-3-5 15:05:38
文件有点大,不好意思

test_adc1.part02.rar

下载

5 MB, 下载次数: 0, 下载积分: ST金币 -1

test_adc1.part03.rar

下载

5 MB, 下载次数: 0, 下载积分: ST金币 -1

test_adc1.part04.rar

下载

5 MB, 下载次数: 0, 下载积分: ST金币 -1

test_adc1.part05.rar

下载

4.22 MB, 下载次数: 0, 下载积分: ST金币 -1

test_adc1.part01.rar

下载

5 MB, 下载次数: 0, 下载积分: ST金币 -1

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版