AnsweredAssumed Answered

STM32F4 Dual ADC Reg Sim Mode with DMA

Question asked by rudu.alex on Mar 21, 2016
Latest reply on Mar 23, 2016 by rudu.alex
Hello, I want to read ADC1 CH0 and ADC2 CH1 in dual regular simultaneous mode and buffer it in DMA. I want to send the ADC values via UART to my PC and read them from the COM Port.
When I start the program now, I only receive the msg 0x0A, which I send after the m_ADCValue. But after some transmissions it stops and nothing is sent anymore.
Another problem is, that I do not really I understand how to get the values that I write in the m_ADCBuffer. Do I have to use the HAL_ADC_ConvCpltCallback and HAL_ADCEx_MultiModeGetValue? What is about the DMA2_Stream0_IRQHandler(), do I need to implement that?

void ADC_init(void){
 
        // 1. Init Timer for Interrupt trigger
 
        TIM_ClockConfigTypeDef sClockSourceConfig;
        TIM_MasterConfigTypeDef sMasterConfig;
 
        // TIM3 clock enable
        __TIM3_CLK_ENABLE();
 
        //Init TIM3 Base
        m_hTIM3.Instance = TIM3;                                               
        m_hTIM3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
        m_hTIM3.Init.Prescaler = 18000;                                        
        m_hTIM3.Init.CounterMode = TIM_COUNTERMODE_UP;
        m_hTIM3.Init.Period = MYADCSAMPLETIME;                                 
        m_hTIM3.Init.RepetitionCounter  = 0;
 
        if(HAL_TIM_Base_Init(&m_hTIM3) != HAL_OK){
            ErrorLED();
        }
 
        //Config Timer3 TRGO
        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
        if(HAL_TIM_ConfigClockSource(&m_hTIM3, &sClockSourceConfig) != HAL_OK){
            ErrorLED();
        }
 
        sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
        sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
        if(HAL_TIMEx_MasterConfigSynchronization(&m_hTIM3, &sMasterConfig) != HAL_OK){
            ErrorLED();
        }
 
        //Start timer
        if(HAL_TIM_Base_Start(&m_hTIM3) != HAL_OK){
            ErrorLED();
        }
 
        // 2. Enable ADC1, ADC2, DMA2 Clock
 
        // Enable ADC Clk before DMA2 Clk
        __ADC1_CLK_ENABLE();
        __ADC2_CLK_ENABLE();
        __DMA2_CLK_ENABLE();
 
        // 3. Init DMA
 
        m_hDMA2s0c0.Instance = DMA2_Stream0;
        m_hDMA2s0c0.Init.Channel = DMA_CHANNEL_0;
        m_hDMA2s0c0.Init.Direction = DMA_PERIPH_TO_MEMORY;
        m_hDMA2s0c0.Init.PeriphInc = DMA_PINC_DISABLE;                                 
        m_hDMA2s0c0.Init.MemInc = DMA_MINC_ENABLE;                                 
        m_hDMA2s0c0.Init.PeriphDataAlignment = MA_PDATAALIGN_WORD;                             
        m_hDMA2s0c0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
        m_hDMA2s0c0.Init.Mode = DMA_CIRCULAR;                                      
        m_hDMA2s0c0.Init.Priority = DMA_PRIORITY_HIGH;
        m_hDMA2s0c0.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
        m_hDMA2s0c0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
        m_hDMA2s0c0.Init.MemBurst = DMA_MBURST_SINGLE;
        m_hDMA2s0c0.Init.PeriphBurst = DMA_PBURST_SINGLE;
 
        if(HAL_DMA_Init(&m_hDMA2s0c0) != HAL_OK){
            ErrorLED();
        }
 
        // DMA mit ADC verlinken
         
        __HAL_LINKDMA(&m_hADC1, DMA_Handle, m_hDMA2s0c0);
 
        HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
 
 
        // 4. Init ADC1
 
        m_hADC1.Instance = ADC1;
        m_hADC1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;                    
        m_hADC1.Init.Resolution = ADC_RESOLUTION_8B;
        m_hADC1.Init.DataAlign  = ADC_DATAALIGN_RIGHT;
        m_hADC1.Init.ScanConvMode   = DISABLE;                                         
        m_hADC1.Init.EOCSelection = DISABLE;                                           
        m_hADC1.Init.ContinuousConvMode = ENABLE;
        m_hADC1.Init.DiscontinuousConvMode = DISABLE;
        m_hADC1.Init.DMAContinuousRequests = ENABLE;                                           
        m_hADC1.Init.NbrOfConversion    = 1;                                               
        m_hADC1.Init.NbrOfDiscConversion    = 0;                       
        m_hADC1.Init.ExternalTrigConvEdge   = ADC_EXTERNALTRIGCONVEDGE_RISING;
        m_hADC1.Init.ExternalTrigConv   = ADC_EXTERNALTRIGCONV_T3_TRGO;
        if(HAL_ADC_Init(&m_hADC1) != HAL_OK){
            ErrorLED();
        }
 
        // 5. Init ADC2
 
        m_hADC2.Instance    = ADC2;
        m_hADC2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;                    
        m_hADC2.Init.Resolution = ADC_RESOLUTION_8B;
        m_hADC2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
        m_hADC2.Init.ScanConvMode   = DISABLE;                                         
        m_hADC2.Init.EOCSelection = DISABLE;                                           
        m_hADC2.Init.ContinuousConvMode = ENABLE;
        m_hADC2.Init.DiscontinuousConvMode = DISABLE;
        m_hADC2.Init.DMAContinuousRequests = ENABLE;                                           
        m_hADC2.Init.NbrOfConversion =1;                                                                           
        m_hADC2.Init.NbrOfDiscConversion = 0;
        m_hADC2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;                      
        m_hADC2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
 
        if(HAL_ADC_Init(&m_hADC2) != HAL_OK){
            ErrorLED();
        }
 
        HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(ADC_IRQn);
 
        // 6. Config ADC Channel
 
        ADC_ChannelConfTypeDef  sConfig;
 
        sConfig.Channel             = ADC_CHANNEL_0;
        sConfig.Rank                = 1;                           
        sConfig.SamplingTime        = ADC_SAMPLETIME_56CYCLES;     
        sConfig.Offset              = 0;
 
        HAL_ADC_ConfigChannel(&m_hADC1, &sConfig);
 
        sConfig.Channel             = ADC_CHANNEL_1;
        sConfig.Rank                = 1;                           
        sConfig.SamplingTime        = ADC_SAMPLETIME_56CYCLES;     
        sConfig.Offset              = 0;
 
        HAL_ADC_ConfigChannel(&m_hADC2, &sConfig);
 
        // 7. ADC Mode
 
        ADC_MultiModeTypeDef   multimode;
 
        multimode.Mode          = ADC_DUALMODE_REGSIMULT;
        multimode.DMAAccessMode     = ADC_DMAACCESSMODE_1; 
        multimode.TwoSamplingDelay  = ADC_TWOSAMPLINGDELAY_6CYCLES;
 
        if(HAL_ADCEx_MultiModeConfigChannel(&m_hADC1, &multimode) != HAL_OK){
            ErrorLED();
        }
 
        if(HAL_ADCEx_MultiModeConfigChannel(&m_hADC2, &multimode) != HAL_OK){
            ErrorLED();
        }
 
}
 
