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

Nucleo F746 双ADC同步采样不能启动

[复制链接]
kylongmu 提问时间:2016-10-8 18:43 /
本帖最后由 kylongmu 于 2016-10-8 18:46 编辑

单通道工作时是正常的,现在想AD1与AD2同步模式工作,但是一直不能启动,各位大神帮看看是什么问题:
static TIM_HandleTypeDef  Timer4Handle;
void Timer4_init()
{
    TIM_ClockConfigTypeDef TimerClockConfig;
    TIM_MasterConfigTypeDef sMasterConfig;
    __TIM4_CLK_ENABLE();
    //Timer init
    Timer4Handle.Instance = (TIM_TypeDef *)TIM4;
    Timer4Handle.Init.Prescaler = 0;
    Timer4Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    Timer4Handle.Init.Period = 108;
    Timer4Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    //Timer4Handle.Init.RepetitionCounter = 0;
    //Timer4Handle.Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    //Timer4Handle.hdma[0] = &DMA_ADC_Handle;
    HAL_TIM_Base_Init(&Timer4Handle);

    TimerClockConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&Timer4Handle,&TimerClockConfig);

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&Timer4Handle, &sMasterConfig);
    //HAL_TIM_Base_Start(&Timer4Handle);
    HAL_TIM_Base_Start_IT(&Timer4Handle);

}
/* ADC1 init function */
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
static void MX_ADC1_Init(void)
{

  ADC_MultiModeTypeDef multimode;
  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T4_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  HAL_ADC_Init(&hadc1);

    /**Configure the ADC multi-mode
    */
  multimode.Mode = ADC_DUALMODE_REGSIMULT;
  multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
  HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);

}

/* ADC2 init function */
static void MX_ADC2_Init(void)
{

  ADC_MultiModeTypeDef multimode;
  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc2.Init.Resolution = ADC_RESOLUTION_12B;
  hadc2.Init.ScanConvMode = DISABLE;
  hadc2.Init.ContinuousConvMode = ENABLE;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc2.Init.NbrOfConversion = 1;
  hadc2.Init.DMAContinuousRequests = ENABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  HAL_ADC_Init(&hadc2);

    /**Configure the ADC multi-mode
    */
  multimode.Mode = ADC_DUALMODE_REGSIMULT;
  multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
  HAL_ADCEx_MultiModeConfigChannel(&hadc2, &multimode);

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
  sConfig.Channel = ADC_CHANNEL_13;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
  HAL_ADC_ConfigChannel(&hadc2, &sConfig);

}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(hadc->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();

    /**ADC1 GPIO Configuration   
    PC0     ------> ADC1_IN10
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Peripheral DMA init*/

    hdma_adc1.Instance = DMA2_Stream0;
    hdma_adc1.Init.Channel = DMA_CHANNEL_0;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_adc1.Init.Mode = DMA_NORMAL;
    hdma_adc1.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_adc1);

    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }
  else if(hadc->Instance==ADC2)
  {
  /* USER CODE BEGIN ADC2_MspInit 0 */

  /* USER CODE END ADC2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ADC2_CLK_ENABLE();

    /**ADC2 GPIO Configuration   
    PC3     ------> ADC2_IN13
    */
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /* USER CODE BEGIN ADC2_MspInit 1 */

  /* USER CODE END ADC2_MspInit 1 */
  }

}
void adc_init_2ch()
{
    HAL_ADC_MspInit(&hadc1);
    HAL_ADC_MspInit(&hadc2);
    MX_ADC1_Init();
    MX_ADC2_Init();

}

void adc_readn( uint32_t * data, uint32_t nelems)
{
    HAL_ADC_Start(&hadc2);
    HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t *)data, nelems);
}

