Hal kütüphanesinde ADC kanal ayarları nasıl yapılıyor?

Başlatan Mucit23, 13 Ocak 2016, 17:45:17

yldzelektronik

Her ölçümü aldıktan sonra bir müddet beklemelisin.Bunu aynı kanaldan yaparken bile kullanmakta fayda var.Hangi denetleyici idi hatırlamıyorum (Stm32 ailesinden hangisi) ama dokümanlarından birinde bunu kısaca izah eden bir yer gördüğümü hatırlıyorum.Kaldı ki adcnin genel yapısını göz önüne aldığında da görebilirsin.

Hatta @z nin konularından birinde konuşuldu diye hatırlıyorum.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

bocek

/[i] ADC1 init function [/i]/
void MX_ADC1_Init(void)
{

  ADC_ChannelConfTypeDef sConfig;
  ADC_MultiModeTypeDef multimode;
...
...
...
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    /**Configure the ADC multi-mode 
    */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
  HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
1 ya da 0. işte 'bit'ün mesele..

z

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Abilerim dostlarım, Az önce deneyebildim kodu. Fakat devam ediyor sorun

Son haliyle ADC ayarlarım aşağıdaki gibi. MultiMode TwoSamplingDelay 20Cylces olacak şekilde ayarladım. Daha fazlada artmıyor zaten. Başka bir sorun olduğunu düşünüyorum. Çünkü gerçekten aşırı etkileniyor. Kabul edilebilir gibi değil.

static void ADC_Config(void)
{
  ADC_ChannelConfTypeDef sConfig;
	ADC_MultiModeTypeDef MultiMode;
  /*##-1- Configure the ADC peripheral #######################################*/
  AdcHandle.Instance          = ADC3;
  
  AdcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV4;
  AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
  AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.NbrOfConversion       = 3;
  AdcHandle.Init.ScanConvMode          = ENABLE;                        /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  AdcHandle.Init.ContinuousConvMode    = DISABLE;                       /* Continuous mode disabled to have only 1 conversion at each conversion trig */
  AdcHandle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  AdcHandle.Init.NbrOfDiscConversion   = 0;
  AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING;        /* Conversion start trigged at each external event */
  AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIG2_T2_TRGO;
  AdcHandle.Init.DMAContinuousRequests = ENABLE;
  AdcHandle.Init.EOCSelection          = DISABLE;
	
  HAL_ADC_Init(&AdcHandle);
	
  /*##-2- Configure ADC regular channel ######################################*/
  sConfig.Channel      = ADC_CHANNEL_6;
  sConfig.Rank         = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
  sConfig.Offset       = 0;

  HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
	
  /*##-3- Configure ADC regular channel ######################################*/
  sConfig.Channel      = ADC_CHANNEL_7;
  sConfig.Rank         = 2;
  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
  sConfig.Offset       = 0;

  HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);

  /*##-4- Configure ADC regular channel ######################################*/
  sConfig.Channel      = ADC_CHANNEL_8;
  sConfig.Rank         = 3;
  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
  sConfig.Offset       = 0;

  HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);

  /*##-5- Configure MultiMode Settings #######################################*/	
	MultiMode.Mode=ADC_MODE_INDEPENDENT;
	MultiMode.TwoSamplingDelay=ADC_TWOSAMPLINGDELAY_20CYCLES;
	
  HAL_ADCEx_MultiModeConfigChannel(&AdcHandle, &MultiMode);

  /*##-6- Start the conversion process #######################################*/
  HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue, 6);

}


Bunun dışında birde GPIO ve DMA ayarlarının yapıldığı MSP_init fonksiyonu var.
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  GPIO_InitTypeDef          GPIO_InitStruct;
  static DMA_HandleTypeDef  hdma_adc;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* ADC3 Periph clock enable */
  __HAL_RCC_ADC3_CLK_ENABLE();
  /* Enable GPIO clock ****************************************/
	__HAL_RCC_GPIOF_CLK_ENABLE();
  /* Enable DMA2 clock */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /*##-2- Configure peripheral GPIO ##########################################*/
	
  /* ADC Channel GPIO pin configuration */
	
  GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /*##-3- Configure the DMA streams ##########################################*/
  /* Set the parameters to be configured */
  hdma_adc.Instance = ADCx_DMA_STREAM;

  hdma_adc.Init.Channel  = ADCx_DMA_CHANNEL;
  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;
  hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  hdma_adc.Init.Mode = DMA_CIRCULAR;
  hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
  hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
  hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
  hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;

  HAL_DMA_Init(&hdma_adc);

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

  /*##-4- Configure the NVIC for DMA #########################################*/
  /* NVIC configuration for DMA transfer complete interrupt */
  HAL_NVIC_SetPriority(ADCx_DMA_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(ADCx_DMA_IRQn);
}


