This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

2 ADC TO ARRAY VIA DMA

Hello guys,
I am newbie here.
I would like to make a programme that take from 2 channels ADC and via DMA store them in an array and then shows flags HT and TC.Do u have any example?
How can I set an input of 600 khz?

  • Aren't you a funny guy who don't seem to consider that it would matter what processor you are using...

  • oops my fault i use stm32f103rb.
    typical newbie mistake.

  • That is an ST product - not Keil.

    Have you studied the ST documentation, and the examples provided by ST...?

    I wouldn't have thought of DMA as a beginner's topic - have you already done basic projects like blinking an LED, or even using the ADC without DMA?

  • It's my first programme in keil.
    i used to programme in C and I am not yet graduate still student.
    My programme should be based on this

    /* Includes ------------------------------------------------------------------*/
    #include "stm32f10x.h"
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    #define ADC1_DR_Address ((uint32_t)0x4001244C)

    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    ADC_InitTypeDef ADC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    __IO uint32_t ADC_DualConvertedValueTab[200];

    /* Private function prototypes -----------------------------------------------*/
    void RCC_Configuration(void);
    void GPIO_Configuration(void);

    /* Private functions ---------------------------------------------------------*/

    /** * @brief Main program * @param None * @retval None */
    int main(void)
    { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */

    /* System clocks configuration ---------------------------------------------*/ RCC_Configuration();

    /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration();

    /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 16; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 Channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE);

    /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE);

    /* ADC2 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 2, ADC_SampleTime_239Cycles5); /* Enable ADC2 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC2, ENABLE);

    /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable Vrefint channel17 */ ADC_TempSensorVrefintCmd(ENABLE);

    /* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1));

    /* Start ADC1 calibration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1));

  • /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE);

    /* Enable ADC2 reset calibration register */ ADC_ResetCalibration(ADC2); /* Check the end of ADC2 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC2));

    /* Start ADC2 calibration */ ADC_StartCalibration(ADC2); /* Check the end of ADC2 calibration */ while(ADC_GetCalibrationStatus(ADC2));

    /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    /* Test on DMA1 channel1 transfer complete flag */ while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); /* Clear DMA1 channel1 transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC1); while (1) /* Test on DMA1 channel1 transfer half flag */ while (!DMA_GetFlagStatus (DMA1_FLAG_HT1)); /* Clear DMA1 channel1 transfer half flag */ DMA_ClearFlag (DMA2_FLAG_HT1) ; while (1) { }
    }

    /** * @brief Configures the different system clocks. * @param None * @retval None */
    void RCC_Configuration(void)
    { /* ADCCLK = PCLK2/4 */ RCC_ADCCLKConfig(RCC_PCLK2_Div4); /* Enable peripheral clocks ------------------------------------------------*/ /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    /* Enable ADC1, ADC2 and GPIOC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOC, ENABLE);
    }

    /** * @brief Configures the different GPIO ports. * @param None * @retval None */
    void GPIO_Configuration(void)
    { GPIO_InitTypeDef GPIO_InitStructure;

    /* Configure PC.01, PC.02 and PC.04 (ADC Channel11, Channel12 and Channel14) as analog input ----------------------------------------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure);
    }

    #ifdef USE_FULL_ASSERT

    /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */
    void assert_failed(uint8_t* file, uint32_t line)
    { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */ while (1) { }
    }

    #endif

    /** * @} */

    /** * @} */

    /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

    where I have added a HT flag still don't know if it is right.
    I should use an array of 200 for storing adc1 and adc2 from the respective channels c1 and c2 via dma.
    I will only debug in simulator,i don't have any board and micontroller yet.
    Please let me know if u want more specification about the project.
    Thanks a lot!

  • I think I'd tend to agree.

    "wouldn't a board like an STM32F3-Discovery, or STM32F4-Discovery be a better choice here? Low cost, built in debugger..."

    I think so: I don't really see that the Simulator gives much (if any) advantage over a Discovery board - and you don't get the added "uncertainties" of simulation...

  • "I don't really see that the Simulator gives much (if any) advantage over a Discovery board"

    That should be:

    I don't really see that the Simulator gives much (if any) advantage over a Discovery board or similar

    That is: a cheap, simple, well-supported board with on-board debug.

  • I was told that I have to use F103RB so I don't have the option to change.
    The instructions I got (that they are not really clear) say that i should put a signal of 600khz in C2 ADC2 but I think that it is the same for AC1.
    Should I change order and put half transfer first?
    I did that and now it shows that :
    main.c(155): warning: #111-D: statement is unreachable
    I am now reading about timers and I will try to understand as much as I can.
    Thanks you so much for your info!

  • main.c(155): warning: #111-D: statement is unreachable

    Yes, well there's a while(1) in there that doesn't look to have a semi-colon, or compound statement associated with it. The formatting is so godawful it's hard to tell.

  • So why aren't you discussing this with the person who told you that?

    "The instructions I got (that they are not really clear)..."

    So why aren't you seeking clarification from the person who gave you those instructions ?

    Only they know what they really meant by them!

  • In context they might be a bit clearer, I think we are getting a reinterpretation of them. Can you get them to post the requirements here?

    I'd read 600 KHz as 600 Hz my bad.

    Now I'm getting the sense it's going to need >1.2MSps, the max on the F103 is 1MSps

  • I will try to ask more specific instructions because I don't have any written details.
    Just a drawing and oral instructions is all what I got so far..
    I've read the TIM manual.
    But I would like to ask for manual on how to debug and run examples on simulator.
    Are there any starters guide? (I 've read the one in Keil's uvision help)

  • Ok I clarify that i want to achieve 600khz sampling rate.
    Any tips how to do that?
    Do I need a timer?