void DMA2_Stream0_IRQHandler(void)//ADC DMA
{
    /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
    tim4cnt++;
    if(__HAL_DMA_GET_IT_SOURCE(&DMA_ADC_Handle, DMA_IT_HT)) { //Half transfer
        tinterval = tmr.read_us();//Half DMA
        HAL_DMA_IRQHandler(&DMA_ADC_Handle);
        return;
    }
    if(__HAL_DMA_GET_IT_SOURCE(&DMA_ADC_Handle, DMA_IT_TC))//Full transfer
        tinterval=tmr.read_us() - tinterval;
    HAL_DMA_IRQHandler(&DMA_ADC_Handle);
}
void Interrupt_Init()
{
    NVIC_SetVector(DMA2_Stream0_IRQn, (uint32_t)DMA2_Stream0_IRQHandler);
    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}

#define SAMPLESADC (1024*3)
union {
    uint32_t D[SAMPLESADC];
    uint16_t C[SAMPLESADC*2];
} samples;


void main()
{
    Interrupt_Init();
    Timer4_init();

    adc_init_2ch();
    memset(samples.D,0x5A5A,sizeof samples.D);
    adc_readn(samples.D,SAMPLESADC);


}
收藏 1 评论15 发布时间:2016-10-8 18:43

举报

15个回答
Paderboy 回答时间:2016-10-8 22:15:49
我用CubeMx 建了个基于767zi开发板的工程,

配置了串口3,输出数据:
PB7 板载蓝色led 运行状态提示
配置ADC 1 内部Vrefint通道 和ADC 2 Pa4 通道

ADC 2 配置参数
767ZI-RESUMM_ADC03.png

DMA 配置参数
767ZI-RESUMM_ADC01.png

初始化
767ZI-RESUMM_ADC02.png

循环输出
767ZI-RESUMM_ADC04.png

ADC回调
767ZI-RESUMM_ADC05.png


好了,输出结果正常。。
767ZI-RESUMM_ADC.png


评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

mark0668 回答时间:2016-10-8 19:45:11
没用过,帮顶
kylongmu 回答时间:2016-10-9 02:00:58
本帖最后由 kylongmu 于 2016-10-9 03:02 编辑
Paderboy 发表于 2016-10-8 22:15
我用CubeMx 建了个基于767zi开发板的工程,

配置了串口3,输出数据:

感谢大神Paderboy的测试!
我也是用CubeMX生成的代码,与你不同的地方是我用了TIM4来触发ADC,一次采集3K点。
但就是不工作,即没有进中断,采集的数据也没有。
我测试了去掉TIM4的触发后,是能够进入中断并正确的获取ADC数据的。TIM4作为触发的程序,我在单个ADC工作时是正常的。

Paderboy 回答时间:2016-10-9 08:46:02
kylongmu 发表于 2016-10-9 02:00
感谢大神Paderboy的测试!
我也是用CubeMX生成的代码,与你不同的地方是我用了TIM4来触发ADC,一次采集3K ...

你先测试下双通道同步采样,先不用tim4触发,看看正常不。。。一步一步排除。。。。
高二毛 回答时间:2016-10-9 08:49:26
支持楼上,一步步排查问题。
kylongmu 回答时间:2016-10-9 12:58:11
本帖最后由 kylongmu 于 2016-10-9 13:03 编辑
Paderboy 发表于 2016-10-9 08:46
你先测试下双通道同步采样,先不用tim4触发,看看正常不。。。一步一步排除。。。。 ...

不用tim4是正常的

双通道同步采样,分别接VCC,GND

双通道同步采样,分别接VCC,GND

双通道同步采样,分别接VCC,GND
Paderboy 回答时间:2016-10-9 15:02:49
kylongmu 发表于 2016-10-9 12:58
不用tim4是正常的
双通道同步采样,分别接VCC,GND

那就在adc tim4触发上找找问题。。
kylongmu 回答时间:2016-10-9 18:28:28
Paderboy 发表于 2016-10-9 15:02
那就在adc tim4触发上找找问题。。

单通道采用tim4是正常的,双通道就是不会启动dma,冥思苦想也不得其解啊。
kylongmu 回答时间:2016-10-9 19:54:31
把ADC 模式改为ADC_DUALMODE_ALTERTRIG也是一样的情况,难道双通道ADC就不能使用触发事件?不应该啊,CubeMX产生的代码也没有禁止触发选项,我看了数据手册也没有说有此限制啊。
12下一页

所属标签

相似问题

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