/*
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* m_hADC1){
 
    m_ADCValue[1] = HAL_ADCEx_MultiModeGetValue(&m_hADC1);
 
}
*/
 
/*
void DMA2_Stream0_IRQHandler(){
 
    HAL_DMA_IRQHandler(m_hADC1.DMA_Handle); //?????? mit & ???????
 
}
*/
 
 
/*
void ADC1_DMA_IRQHandler(void)
{
  HAL_DMA_IRQHandler(m_hADC1.DMA_Handle);
}
*/
/*
void ADC_IRQHandler(){
    HAL_ADC_IRQHandler(&m_hADC1);
}
*/
 
 
 
int main(){
 
    HAL_Init();
    SystemCoreClockConfigure_180MHz_internal();
 
    GPIO_PowerLub_init();
    UART_Init(mBaudrate);
    ADC_init();
 
    uint8_t msg[1] = {0x0A};
 
    HAL_ADC_Start(&m_hADC2);
    HAL_ADCEx_MultiModeStart_DMA(&m_hADC1, (uint32_t *)m_ADCBuffer, 2)
 
    while(1){
 
        HAL_UART_Transmit(&huart2, (uint32_t *)m_ADCValue, 2, 0xAAFF);
        HAL_UART_Transmit(&huart2, (uint32_t *)msg, 1, 0xAAFF);
    }
 
}

Outcomes