STM32F4Discovery Çok Kanal ADC sorunu!

Başlatan alper0017, 21 Şubat 2013, 21:01:28

alper0017

#define ADC1_DR_ADDRESS     ((uint32_t)0x4001244C)
	uint16_t ADC1ConvertedValue[4];

void CH12_Config(void)
	{
	ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC1, DMA1 and GPIO clocks ****************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7 ;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
        
		
  /* DMA2 Stream0 channel0 configuration **************************************/
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC1ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 4;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* ADC Common Init **********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 4;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC regular channel2 configuration *************************************/
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 4, ADC_SampleTime_3Cycles);

 /* Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
	}
	int main(void)
	{
		
	CH12_Config();
	ADC_DMACmd(ADC1,ENABLE);
	ADC_SoftwareStartConv(ADC1);
		
		
	while(1)
		{
	LCD_Write_integer(200,150,ADC1ConvertedValue[0],Green,Black);
	LCD_Write_integer(200,165,ADC1ConvertedValue[1],Green,Black);	
	LCD_Write_integer(200,180,ADC1ConvertedValue[2],Green,Black);
	LCD_Write_integer(200,195,ADC1ConvertedValue[3],Green,Black);	
		}
	}


Hata nerede acaba?Veya çok kanal adc okumayı başarabilen varmı?

Klein

#1
https://www.picproje.org/index.php/topic,43472.0.html

DMA tanımlarını F4'e uyarladığında muhtemelen çalışır.

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

Bu da DMA ve ST_LIB kullanmadan Interrupt kullanılarak yapılmış bir örnek. Şahsen DMA kullanmadan yapılmasını önermiyorum.

alper0017

Cortex M4 üzerinde çalışıyorum.Örneğinizi inceledim.Örnekteki kodlar M4'de hata veriyor.Şuan kodları düzenledim çalışıyor fakat 2-3-4 kanaldan okuduğum adc değerleri ufakda olsa birbirinden etkileniyorlar buna çare bulamıyorum

z

ADC girişlerine nasıl voltaj uyguluyorsun?

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

alper0017

ADC kanalını 100 uF kapasitör'le birlikte gnd'ye bağlıyorum.O şekilde uyguluyorum.Direk uyguluyorum sonuç aynı.Örneklerde ADC1 DMA kanal 0 kullanılmış.Ben ADC3 DMA kanal 2 kullandım.Etkileyebilirmi?

//Defines
	#define ADC1_DR_ADDRESS     ((uint32_t)0x4001244C)
	#define ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)
	//
	
	//Variables
	__IO uint16_t ADC3ConvertedValue[10] = 0;
	//Variables
	
void ADC_Initialize(void)
	{
		
	ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;
	

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  DMA_InitStructure.DMA_Channel = DMA_Channel_2;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 10;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);

 	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 10;
  ADC_Init(ADC3, &ADC_InitStructure);

  ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 2, ADC_SampleTime_3Cycles);
	ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 3, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_4, 4, ADC_SampleTime_3Cycles);
	ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 5, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_8, 6, ADC_SampleTime_3Cycles);
	ADC_RegularChannelConfig(ADC3, ADC_Channel_9, 7, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 8, ADC_SampleTime_3Cycles);
	ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 9, ADC_SampleTime_3Cycles);
	ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 10, ADC_SampleTime_3Cycles);
	}

  uint16_t ADC_Read(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin_X)
	{
	uint16_t ADC_channel;	
		
	if(GPIOx==GPIOA & GPIO_Pin_X==GPIO_Pin_1)ADC_channel=ADC3ConvertedValue[0];
	if(GPIOx==GPIOA & GPIO_Pin_X==GPIO_Pin_2)ADC_channel=ADC3ConvertedValue[1];
	if(GPIOx==GPIOA & GPIO_Pin_X==GPIO_Pin_3)ADC_channel=ADC3ConvertedValue[2];
	if(GPIOx==GPIOA & GPIO_Pin_X==GPIO_Pin_4)ADC_channel=ADC3ConvertedValue[3];
	if(GPIOx==GPIOA & GPIO_Pin_X==GPIO_Pin_5)ADC_channel=ADC3ConvertedValue[4];
	if(GPIOx==GPIOB & GPIO_Pin_X==GPIO_Pin_0)ADC_channel=ADC3ConvertedValue[5];
	if(GPIOx==GPIOB & GPIO_Pin_X==GPIO_Pin_1)ADC_channel=ADC3ConvertedValue[6];
	if(GPIOx==GPIOC & GPIO_Pin_X==GPIO_Pin_0)ADC_channel=ADC3ConvertedValue[7];
	if(GPIOx==GPIOC & GPIO_Pin_X==GPIO_Pin_1)ADC_channel=ADC3ConvertedValue[8];
	if(GPIOx==GPIOC & GPIO_Pin_X==GPIO_Pin_2)ADC_channel=ADC3ConvertedValue[9];
		
	return ADC_channel;
	}
	
	void ADC_Start(void)
	{
	ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
  ADC_DMACmd(ADC3, ENABLE);
  ADC_Cmd(ADC3, ENABLE);	
	DMA_Cmd(DMA2_Stream0, ENABLE);	
		
	ADC_SoftwareStartConv(ADC3);
	}

	void ADC_Stop(void)
	{
	ADC_DMARequestAfterLastTransferCmd(ADC3,DISABLE);
  ADC_DMACmd(ADC3,DISABLE);
  ADC_Cmd(ADC3,DISABLE);
	DMA_Cmd(DMA2_Stream0,DISABLE);
	}

z

Yüz Ohmluk 1 kaç tane trimpotu 3.3v a bağla.

Trimpotların orta uçlarından ADC girişlerine gir.

Kanallar biribirinden etkileniyormu diye yazılımını bir daha dene.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

alper0017

Hocam kastettiğim o zaten.Önerin için teşekkür ederimde Elektronik Mühendisiyim, böyle bir hataya düşmem:).Malesef çok fazla oynak değerler geliyor ve 2 kanaldan birini 0'a çektiğimde diğer kanal 1'de bile olsa 4095'den 4070'lere düşüyor.Kanalların birbiriyle ne gibi bi bağlantısı olabilir anlayamıyorum

z

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

Klein

#8
Örnek alma süresini   (Cycle_Time) değerini  biraz uzatır mısın?

alper0017

ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; olan satırı ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; haline getirdim.Fakat hala pinler birbirinden etkileniyor.
Örnek vermek gerekirse; PC1 ve PC0 pinleri boştayken(parazit durumu) PC1 pinini gnd'ye çektiğimde PC0'dan okunan adc değeri değişmiyor fakat PC0 pinini gnd'ye çektiğimde parazit durumunda 10 bitte 700lerde gösteren PC1 pini 100'lere iniyor.Aynı şekilde PC0'ı 3.3v'ye çektiğimde de 700 lerde olan adc değeri 850 lere çıkıyor.Bunun gibi arasında ilişki bulunan pinler var ve birbirilerinden de etkileniyorlar.Kod olarak da üstte eklediğim kodu kullanmaktayım.Bu soruna bir çare bulursak gerçekten güzel olucak.
Şimdiden Teşekkürler...

alper0017


Klein

Fırsat bulursam  ilgilenmeye çalışacağım.

pisayisi

#12
PC0 pini adc kanallarından birine bağlı bunda sorun yok ancak bord üzerinde dahili olarak usb anahtarlama entegresinin enable pinine de bağlı. R46 direnci ile PC0 üzerindeki adc ölçümleri de doğal olarak etkilenecektir. Bu direnci sıfır ohm olarak kullanmışlar muhtemelen kullanıcı bir jumper ile değiştirme imkanı bulsun demişler...
Ancak PC1 pini doğrudan pin header çıkışına bağlı bu pinden yapılan ölçümlerde sorun olmaması lazım...

[IMG]http://imageshack.us/a/img542/9919/pc0j.jpg[/img]
Murat

z

#13
Alıntı yapılan: alper0017 - 23 Şubat 2013, 14:36:35
Cevap yok mu?

Verdiğim linki okumadınmı? Başından beri olayın giriş empedansı ile ilgili olduğunu belirtmeye çalışıyorum.

ADC girişlerinden sample alma sürelerin  kısaldıkça  (sample frekansı arttıkça) ADC giriş empedansın küçülür. Uzadıkça büyür. Bu etkinin olumsuz etkisinden ancak çok düşük empedanslı bufferlarla kurtulursun.

ADC dönüşümünün başlangıcındaki sample alma  pencere aralığını genişletmek işe yarar fakat asıl önemli olan ADC önündeki devrede.

100 Ohmluk trimpotlarla deneme yaptınmı? Bence yapmadın.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

alper0017

Elimde qrd sensör kartı potanslar herşey var.Ve hepsiyle deneme yaptım.Devre analizinde bir sorun yok.
Olaki elimdeki potansların hepsi yanmış olsun.Sensör kartımda sorunlar olsun.Mikroc ile basit bir kod yazarak tekrar denedim.Mikroc'de herşey sorunsuz çalışırken keil adc3 kodlarımda sorun olduğu apaçık ortada.ADC1'i set etmeye çalışıyorum fakat onda da problem yaşıyorum.Sürekli 0 alıyorum adc kanallarından.Bu işin bi çözümü olmalı ama hiçbiryerde göremiyorum