stm32f4 discovery ADC okuma sorunlarım

Başlatan seyityildirim, 06 Aralık 2016, 23:15:59

seyityildirim

Herkese iyi akşamlar...

Discovery kartıyla Adc okumaya çalışıyorum. 12V luk bir adaptörüm var. Şöyle bir devre kurdum.



kodlar ise şu şekilde

/* Includes ------------------------------------------------------------------*/
#include "main.h"

double deger1,deger2,deger3,deger4;
__IO uint16_t aADCDualConvertedValue[4];

/* Private function prototypes -----------------------------------------------*/
static void DMA_Config(void);
static void GPIO_Config(void);
static void ADC1_CH10_CH11_Config(void);
static void ADC2_CH11_CH12_Config(void);

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

int main(void)
{

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

  /* Enable peripheral clocks *************************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
    
  /* DMA2 Stream0 channel0 configuration **************************************/
  DMA_Config();
  
  /* ADCs configuration ------------------------------------------------------*/
  /* Configure ADC Channel10, 11, 12 pin as analog input */
  GPIO_Config();

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

  /* ADC1 regular channels 10, 11 configuration */
  ADC1_CH10_CH11_Config();

  /* ADC2 regular channels 11, 12 configuration */
  ADC2_CH11_CH12_Config();

  /* Enable DMA request after last transfer (Multi-ADC mode)  */
  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

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

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConv(ADC1);

  while (1)
  {
	  deger1=aADCDualConvertedValue[0]*0.0007326;
		deger2=aADCDualConvertedValue[1];
	  deger3=aADCDualConvertedValue[2];
		deger4=aADCDualConvertedValue[3];
  }
}

static void ADC1_CH10_CH11_Config(void)
{
  ADC_InitTypeDef ADC_InitStructure;

  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_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channels 10, 11 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
}


static void ADC2_CH11_CH12_Config(void)
{
  ADC_InitTypeDef ADC_InitStructure;

  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_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2;
  ADC_Init(ADC2, &ADC_InitStructure);

  /* ADC2 regular channels 11, 12 configuration */ 
  ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 2, ADC_SampleTime_3Cycles);
}


static void DMA_Config(void)
{
  DMA_InitTypeDef DMA_InitStructure;

  DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aADCDualConvertedValue;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS;
  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_Enable;         
  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);

  /* DMA2_Stream0 enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);
}

/**
  * @brief Configure ADC Channels 10, 11, 12 pins as analog inputs
  * @param  None
  * @retval None
  */
static void GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  /* ADC Channel 10 -> PC0
     ADC Channel 11 -> PC1
     ADC Channel 12 -> PC2
  */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;
  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



Adc ucundaki gerilimi bir yandan multimetre ile kontrol ederken diğer yandan Keil'de debug yaparak değer1 değişkenini watch pencersinden izliyorum.

Aldığım sonuçlar şu şekilde

Multimetre                Programın hesapladığı

1 V                            1,03 V
1,56 V                       1,61 V
1,77 V                       1,83 V
2 V                            2,07 V
2,49 V                       2,57 V

Bu uyumsuzluklar neden kaynaklanıyor?

Ayrıca 1V'un altına düştüğümde resimde işaretlediğim LD7 ledi yanmaya başlıyor. Kısa devre mi demek istiyor? Bu sorunlarla daha önce karşılaşan var mı?


baran123

"Bu uyumsuzluklar neden kaynaklanıyor?"
Ölçü aletinin hassasiyeti, ıvır zıvır kayıplar vs bir sürü ekten olabilir.
Arada ölümcül bir fark yok gibi.
STM ledini bilmiyorum datasheetten bakabilirsin

seyityildirim

Alıntı yapılan: baran123 - 06 Aralık 2016, 23:26:15
"Bu uyumsuzluklar neden kaynaklanıyor?"
Ölçü aletinin hassasiyeti, ıvır zıvır kayıplar vs bir sürü ekten olabilir.
Arada ölümcül bir fark yok gibi.

Hocam hassas ölçüm gerekiyor. En azından 1mV yakalayabilmem gerekiyor.

anlamadığım 12 bit adc kullanıyorum. Bu hata paylarının düşmesi gerekiyor. Ben baya yakın olacağı düşüncesindeydim Arduino ile okuyacak olsam sanki daha yakın olur gibi geliyor.

striger

"USB LD7: green LED indicates when VBUS is present on CN5 and is connected to
PA9 of the STM32F407VGT6." usb portunda enerji oldugunu gosteren led.

c0 yerine c1 den okumyı deneyebilirsin, c0 da usb lik bi ozellik var.

quarko

Hesaplamada kullandığınız ondalıklı sayı hatalı.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

seyityildirim

@striger teşekkürler

Alıntı yapılan: quarko - 06 Aralık 2016, 23:52:48
Hesaplamada kullandığınız ondalıklı sayı hatalı.

Hocam ilk önce adc değerini 3/4095 ile çarptım. o zaman sadece tam sayı gösteriyordu. Ondalık kısım hiç görülmedi. Ben de hesap makinesine 3/4095 yazdım. çıkan sonucu yazdım oraya. 

muhittin_kaplan

neden 3/4095 yaptınız MCU nun referans  gerilimini ölçtünüz mü ? (Vref/4096 dan)

quarko

Alıntı yapılan: seyityildirim - 07 Aralık 2016, 00:04:36
Hocam ilk önce adc değerini 3/4095 ile çarptım. o zaman sadece tam sayı gösteriyordu. Ondalık kısım hiç görülmedi. Ben de hesap makinesine 3/4095 yazdım. çıkan sonucu yazdım oraya.

ADC nin referansının 3V olduğuna emin misiniz ? 3V geldiğinde 4095 olarak 12bit değer elde ettiğinizi kontrol etmelisiniz. Bir nevi kalibrasyon yapmanız gerekiyor yani.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."