DMA kullanarak 7 kanal ADC okumak (STM32F030x)

Başlatan a.shn, 24 Mart 2016, 17:59:11

a.shn

Arkadaşlar Merhabalar ;

Arm ile yeni yeni uğraşmaya başlıyorum. Keil ve HAL library kullanıyorum.

Elimdeki proje gereği 7 kanal ADC den veri okuyup DMA ile buffer a kaydetmem gerekiyor. Gerekli ayarlamaları yaptım örneklerden ve araştırmalarımdan gördüklerimle. Fakat Şöyle bir durumla karşılaştım.

HAL_ADC_Start_DMA(&hadc,(uint32_t *)ADC_Converted_Values,BUFFERSIZE);

fonksiyonu ile ADC startlıyorum ve değerleri DMA sayesinde buffera kaydediyor.
Daha sonra kurduğum timer sayesinde her 1 ms de
HAL_ADC_Start(&hadc); komutu ile yeni ölçümler alıyorum.

Gelelim sorunuma  eğer DMA nın kayıt yapacağı buffer ı 7 lik size da gönderirsem bana hiç bir okuma gelmiyor. Fakat buffersize=4 yapınca herşey sorunsuz şekilde halloluyor 4 tane ADC kanalınında verisini okuyabiliyorum.

sabahtan beridir araştıryorum fakat elle tutulur bir cevap bulamadım açıkcası. Yardımcı olabilirseniz çok sevinirim.



void ADC_INIT(void)
{
	  ADC_ChannelConfTypeDef sConfig;

  /* ### - 1 - Initialize ADC peripheral #################################### */
  /*
   *  Instance                  = ADC1.
   *  ClockPrescaler            = PCLK divided by 1.
   *  LowPowerAutoWait          = Disabled
   *  LowPowerAutoPowerOff      = Disabled
   *  Resolution                = 12 bit (increased to 16 bit with oversampler)
   *  ScanConvMode              = ADC_SCAN_DIRECTION_FORWARD 
   *  DataAlign                 = Right
   *  ContinuousConvMode        = disabled
   *  DiscontinuousConvMode     = Enabled
   *  ExternalTrigConv          = ADC_SOFTWARE_START
   *  ExternalTrigConvEdge      = None (Software start)
   *  EOCSelection              = End Of Conversion event
   *  DMAContinuousRequests     = ENABLE
   */
	

       hadc.Instance 					= ADC1;
        hadc.Init.ClockPrescaler                  = ADC_CLOCK_ASYNC_DIV1;
	hadc.Init.Resolution                        = ADC_RESOLUTION_8B; // 12 bit yap alican !!!!!
       hadc.Init.DataAlign                          = ADC_DATAALIGN_RIGHT;	
       hadc.Init.ScanConvMode                 = ADC_SCAN_DIRECTION_FORWARD; /* Sequencer will convert the number of channels configured below, successively from the lowest to the highest channel number */
       hadc.Init.EOCSelection                    = ADC_EOC_SINGLE_CONV;
       hadc.Init.LowPowerAutoWait           = DISABLE;                    
       hadc.Init.LowPowerAutoPowerOff    = DISABLE;
       hadc.Init.ContinuousConvMode      = DISABLE;                    /* Continuous mode disabled to have only 1 rank converted at each conversion trig, and because discontinuous mode is enabled */
       hadc.Init.DiscontinuousConvMode = ENABLE;											/* Sequencer of regular group will convert the sequence in several sub-divided sequences */
       hadc.Init.ExternalTrigConv                  = ADC_SOFTWARE_START;					/* Software start to trig the 1st conversion manually, without external event */
       hadc.Init.ExternalTrigConvEdge 	  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trig of conversion by software start (no external event) */
       hadc.Init.DMAContinuousRequests    = ENABLE;												/* ADC-DMA continuous requests to match with DMA configured in circular mode */
       hadc.Init.Overrun 			          = ADC_OVR_DATA_OVERWRITTEN;
       hadc.Init.SamplingTimeCommon       = ADC_SAMPLETIME_239CYCLES_5;

	
  HAL_ADC_Init(&hadc);

     sConfig.Rank         = 0;
     sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5 ;
     sConfig.Channel = REF_1_5_Volt_Pin;			
     HAL_ADC_ConfigChannel(&hadc, &sConfig);
		
     sConfig.Channel = L1_voltage_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L2_voltage_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L3_voltage_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L1_curent_Pin;			
     HAL_ADC_ConfigChannel(&hadc, &sConfig);
		
     sConfig.Channel = L2_curent_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L3_curent_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig)
  	
}

void ADC_DMA_INIT(void)
{
  /* DMA controller clock enable */
  __DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}


void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{

  if(hadc->Instance==ADC1)
  {
		
  GPIO_InitTypeDef          GPIO_InitStruct;
  RCC_OscInitTypeDef        RCC_OscInitStructure;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
	
  /* Enable clock of GPIO associated to the peripheral channels */
    __HAL_RCC_GPIOA_CLK_ENABLE();
		
  /* Enable clock of ADCx peripheral */
	 __HAL_RCC_ADC1_CLK_ENABLE();

  /* Note: In case of usage of asynchronous clock derived from ADC dedicated  */
  /*       HSI RC oscillator 14MHz, with ADC setting                          */
  /*       "AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1",            */
  /*       the clock source has to be enabled at RCC top level using function */
  /*       "HAL_RCC_OscConfig()" (see comments in stm32l1_hal_adc.c header)   */

  /* Enable asynchronous clock source of ADCx */
  /* (place oscillator HSI14 under control of the ADC) */
	
  HAL_RCC_GetOscConfig(&RCC_OscInitStructure);
  RCC_OscInitStructure.OscillatorType        	 = RCC_OSCILLATORTYPE_HSI14;
  RCC_OscInitStructure.HSI14CalibrationValue 	 = RCC_HSI14CALIBRATION_DEFAULT;
  RCC_OscInitStructure.HSI14State 		 = RCC_HSI14_ADC_CONTROL;
  HAL_RCC_OscConfig(&RCC_OscInitStructure);
  
  /* Enable clock of DMA associated to the peripheral */
	__HAL_RCC_DMA1_CLK_ENABLE();
  
 /*##- 2- Configure peripheral GPIO #########################*/		
  
    GPIO_InitStruct.Pin  = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
		
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  
  /*##-3- Configure the DMA ##################################################*/
	
  /* Configure DMA parameters */
  hdma_adc.Instance = DMA1_Channel1;

  hdma_adc.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  hdma_adc.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_adc.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;   /* Transfer from ADC by half-word to match with ADC configuration: ADC resolution 10 or 12 bits */

  hdma_adc.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;   /* Transfer to memory by half-word to match with buffer variable type: half-word */

  hdma_adc.Init.Mode                = DMA_CIRCULAR; /* DMA in circular mode to match with ADC configuration: DMA continuous requests */

  hdma_adc.Init.Priority            = DMA_PRIORITY_HIGH;
  
  /* Deinitialize  & Initialize the DMA for new transfer */

  HAL_DMA_DeInit(&hdma_adc);
  HAL_DMA_Init(&hdma_adc);

  /* Associate the initialized DMA handle to the ADC handle */
  __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc);
	
  }

}