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

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产生的代码也没有禁止触发选项,我看了数据手册也没有说有此限制啊。
assssdz 回答时间:2016-10-9 20:52:01
Paderboy 回答时间:2016-10-9 21:13:58
本帖最后由 Paderboy 于 2016-10-9 21:16 编辑
kylongmu 发表于 2016-10-9 19:54
把ADC 模式改为ADC_DUALMODE_ALTERTRIG也是一样的情况,难道双通道ADC就不能使用触发事件?不应该啊,CubeM ...

你试试,只用tim4 的触发去自己标定个flag 不直接去触发adc, 然后通过判断标志位,再去软启动adc 同步采样。。或者设置下 dma 和tim4 中断的优先等级差异看看。。
kylongmu 回答时间:2016-10-9 21:18:14
Paderboy 发表于 2016-10-9 21:13
你试试,只用tim4 的触发去标定个flag  然后通过判断,再去启动adc 同步采样呢? ...

通过TIM4中断去触发ADC采样肯定可以,问题是TIM4的中断响应时间是个不确定值,只要是软件方法就会导致ADC每次采样就会与前面的采样有相位抖动不一致啊。
原田夜舞love 回答时间:2016-10-10 00:01:02
没用过,帮顶
zero99 回答时间:2016-11-16 10:00:27
楼主解决了么
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版