AnsweredAssumed Answered

STM32F373RB ADC+DMA+Interrupt

Question asked by on Mar 3, 2016
Latest reply on Mar 6, 2016 by

Dear Community

I have an STM32F373RB device and I try to use the DMA to read the ADC1. However the DMA interrupt is not triggered. Since there is no example on the µC how to use DMA and ADC together with interrupt I would be very happy if someone could give a hint what I could check in my next trial and error session.



void ADC_1_Init() {
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure; //DMA Interupt
    // Enable DMA1 clock 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    // Enable ADC1 clock 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div4); // this I copied form the ADC_DMA example but I havent checked what it means so far
    //Enable GPIO Clock
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    // Configure PB.12 (ADC Channel8) in analog mode 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  //PB10 --> ADC_IN10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  //PB11 --> ADC_IN11
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    //DMA1 Channel1 configuration   
    DMA_InitStructure.DMA_BufferSize = sizeof(ADC1_Buffer); 
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1_Buffer;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA_Mode_Normal; //
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_PeripheralDataSize =  DMA_PeripheralDataSize_HalfWord;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    //DMA_IT_TC: Transfer complete interrupt mask 
    //DMA_IT_HT: Half transfer interrupt mask 
    //DMA_IT_TE: Transfer error interrupt mask
    // Enable DMA1 channel6 IRQ Channel
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ADC_Prio;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =        ADC_subPrio;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);
    DMA_Cmd(DMA1_Channel1, ENABLE);
    // ADC1 configuration 
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //Enable for conti mode
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  //Enable for conti mode
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; //Trigger 
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);         
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_7Cycles5);
    // Enable ADC1 DMA 
    //The folowing section is probably obsolete...
    // Enable ADC1 
    ADC_Cmd(ADC1, ENABLE);  
    // ADC1 reset calibration register   
    // ADC1 calibration start 
    ADC_Cmd(ADC1, ENABLE);   

IRQ Handler:

void DMA1_Channel1_IRQHandler() {   
    if(DMA_GetFlagStatus(DMA1_IT_TC1) != RESET) {
        ADC_Cmd(ADC1, DISABLE);     

Call from DMA2_Channel3_IRQHandler() :


PS: This mechanism works on stm32L100 and now I try to migrate this to stm32373 for reaching higher performance.