Sonuç:
https://www.youtube.com/watch?v=NkiLlNQ1SH4

Mucit23


PROTECH_

Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN

Mucit23

Hocam datasheete bakıyorum. Kurcalamadığım tek ayar EOC ayarı kaldı. Yani End Of Conversion.
Bu işlevin çalışmasını anlamaya çalışıyorum.
Datasheette ADCx->SR registerinin 1. biti EOC için ayrılmış. Şöyle bir açıklama var

Alıntı YapBit 1 EOC: Regular channel end of conversion
This bit is set by hardware at the end of the conversion of a regular group of channels. It is
cleared by software or by reading the ADC_DR register.
0: Conversion not complete (EOCS=0), or sequence of conversions not complete (EOCS=1)
1: Conversion complete (EOCS=0), or sequence of conversions complete (EOCS=1)

Ayrıca DisContinuous Mode'da ADC Regular Group kısmında (Sayfa 420)
Alıntı YapExample:
• n = 3, channels to be converted = 0, 1, 2, 3, 6, 7, 9, 10
• 1st trigger: sequence converted 0, 1, 2. An EOC event is generated at each
conversion.
• 2nd trigger: sequence converted 3, 6, 7. An EOC event is generated at each
conversion
• 3rd trigger: sequence converted 9, 10.An EOC event is generated at each conversion
• 4th trigger: sequence converted 0, 1, 2. An EOC event is generated at each conversion
Note: When a regular group is converted in discontinuous mode, no rollover occurs.
When all subgroups are converted, the next trigger starts the conversion of the first
subgroup. In the example above, the 4th trigger reconverts the channels 0, 1 and 2 in the
1st subgroup.

Tam olarak ne demek istiyor anlamadım aslında. Acaba EOC aktif olmadığı  için dönüşüm tamamlanmadan mı kanal değiştiriliyor.

Ben birde Timer Trigger olmadan yine ADC yi kendim tetikleyerek sıra ile ölçüm alacam.

Normal olarak pic lerde yaptığım gibi
Kanal değiştir
ADC yi başlat
Örnek Al
Kanal Değiştir
ADC yi başlat
Örnek Al

gibi. Deneyip sonucu yazarım.

superconductor

Diger iki kanal float iken pot bagli kanala gore durum degistirmesi normal degil mi? Adc pinlerinin empedansi cok yuksek yuksek. 100k gibi bir direncle pulldown yapmayi dene hala etkileniyorsa o zaman problem var denebilir. Ayni durum digital inputlar icinde gecerli float birakip debugdan port input bufferini izleyin pinlerin yoresinden sinyal geciyorsa durumlari zangir zangir degisiyor.

Mucit23

Hocam bu kadar çok etkilenmesi normal değil gibi geldi bana. Ama aynı zamanda ADC girişleride yan yana PF10, PF9 ve PF8 olmak üzere işlemcinin dibinden yan yana duruyor. Bunlar dediğiniz gibi bir birinden etkilenebilir. Ben 100K direnci bir deneyeyim.

z

Boş ADC pinleri varsa bunları GND ye doğrudan bağlamazsan bu kanallar ölçüm yapılan kanaldan etkilenir. Sesini yukarıda yazmıştım.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

100K direnç sorunu çözdü. 1M direnç bağladım onunla da sorun çözüldü. Dediğiniz gibi hatlar birbirine çok yakın olduğundan ve ADC giriş empedansı çok yüksek olduğundan birbirinden etkileniyor. Direnç koymadan iki ölçüm arası istediğiniz kadar bekleyin fayda etmiyor.

astum

Alıntı yapılan: bocek - 13 Ocak 2016, 23:48:40şunu:
  HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue[0], 3)
şöyle yapsan?:
  HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)uhADCxConvertedValue, 3)



Muhtemelen benzer problemi yaşıyorum.

https://www.picproje.org/index.php/topic,72715.0.html